dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [RFC] drm/kms: control display brightness through drm_connector properties
@ 2022-04-07 15:38 Hans de Goede
  2022-04-07 16:51 ` Simon Ser
                   ` (3 more replies)
  0 siblings, 4 replies; 44+ messages in thread
From: Hans de Goede @ 2022-04-07 15:38 UTC (permalink / raw)
  To: dri-devel, wayland
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, Yusuf Khan

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.

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.


What scale to use for the drm_connector bl_brightness property?
===============================================================

The tricky part of this plan is phase 2 and then esp. defining what the
new brightness properties will look like and how they will work.

The biggest challenge here is to decide on a fixed scale for the main
brightness property, say 0-65535, using scaling where the actual hw scale
is different, or if this should simply be a 1:1 mirror of the current
backlight interface, with the actual hw scale / brightness_max value
exposed as a drm_connector property.

1:1 advantages / 0-65535 disadvantages
- Userspace will likely move over to the connector-props quite slowly and
  we can expect various userspace bits, esp. also custom user scripts, to
  keep using the old uAPI for a long time. Using the 2 APIs are intermixed
  is fine when using a 1:1 brightness scale mapping. But if we end up doing
  a scaling round-trip all the time then eventually the brightness is going
  do drift. This can even happen if the user never changes the brightness
  when userspace saves it over suspend/resume or reboots.
- Almost all laptops have brightness up/down hotkeys. E.g GNOME decides
  on a step size for the hotkeys by doing min(brightness_max/20, 1).
  Some of the vendor specific backlight fw APIs (e.g. dell-laptop) have
  only 8 steps. When giving userspace the actual max_brightness value, then
  this will all work just fine. When hardcode brightness_max to 65535 OTOH
  then in this case GNOME will still give the user 20 steps where only 1
  in every 2-3 steps actually changes the brightness which IMHO is
  an unacceptably bad user experience.

0-65535 advantages / 1:1 disadvantages
- Without a fixed scale for the brightness property the brightness_max
  value may change after an userspace application's initial enumeration
  of the drm_connector. This can happen when neither the native GPU nor
  the acpi_video backlight devices are present/usable in this case
  acpi_video_get_backlight_type() will _assume_ a vendor specific fw API
  will be used for backlight control and the driver proving the "vendor"
  backlight device will show up much later and may even never show-up,
  so waiting for it is not an option. With a fixed 0-65535 scale userspace
  can just always assume this and the drm_connector backlight props helper
  code can even cache writes and send it to the actual backlight device
  when it shows up. With a 1:1 mapping userspace needs to listen for
  a uevent and then update the brightness range on such an event.

I believe that the 1:1 mapping advantages out way the disadvantages
here. Also note that current userspace already blindly assumes that
all relevant drivers are loaded before the graphical-environment
starts and all the desktop environments as such already only do
a single scan of /sys/class/backlight when they start. So when
userspace forgets to add code to listen for the uevent when switching
to the new API nothing changes; and with the uevent userspace actually
gets a good mechanism to detect backlight drivers loading after
the graphical-environment has already started.

So based on this here is my proposal for a set of new brightness
properties on the drm_connector object. Note these are all prefixed with
bl which stands for backlight, which is technically not correct for OLED.
But we need a prefix to avoid a name collision with the "brightness"
attribute which is part of the existing TV specific properties and IMHO
it is good to have a common prefix to make it clear that these all
belong together.


The drm_connector brightness properties
=======================================

bl_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 bl_brightness_max.

bl_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 (yet).

bl_brightness_0_is_min_brightness: ro, boolean
When this is set to true then it is safe to set brightness to 0
without worrying that this completely turns the backlight off causing
the screen to become unreadable. When this is false setting brightness
to 0 may turn the backlight off, but this is _not_ guaranteed.
This will e.g. be true when directly driving a PWM and the video-BIOS
has provided a minimum (non 0) duty-cycle below which the driver will
never go.

bl_brightness_control_method: ro, enum, possible values:
none:     The GPU driver expects brightness control to be provided by another
          driver and that driver has not loaded yet.
unknown:  The underlying control mechanism is unknown.
pwm:      The brightness property directly controls the duty-cycle of a PWM
          output.
firmware: The brightness is controlled through firmware calls.
DDC/CI:   The brightness is controlled through the DDC/CI protocol.
gmux:     The brightness is controlled by the GMUX.
Note this enum may be extended in the future, so other values may
be read, these should be treated as "unknown".

When brightness control becomes available after being reported
as not available before (bl_brightness_control_method=="none")
a uevent with CONNECTOR=<connector-id> and
PROPERTY=<bl_brightness_control_method-id> will be generated
at this point all the properties must be re-read.

When/once brightness control is available then all the read-only
properties are fixed and will never change.

Besides the "none" value for no driver having loaded yet,
the different bl_brightness_control_method values are intended for
(userspace) heuristics for such things as the brightness setting
linearly controlling electrical power or setting perceived brightness.

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


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-07 15:38 [RFC] drm/kms: control display brightness through drm_connector properties Hans de Goede
@ 2022-04-07 16:51 ` Simon Ser
  2022-04-07 17:43   ` Hans de Goede
  2022-04-07 18:58 ` Carsten Haitzler
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 44+ messages in thread
From: Simon Ser @ 2022-04-07 16:51 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

Very nice plan! Big +1 for the overall approach.

On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:

> The drm_connector brightness properties
> =======================================
>
> bl_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 bl_brightness_max.

Do we need to split this up into two props for sw/hw state? The privacy screen
stuff needed this, but you're pretty familiar with that. :)

> bl_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 (yet).

I don't think we actually need that one. Integer KMS props all have a
range which can be fetched via drmModeGetProperty. The max can be
exposed via this range. Example with the existing alpha prop:

    "alpha": range [0, UINT16_MAX] = 65535

> bl_brightness_0_is_min_brightness: ro, boolean
> When this is set to true then it is safe to set brightness to 0
> without worrying that this completely turns the backlight off causing
> the screen to become unreadable. When this is false setting brightness
> to 0 may turn the backlight off, but this is not guaranteed.
> This will e.g. be true when directly driving a PWM and the video-BIOS
> has provided a minimum (non 0) duty-cycle below which the driver will
> never go.

Hm. It's quite unfortunate that it's impossible to have strong guarantees
here.

Is there any way we can avoid this prop?

For instance if we can guarantee that the min level won't turn the screen
completely off we could make the range start from 1 instead of 0.
Or allow -1 to mean "minimum value, maybe completely off".

> bl_brightness_control_method: ro, enum, possible values:
> none: The GPU driver expects brightness control to be provided by another
> driver and that driver has not loaded yet.
> unknown: The underlying control mechanism is unknown.
> pwm: The brightness property directly controls the duty-cycle of a PWM
> output.
> firmware: The brightness is controlled through firmware calls.
> DDC/CI: The brightness is controlled through the DDC/CI protocol.
> gmux: The brightness is controlled by the GMUX.
> Note this enum may be extended in the future, so other values may
> be read, these should be treated as "unknown".
>
> When brightness control becomes available after being reported
> as not available before (bl_brightness_control_method=="none")
> a uevent with CONNECTOR=<connector-id> and
>
> PROPERTY=<bl_brightness_control_method-id> will be generated
>
> at this point all the properties must be re-read.
>
> When/once brightness control is available then all the read-only
> properties are fixed and will never change.
>
> Besides the "none" value for no driver having loaded yet,
> the different bl_brightness_control_method values are intended for
> (userspace) heuristics for such things as the brightness setting
> linearly controlling electrical power or setting perceived brightness.

Can you elaborate? I don't know enough about brightness control to
understand all of the implications here.

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-07 16:51 ` Simon Ser
@ 2022-04-07 17:43   ` Hans de Goede
  2022-04-07 21:05     ` Alex Deucher
  2022-04-08  8:22     ` Simon Ser
  0 siblings, 2 replies; 44+ messages in thread
From: Hans de Goede @ 2022-04-07 17:43 UTC (permalink / raw)
  To: Simon Ser
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

Hi Simon,

On 4/7/22 18:51, Simon Ser wrote:
> Very nice plan! Big +1 for the overall approach.

Thanks.

> On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
> 
>> The drm_connector brightness properties
>> =======================================
>>
>> bl_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 bl_brightness_max.
> 
> Do we need to split this up into two props for sw/hw state? The privacy screen
> stuff needed this, but you're pretty familiar with that. :)

Luckily that won't be necessary, since the privacy-screen is a security
feature the firmware/embedded-controller may refuse our requests
(may temporarily lock-out changes) and/or may make changes without
us requesting them itself. Neither is really the case with the
brightness setting of displays.

>> bl_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 (yet).
> 
> I don't think we actually need that one. Integer KMS props all have a
> range which can be fetched via drmModeGetProperty. The max can be
> exposed via this range. Example with the existing alpha prop:
> 
>     "alpha": range [0, UINT16_MAX] = 65535

Right, I already knew that, which is why I explicitly added a range
to the props already. The problem is that the range must be set
before registering the connector and when the backlight driver
only shows up (much) later during boot then we don't know the
range when registering the connector. I guess we could "patch-up"
the range later. But AFAIK that would be a bit of abuse of the
property API as the range is intended to never change, not
even after hotplug uevents. At least atm there is no infra
in the kernel to change the range later.

Which is why I added an explicit bl_brightness_max property
of which the value gives the actual effective maximum of the
brightness.

I did consider using the range for this and updating it
on the fly I think nothing is really preventing us from
doing so, but it very much feels like abusing the generic
properties API.

>> bl_brightness_0_is_min_brightness: ro, boolean
>> When this is set to true then it is safe to set brightness to 0
>> without worrying that this completely turns the backlight off causing
>> the screen to become unreadable. When this is false setting brightness
>> to 0 may turn the backlight off, but this is not guaranteed.
>> This will e.g. be true when directly driving a PWM and the video-BIOS
>> has provided a minimum (non 0) duty-cycle below which the driver will
>> never go.
> 
> Hm. It's quite unfortunate that it's impossible to have strong guarantees
> here.
> 
> Is there any way we can avoid this prop?

Not really, the problem is that we really don't know if 0 is off
or min-brightness. In the given example where we actually never go
down to a duty-cycle of 0% because the video BIOS tables tell us
not to, we can be certain that setting the brightness prop to 0
will not turn of the backlight, since we then set the duty-cycle
to the VBT provided minimum. Note the intend here is to only set
the boolean to true if the VBT provided minimum is _not_ 0, 0
just means the vendor did not bother to provide a minimum.

Currently e.g. GNOME never goes lower then something like 5%
of brightness_max to avoid accidentally turning the screen off.

Turning the screen off is quite bad to do on e.g. tablets where
the GUI is the only way to undo the brightness change and now
the user can no longer see the GUI.

The idea behind this boolean is to give e.g. GNOME a way to
know that it is safe to go down to 0% and for it to use
the entire range.

> For instance if we can guarantee that the min level won't turn the screen
> completely off we could make the range start from 1 instead of 0.
> Or allow -1 to mean "minimum value, maybe completely off".

Right, the problem is we really don't know and when the range is
e.g. 0-65535 then something like 1 will almost always still just
turn the screen completely off. There will be a value of say like
150 or some such which is then the actual minimum value to still
get the backlight to light up at all. The problem is we have
no clue what the actual minimum is. And if the PWM output does
not directly drive the LEDs but is used as an input for some
LED backlight driver chip, that chip itself may have a lookup
table (which may also take care of doing perceived brightness
mapping) and may guarantee a minimum backlight even when given
a 0% duty cycle PWM signal...

This prop is sort of orthogonal to the generic change to
drm_connector props, so we could also do this later as a follow up
change. At a minimum when I code this up this should be in its
own commit(s) I believe.

But I do think having this will be useful for the above
GNOME example.

>> bl_brightness_control_method: ro, enum, possible values:
>> none: The GPU driver expects brightness control to be provided by another
>> driver and that driver has not loaded yet.
>> unknown: The underlying control mechanism is unknown.
>> pwm: The brightness property directly controls the duty-cycle of a PWM
>> output.
>> firmware: The brightness is controlled through firmware calls.
>> DDC/CI: The brightness is controlled through the DDC/CI protocol.
>> gmux: The brightness is controlled by the GMUX.
>> Note this enum may be extended in the future, so other values may
>> be read, these should be treated as "unknown".
>>
>> When brightness control becomes available after being reported
>> as not available before (bl_brightness_control_method=="none")
>> a uevent with CONNECTOR=<connector-id> and
>>
>> PROPERTY=<bl_brightness_control_method-id> will be generated
>>
>> at this point all the properties must be re-read.
>>
>> When/once brightness control is available then all the read-only
>> properties are fixed and will never change.
>>
>> Besides the "none" value for no driver having loaded yet,
>> the different bl_brightness_control_method values are intended for
>> (userspace) heuristics for such things as the brightness setting
>> linearly controlling electrical power or setting perceived brightness.
> 
> Can you elaborate? I don't know enough about brightness control to
> understand all of the implications here.

So after sending this email I was already thinking myself that this
one might not be the best idea. Another shortcoming of the current
backlight API is that it does not let userspace know if the
number is a linear control of the time the LEDs are on vs off
(assuming a LED backlight) or if some component already uses a
lookup table to make 0-100% be more of a linear scale in the
human perception, which is very much non linear. See e.g.:

https://www.sciencedirect.com/topics/computer-science/perceived-brightness

"refers to the perceived amount of light coming from self-luminous sources"
"Perceived brightness is a very nonlinear function of the amount of light emitted by a lamp."

The problem is that at the kernel level we have no idea if
we are controlling "the amount of light emitted" or
perceived brightness and it would be sorta nice for userspace
to know. So the idea here is/was to allow userspace to make some
educated guess here. E.g. a bl_brightness_control_method of "PWM"
hints strongly at "the amount of light emitted" (but this is
not true 100% of the time).  ATM userspace does not do any
"perceived brightness" curve correction so for the first
implementation of moving brightness control to drm properties
I believe it might be better to just park the whole
bl_brightness_control_method propery idea.

Which would leave the problem of communicating the control_method=="none"
case but we can just use bl_brightness_max == 0 for that.

Regards,

Hans




^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-07 15:38 [RFC] drm/kms: control display brightness through drm_connector properties Hans de Goede
  2022-04-07 16:51 ` Simon Ser
@ 2022-04-07 18:58 ` Carsten Haitzler
  2022-04-11 10:27   ` Hans de Goede
  2022-04-14 13:10 ` Jani Nikula
  2022-08-24  2:18 ` Yusuf Khan
  3 siblings, 1 reply; 44+ messages in thread
From: Carsten Haitzler @ 2022-04-07 18:58 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

On Thu, 7 Apr 2022 17:38:59 +0200 Hans de Goede <hdegoede@redhat.com> said:

Below you covered our usual /sys/class/backlight device friends... what about
DDC monitor controls? These function similarly but just remotely control a
screen via I2C and also suffer from the same problems of "need root" and "have
to do some fun in mapping them to a given screen".

Otherwise I welcome this de-uglification of the backlight device and putting it
together with the drm device that controls that monitor.

Just to make life more fun ... DDC does much more than backlight controls. It
can control essentially anything that is in the OSD for your monitor (contrast,
brightness, backlight, sharpness, color temperatures, input to display (DP vs
HDMI vs DVI etc.), an for extra fun points can even tel you the current
rotation state of your monitor. All of these do make sense to live as drm
connector properties too. Perhaps not a first iteration but something to
consider in this design.

> 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.
> 
> 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.
> 
> 
> What scale to use for the drm_connector bl_brightness property?
> ===============================================================
> 
> The tricky part of this plan is phase 2 and then esp. defining what the
> new brightness properties will look like and how they will work.
> 
> The biggest challenge here is to decide on a fixed scale for the main
> brightness property, say 0-65535, using scaling where the actual hw scale
> is different, or if this should simply be a 1:1 mirror of the current
> backlight interface, with the actual hw scale / brightness_max value
> exposed as a drm_connector property.
> 
> 1:1 advantages / 0-65535 disadvantages
> - Userspace will likely move over to the connector-props quite slowly and
>   we can expect various userspace bits, esp. also custom user scripts, to
>   keep using the old uAPI for a long time. Using the 2 APIs are intermixed
>   is fine when using a 1:1 brightness scale mapping. But if we end up doing
>   a scaling round-trip all the time then eventually the brightness is going
>   do drift. This can even happen if the user never changes the brightness
>   when userspace saves it over suspend/resume or reboots.
> - Almost all laptops have brightness up/down hotkeys. E.g GNOME decides
>   on a step size for the hotkeys by doing min(brightness_max/20, 1).
>   Some of the vendor specific backlight fw APIs (e.g. dell-laptop) have
>   only 8 steps. When giving userspace the actual max_brightness value, then
>   this will all work just fine. When hardcode brightness_max to 65535 OTOH
>   then in this case GNOME will still give the user 20 steps where only 1
>   in every 2-3 steps actually changes the brightness which IMHO is
>   an unacceptably bad user experience.
> 
> 0-65535 advantages / 1:1 disadvantages
> - Without a fixed scale for the brightness property the brightness_max
>   value may change after an userspace application's initial enumeration
>   of the drm_connector. This can happen when neither the native GPU nor
>   the acpi_video backlight devices are present/usable in this case
>   acpi_video_get_backlight_type() will _assume_ a vendor specific fw API
>   will be used for backlight control and the driver proving the "vendor"
>   backlight device will show up much later and may even never show-up,
>   so waiting for it is not an option. With a fixed 0-65535 scale userspace
>   can just always assume this and the drm_connector backlight props helper
>   code can even cache writes and send it to the actual backlight device
>   when it shows up. With a 1:1 mapping userspace needs to listen for
>   a uevent and then update the brightness range on such an event.
> 
> I believe that the 1:1 mapping advantages out way the disadvantages
> here. Also note that current userspace already blindly assumes that
> all relevant drivers are loaded before the graphical-environment
> starts and all the desktop environments as such already only do
> a single scan of /sys/class/backlight when they start. So when
> userspace forgets to add code to listen for the uevent when switching
> to the new API nothing changes; and with the uevent userspace actually
> gets a good mechanism to detect backlight drivers loading after
> the graphical-environment has already started.
> 
> So based on this here is my proposal for a set of new brightness
> properties on the drm_connector object. Note these are all prefixed with
> bl which stands for backlight, which is technically not correct for OLED.
> But we need a prefix to avoid a name collision with the "brightness"
> attribute which is part of the existing TV specific properties and IMHO
> it is good to have a common prefix to make it clear that these all
> belong together.
> 
> 
> The drm_connector brightness properties
> =======================================
> 
> bl_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 bl_brightness_max.
> 
> bl_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 (yet).
> 
> bl_brightness_0_is_min_brightness: ro, boolean
> When this is set to true then it is safe to set brightness to 0
> without worrying that this completely turns the backlight off causing
> the screen to become unreadable. When this is false setting brightness
> to 0 may turn the backlight off, but this is _not_ guaranteed.
> This will e.g. be true when directly driving a PWM and the video-BIOS
> has provided a minimum (non 0) duty-cycle below which the driver will
> never go.
> 
> bl_brightness_control_method: ro, enum, possible values:
> none:     The GPU driver expects brightness control to be provided by another
>           driver and that driver has not loaded yet.
> unknown:  The underlying control mechanism is unknown.
> pwm:      The brightness property directly controls the duty-cycle of a PWM
>           output.
> firmware: The brightness is controlled through firmware calls.
> DDC/CI:   The brightness is controlled through the DDC/CI protocol.
> gmux:     The brightness is controlled by the GMUX.
> Note this enum may be extended in the future, so other values may
> be read, these should be treated as "unknown".
> 
> When brightness control becomes available after being reported
> as not available before (bl_brightness_control_method=="none")
> a uevent with CONNECTOR=<connector-id> and
> PROPERTY=<bl_brightness_control_method-id> will be generated
> at this point all the properties must be re-read.
> 
> When/once brightness control is available then all the read-only
> properties are fixed and will never change.
> 
> Besides the "none" value for no driver having loaded yet,
> the different bl_brightness_control_method values are intended for
> (userspace) heuristics for such things as the brightness setting
> linearly controlling electrical power or setting perceived brightness.
> 
> 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
> 


-- 
------------- Codito, ergo sum - "I code, therefore I am" --------------
Carsten Haitzler - raster@rasterman.com


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-07 17:43   ` Hans de Goede
@ 2022-04-07 21:05     ` Alex Deucher
  2022-04-08  8:07       ` Daniel Vetter
  2022-04-08  8:22     ` Simon Ser
  1 sibling, 1 reply; 44+ messages in thread
From: Alex Deucher @ 2022-04-07 21:05 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Sebastian Wick, Martin Roukala, dri-devel, wayland,
	Christoph Grenz, Yusuf Khan

On Thu, Apr 7, 2022 at 1:43 PM Hans de Goede <hdegoede@redhat.com> wrote:
>
> Hi Simon,
>
> On 4/7/22 18:51, Simon Ser wrote:
> > Very nice plan! Big +1 for the overall approach.
>
> Thanks.
>
> > On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
> >
> >> The drm_connector brightness properties
> >> =======================================
> >>
> >> bl_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 bl_brightness_max.
> >
> > Do we need to split this up into two props for sw/hw state? The privacy screen
> > stuff needed this, but you're pretty familiar with that. :)
>
> Luckily that won't be necessary, since the privacy-screen is a security
> feature the firmware/embedded-controller may refuse our requests
> (may temporarily lock-out changes) and/or may make changes without
> us requesting them itself. Neither is really the case with the
> brightness setting of displays.
>
> >> bl_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 (yet).
> >
> > I don't think we actually need that one. Integer KMS props all have a
> > range which can be fetched via drmModeGetProperty. The max can be
> > exposed via this range. Example with the existing alpha prop:
> >
> >     "alpha": range [0, UINT16_MAX] = 65535
>
> Right, I already knew that, which is why I explicitly added a range
> to the props already. The problem is that the range must be set
> before registering the connector and when the backlight driver
> only shows up (much) later during boot then we don't know the
> range when registering the connector. I guess we could "patch-up"
> the range later. But AFAIK that would be a bit of abuse of the
> property API as the range is intended to never change, not
> even after hotplug uevents. At least atm there is no infra
> in the kernel to change the range later.
>
> Which is why I added an explicit bl_brightness_max property
> of which the value gives the actual effective maximum of the
> brightness.
>
> I did consider using the range for this and updating it
> on the fly I think nothing is really preventing us from
> doing so, but it very much feels like abusing the generic
> properties API.
>
> >> bl_brightness_0_is_min_brightness: ro, boolean
> >> When this is set to true then it is safe to set brightness to 0
> >> without worrying that this completely turns the backlight off causing
> >> the screen to become unreadable. When this is false setting brightness
> >> to 0 may turn the backlight off, but this is not guaranteed.
> >> This will e.g. be true when directly driving a PWM and the video-BIOS
> >> has provided a minimum (non 0) duty-cycle below which the driver will
> >> never go.
> >
> > Hm. It's quite unfortunate that it's impossible to have strong guarantees
> > here.
> >
> > Is there any way we can avoid this prop?
>
> Not really, the problem is that we really don't know if 0 is off
> or min-brightness. In the given example where we actually never go
> down to a duty-cycle of 0% because the video BIOS tables tell us
> not to, we can be certain that setting the brightness prop to 0
> will not turn of the backlight, since we then set the duty-cycle
> to the VBT provided minimum. Note the intend here is to only set
> the boolean to true if the VBT provided minimum is _not_ 0, 0
> just means the vendor did not bother to provide a minimum.
>
> Currently e.g. GNOME never goes lower then something like 5%
> of brightness_max to avoid accidentally turning the screen off.
>
> Turning the screen off is quite bad to do on e.g. tablets where
> the GUI is the only way to undo the brightness change and now
> the user can no longer see the GUI.
>
> The idea behind this boolean is to give e.g. GNOME a way to
> know that it is safe to go down to 0% and for it to use
> the entire range.

Why not just make it policy that 0 is defined as minimum brightness,
not off, and have all drivers conform to that?

Alex

>
> > For instance if we can guarantee that the min level won't turn the screen
> > completely off we could make the range start from 1 instead of 0.
> > Or allow -1 to mean "minimum value, maybe completely off".
>
> Right, the problem is we really don't know and when the range is
> e.g. 0-65535 then something like 1 will almost always still just
> turn the screen completely off. There will be a value of say like
> 150 or some such which is then the actual minimum value to still
> get the backlight to light up at all. The problem is we have
> no clue what the actual minimum is. And if the PWM output does
> not directly drive the LEDs but is used as an input for some
> LED backlight driver chip, that chip itself may have a lookup
> table (which may also take care of doing perceived brightness
> mapping) and may guarantee a minimum backlight even when given
> a 0% duty cycle PWM signal...
>
> This prop is sort of orthogonal to the generic change to
> drm_connector props, so we could also do this later as a follow up
> change. At a minimum when I code this up this should be in its
> own commit(s) I believe.
>
> But I do think having this will be useful for the above
> GNOME example.
>
> >> bl_brightness_control_method: ro, enum, possible values:
> >> none: The GPU driver expects brightness control to be provided by another
> >> driver and that driver has not loaded yet.
> >> unknown: The underlying control mechanism is unknown.
> >> pwm: The brightness property directly controls the duty-cycle of a PWM
> >> output.
> >> firmware: The brightness is controlled through firmware calls.
> >> DDC/CI: The brightness is controlled through the DDC/CI protocol.
> >> gmux: The brightness is controlled by the GMUX.
> >> Note this enum may be extended in the future, so other values may
> >> be read, these should be treated as "unknown".
> >>
> >> When brightness control becomes available after being reported
> >> as not available before (bl_brightness_control_method=="none")
> >> a uevent with CONNECTOR=<connector-id> and
> >>
> >> PROPERTY=<bl_brightness_control_method-id> will be generated
> >>
> >> at this point all the properties must be re-read.
> >>
> >> When/once brightness control is available then all the read-only
> >> properties are fixed and will never change.
> >>
> >> Besides the "none" value for no driver having loaded yet,
> >> the different bl_brightness_control_method values are intended for
> >> (userspace) heuristics for such things as the brightness setting
> >> linearly controlling electrical power or setting perceived brightness.
> >
> > Can you elaborate? I don't know enough about brightness control to
> > understand all of the implications here.
>
> So after sending this email I was already thinking myself that this
> one might not be the best idea. Another shortcoming of the current
> backlight API is that it does not let userspace know if the
> number is a linear control of the time the LEDs are on vs off
> (assuming a LED backlight) or if some component already uses a
> lookup table to make 0-100% be more of a linear scale in the
> human perception, which is very much non linear. See e.g.:
>
> https://www.sciencedirect.com/topics/computer-science/perceived-brightness
>
> "refers to the perceived amount of light coming from self-luminous sources"
> "Perceived brightness is a very nonlinear function of the amount of light emitted by a lamp."
>
> The problem is that at the kernel level we have no idea if
> we are controlling "the amount of light emitted" or
> perceived brightness and it would be sorta nice for userspace
> to know. So the idea here is/was to allow userspace to make some
> educated guess here. E.g. a bl_brightness_control_method of "PWM"
> hints strongly at "the amount of light emitted" (but this is
> not true 100% of the time).  ATM userspace does not do any
> "perceived brightness" curve correction so for the first
> implementation of moving brightness control to drm properties
> I believe it might be better to just park the whole
> bl_brightness_control_method propery idea.
>
> Which would leave the problem of communicating the control_method=="none"
> case but we can just use bl_brightness_max == 0 for that.
>
> Regards,
>
> Hans
>
>
>

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-07 21:05     ` Alex Deucher
@ 2022-04-08  8:07       ` Daniel Vetter
  2022-04-08  9:58         ` Hans de Goede
  2022-04-08 14:08         ` Alex Deucher
  0 siblings, 2 replies; 44+ messages in thread
From: Daniel Vetter @ 2022-04-08  8:07 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	Hans de Goede, dri-devel, Yusuf Khan

On Thu, Apr 07, 2022 at 05:05:52PM -0400, Alex Deucher wrote:
> On Thu, Apr 7, 2022 at 1:43 PM Hans de Goede <hdegoede@redhat.com> wrote:
> >
> > Hi Simon,
> >
> > On 4/7/22 18:51, Simon Ser wrote:
> > > Very nice plan! Big +1 for the overall approach.
> >
> > Thanks.
> >
> > > On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
> > >
> > >> The drm_connector brightness properties
> > >> =======================================
> > >>
> > >> bl_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 bl_brightness_max.
> > >
> > > Do we need to split this up into two props for sw/hw state? The privacy screen
> > > stuff needed this, but you're pretty familiar with that. :)
> >
> > Luckily that won't be necessary, since the privacy-screen is a security
> > feature the firmware/embedded-controller may refuse our requests
> > (may temporarily lock-out changes) and/or may make changes without
> > us requesting them itself. Neither is really the case with the
> > brightness setting of displays.
> >
> > >> bl_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 (yet).
> > >
> > > I don't think we actually need that one. Integer KMS props all have a
> > > range which can be fetched via drmModeGetProperty. The max can be
> > > exposed via this range. Example with the existing alpha prop:
> > >
> > >     "alpha": range [0, UINT16_MAX] = 65535
> >
> > Right, I already knew that, which is why I explicitly added a range
> > to the props already. The problem is that the range must be set
> > before registering the connector and when the backlight driver
> > only shows up (much) later during boot then we don't know the
> > range when registering the connector. I guess we could "patch-up"
> > the range later. But AFAIK that would be a bit of abuse of the
> > property API as the range is intended to never change, not
> > even after hotplug uevents. At least atm there is no infra
> > in the kernel to change the range later.
> >
> > Which is why I added an explicit bl_brightness_max property
> > of which the value gives the actual effective maximum of the
> > brightness.

Uh ... I'm not a huge fan tbh. The thing is, if we allow hotplugging
brightness control later on then we just perpetuate the nonsense we have
right now, forever.

Imo we should support two kinds of drivers:

- drivers which are non-crap, and make sure their backlight driver is
  loaded before they register the drm_device (or at least the
  drm_connector). For those we want the drm_connector->backlight pointer
  to bit static over the lifetime of the connector, and then we can also
  set up the brightness range correctly.

- funny drivers which implement the glorious fallback dance which
  libbacklight implements currently in userspace. Imo for these drivers we
  should have a libbacklight_heuristics_backlight, which normalizes or
  whatever, and is also ways there. And then internally handles the
  fallback mess to the "right" backlight driver.

We might have some gaps on acpi systems to make sure the drm driver can
wait for the backlight driver to show up, but that's about it.

Hotplugging random pieces later on is really not how drivers work nowadays
with deferred probe and component framework and all that.

> > I did consider using the range for this and updating it
> > on the fly I think nothing is really preventing us from
> > doing so, but it very much feels like abusing the generic
> > properties API.
> >
> > >> bl_brightness_0_is_min_brightness: ro, boolean
> > >> When this is set to true then it is safe to set brightness to 0
> > >> without worrying that this completely turns the backlight off causing
> > >> the screen to become unreadable. When this is false setting brightness
> > >> to 0 may turn the backlight off, but this is not guaranteed.
> > >> This will e.g. be true when directly driving a PWM and the video-BIOS
> > >> has provided a minimum (non 0) duty-cycle below which the driver will
> > >> never go.
> > >
> > > Hm. It's quite unfortunate that it's impossible to have strong guarantees
> > > here.
> > >
> > > Is there any way we can avoid this prop?
> >
> > Not really, the problem is that we really don't know if 0 is off
> > or min-brightness. In the given example where we actually never go
> > down to a duty-cycle of 0% because the video BIOS tables tell us
> > not to, we can be certain that setting the brightness prop to 0
> > will not turn of the backlight, since we then set the duty-cycle
> > to the VBT provided minimum. Note the intend here is to only set
> > the boolean to true if the VBT provided minimum is _not_ 0, 0
> > just means the vendor did not bother to provide a minimum.
> >
> > Currently e.g. GNOME never goes lower then something like 5%
> > of brightness_max to avoid accidentally turning the screen off.
> >
> > Turning the screen off is quite bad to do on e.g. tablets where
> > the GUI is the only way to undo the brightness change and now
> > the user can no longer see the GUI.
> >
> > The idea behind this boolean is to give e.g. GNOME a way to
> > know that it is safe to go down to 0% and for it to use
> > the entire range.
> 
> Why not just make it policy that 0 is defined as minimum brightness,
> not off, and have all drivers conform to that?

Because the backlight subsystem isn't as consistent on this, and it's been
an epic source of confusion since forever.

What's worse, there's both userspace out there which assumes brightness =
0 is a really fast dpms off _and_ userspace that assumes that brightness =
0 is the lowest setting. Of course on different sets of machines.

So yeah we're screwed. I have no idea how to get out of this.
-Daniel

> 
> Alex
> 
> >
> > > For instance if we can guarantee that the min level won't turn the screen
> > > completely off we could make the range start from 1 instead of 0.
> > > Or allow -1 to mean "minimum value, maybe completely off".
> >
> > Right, the problem is we really don't know and when the range is
> > e.g. 0-65535 then something like 1 will almost always still just
> > turn the screen completely off. There will be a value of say like
> > 150 or some such which is then the actual minimum value to still
> > get the backlight to light up at all. The problem is we have
> > no clue what the actual minimum is. And if the PWM output does
> > not directly drive the LEDs but is used as an input for some
> > LED backlight driver chip, that chip itself may have a lookup
> > table (which may also take care of doing perceived brightness
> > mapping) and may guarantee a minimum backlight even when given
> > a 0% duty cycle PWM signal...
> >
> > This prop is sort of orthogonal to the generic change to
> > drm_connector props, so we could also do this later as a follow up
> > change. At a minimum when I code this up this should be in its
> > own commit(s) I believe.
> >
> > But I do think having this will be useful for the above
> > GNOME example.
> >
> > >> bl_brightness_control_method: ro, enum, possible values:
> > >> none: The GPU driver expects brightness control to be provided by another
> > >> driver and that driver has not loaded yet.
> > >> unknown: The underlying control mechanism is unknown.
> > >> pwm: The brightness property directly controls the duty-cycle of a PWM
> > >> output.
> > >> firmware: The brightness is controlled through firmware calls.
> > >> DDC/CI: The brightness is controlled through the DDC/CI protocol.
> > >> gmux: The brightness is controlled by the GMUX.
> > >> Note this enum may be extended in the future, so other values may
> > >> be read, these should be treated as "unknown".
> > >>
> > >> When brightness control becomes available after being reported
> > >> as not available before (bl_brightness_control_method=="none")
> > >> a uevent with CONNECTOR=<connector-id> and
> > >>
> > >> PROPERTY=<bl_brightness_control_method-id> will be generated
> > >>
> > >> at this point all the properties must be re-read.
> > >>
> > >> When/once brightness control is available then all the read-only
> > >> properties are fixed and will never change.
> > >>
> > >> Besides the "none" value for no driver having loaded yet,
> > >> the different bl_brightness_control_method values are intended for
> > >> (userspace) heuristics for such things as the brightness setting
> > >> linearly controlling electrical power or setting perceived brightness.
> > >
> > > Can you elaborate? I don't know enough about brightness control to
> > > understand all of the implications here.
> >
> > So after sending this email I was already thinking myself that this
> > one might not be the best idea. Another shortcoming of the current
> > backlight API is that it does not let userspace know if the
> > number is a linear control of the time the LEDs are on vs off
> > (assuming a LED backlight) or if some component already uses a
> > lookup table to make 0-100% be more of a linear scale in the
> > human perception, which is very much non linear. See e.g.:
> >
> > https://www.sciencedirect.com/topics/computer-science/perceived-brightness
> >
> > "refers to the perceived amount of light coming from self-luminous sources"
> > "Perceived brightness is a very nonlinear function of the amount of light emitted by a lamp."
> >
> > The problem is that at the kernel level we have no idea if
> > we are controlling "the amount of light emitted" or
> > perceived brightness and it would be sorta nice for userspace
> > to know. So the idea here is/was to allow userspace to make some
> > educated guess here. E.g. a bl_brightness_control_method of "PWM"
> > hints strongly at "the amount of light emitted" (but this is
> > not true 100% of the time).  ATM userspace does not do any
> > "perceived brightness" curve correction so for the first
> > implementation of moving brightness control to drm properties
> > I believe it might be better to just park the whole
> > bl_brightness_control_method propery idea.
> >
> > Which would leave the problem of communicating the control_method=="none"
> > case but we can just use bl_brightness_max == 0 for that.
> >
> > Regards,
> >
> > Hans
> >
> >
> >

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-07 17:43   ` Hans de Goede
  2022-04-07 21:05     ` Alex Deucher
@ 2022-04-08  8:22     ` Simon Ser
  2022-04-08 15:00       ` Hans de Goede
  2022-04-11 10:35       ` Hans de Goede
  1 sibling, 2 replies; 44+ messages in thread
From: Simon Ser @ 2022-04-08  8:22 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

Hi Hans,

Thanks for your details replies!

On Thursday, April 7th, 2022 at 19:43, Hans de Goede <hdegoede@redhat.com> wrote:

> > On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
> >
> >> The drm_connector brightness properties
> >> =======================================
> >>
> >> bl_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 bl_brightness_max.
> >
> > Do we need to split this up into two props for sw/hw state? The privacy screen
> > stuff needed this, but you're pretty familiar with that. :)
>
> Luckily that won't be necessary, since the privacy-screen is a security
> feature the firmware/embedded-controller may refuse our requests
> (may temporarily lock-out changes) and/or may make changes without
> us requesting them itself. Neither is really the case with the
> brightness setting of displays.

Cool, makes sense to me!

> >> bl_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 (yet).
> >
> > I don't think we actually need that one. Integer KMS props all have a
> > range which can be fetched via drmModeGetProperty. The max can be
> > exposed via this range. Example with the existing alpha prop:
> >
> >     "alpha": range [0, UINT16_MAX] = 65535
>
> Right, I already knew that, which is why I explicitly added a range
> to the props already. The problem is that the range must be set
> before registering the connector and when the backlight driver
> only shows up (much) later during boot then we don't know the
> range when registering the connector. I guess we could "patch-up"
> the range later. But AFAIK that would be a bit of abuse of the
> property API as the range is intended to never change, not
> even after hotplug uevents. At least atm there is no infra
> in the kernel to change the range later.
>
> Which is why I added an explicit bl_brightness_max property
> of which the value gives the actual effective maximum of the
> brightness.
>
> I did consider using the range for this and updating it
> on the fly I think nothing is really preventing us from
> doing so, but it very much feels like abusing the generic
> properties API.

Since this is new uAPI there's no concern about backwards compat here. So it's
pretty much a matter of how we want the uAPI to look like. I was suggesting
using a range because it's self-describing, but maybe it's an abuse.

Daniel Vetter, what do you think? If a property's range is going to be updated
on the fly, should we go for it, or should we use a separate prop to describe
the max value?

> >> bl_brightness_0_is_min_brightness: ro, boolean
> >> When this is set to true then it is safe to set brightness to 0
> >> without worrying that this completely turns the backlight off causing
> >> the screen to become unreadable. When this is false setting brightness
> >> to 0 may turn the backlight off, but this is not guaranteed.
> >> This will e.g. be true when directly driving a PWM and the video-BIOS
> >> has provided a minimum (non 0) duty-cycle below which the driver will
> >> never go.
> >
> > Hm. It's quite unfortunate that it's impossible to have strong guarantees
> > here.
> >
> > Is there any way we can avoid this prop?
>
> Not really, the problem is that we really don't know if 0 is off
> or min-brightness. In the given example where we actually never go
> down to a duty-cycle of 0% because the video BIOS tables tell us
> not to, we can be certain that setting the brightness prop to 0
> will not turn of the backlight, since we then set the duty-cycle
> to the VBT provided minimum. Note the intend here is to only set
> the boolean to true if the VBT provided minimum is _not_ 0, 0
> just means the vendor did not bother to provide a minimum.
>
> Currently e.g. GNOME never goes lower then something like 5%
> of brightness_max to avoid accidentally turning the screen off.
>
> Turning the screen off is quite bad to do on e.g. tablets where
> the GUI is the only way to undo the brightness change and now
> the user can no longer see the GUI.
>
> The idea behind this boolean is to give e.g. GNOME a way to
> know that it is safe to go down to 0% and for it to use
> the entire range.
>
> > For instance if we can guarantee that the min level won't turn the screen
> > completely off we could make the range start from 1 instead of 0.
> > Or allow -1 to mean "minimum value, maybe completely off".
>
> Right, the problem is we really don't know and when the range is
> e.g. 0-65535 then something like 1 will almost always still just
> turn the screen completely off. There will be a value of say like
> 150 or some such which is then the actual minimum value to still
> get the backlight to light up at all. The problem is we have
> no clue what the actual minimum is. And if the PWM output does
> not directly drive the LEDs but is used as an input for some
> LED backlight driver chip, that chip itself may have a lookup
> table (which may also take care of doing perceived brightness
> mapping) and may guarantee a minimum backlight even when given
> a 0% duty cycle PWM signal...

Oh, what a fun world we live in.

Would it be completely unreasonable to have a hwdb in the kernel to know the
real minimum value if it hasn't been provided by the VBT? Or would that be too
much of a colossal effort?

What happens in the DDC/CI world? What does 0 mean there? Is it the same messy
situation again?

> This prop is sort of orthogonal to the generic change to
> drm_connector props, so we could also do this later as a follow up
> change. At a minimum when I code this up this should be in its
> own commit(s) I believe.
>
> But I do think having this will be useful for the above
> GNOME example.
>
> >> bl_brightness_control_method: ro, enum, possible values:
> >> none: The GPU driver expects brightness control to be provided by another
> >> driver and that driver has not loaded yet.
> >> unknown: The underlying control mechanism is unknown.
> >> pwm: The brightness property directly controls the duty-cycle of a PWM
> >> output.
> >> firmware: The brightness is controlled through firmware calls.
> >> DDC/CI: The brightness is controlled through the DDC/CI protocol.
> >> gmux: The brightness is controlled by the GMUX.
> >> Note this enum may be extended in the future, so other values may
> >> be read, these should be treated as "unknown".
> >>
> >> When brightness control becomes available after being reported
> >> as not available before (bl_brightness_control_method=="none")
> >> a uevent with CONNECTOR=<connector-id> and
> >>
> >> PROPERTY=<bl_brightness_control_method-id> will be generated
> >>
> >> at this point all the properties must be re-read.
> >>
> >> When/once brightness control is available then all the read-only
> >> properties are fixed and will never change.
> >>
> >> Besides the "none" value for no driver having loaded yet,
> >> the different bl_brightness_control_method values are intended for
> >> (userspace) heuristics for such things as the brightness setting
> >> linearly controlling electrical power or setting perceived brightness.
> >
> > Can you elaborate? I don't know enough about brightness control to
> > understand all of the implications here.
>
> So after sending this email I was already thinking myself that this
> one might not be the best idea. Another shortcoming of the current
> backlight API is that it does not let userspace know if the
> number is a linear control of the time the LEDs are on vs off
> (assuming a LED backlight) or if some component already uses a
> lookup table to make 0-100% be more of a linear scale in the
> human perception, which is very much non linear. See e.g.:
>
> https://www.sciencedirect.com/topics/computer-science/perceived-brightness
>
> "refers to the perceived amount of light coming from self-luminous sources"
> "Perceived brightness is a very nonlinear function of the amount of light emitted by a lamp."
>
> The problem is that at the kernel level we have no idea if
> we are controlling "the amount of light emitted" or
> perceived brightness and it would be sorta nice for userspace
> to know. So the idea here is/was to allow userspace to make some
> educated guess here. E.g. a bl_brightness_control_method of "PWM"
> hints strongly at "the amount of light emitted" (but this is
> not true 100% of the time).  ATM userspace does not do any
> "perceived brightness" curve correction so for the first
> implementation of moving brightness control to drm properties
> I believe it might be better to just park the whole
> bl_brightness_control_method propery idea.

Hm, I see.

Are there other use-cases for this property besides the perceived brightness?

What other non-PWM methods set the perceived brightness (as opposed to
electrical power)?

As above, is it completely unreasonable to have a hwdb?

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-08  8:07       ` Daniel Vetter
@ 2022-04-08  9:58         ` Hans de Goede
  2022-04-08 10:09           ` Hans de Goede
  2022-04-08 10:23           ` Hans de Goede
  2022-04-08 14:08         ` Alex Deucher
  1 sibling, 2 replies; 44+ messages in thread
From: Hans de Goede @ 2022-04-08  9:58 UTC (permalink / raw)
  To: Daniel Vetter, Alex Deucher
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

Hi Daniel,

On 4/8/22 10:07, Daniel Vetter wrote:
> On Thu, Apr 07, 2022 at 05:05:52PM -0400, Alex Deucher wrote:
>> On Thu, Apr 7, 2022 at 1:43 PM Hans de Goede <hdegoede@redhat.com> wrote:
>>>
>>> Hi Simon,
>>>
>>> On 4/7/22 18:51, Simon Ser wrote:
>>>> Very nice plan! Big +1 for the overall approach.
>>>
>>> Thanks.
>>>
>>>> On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
>>>>
>>>>> The drm_connector brightness properties
>>>>> =======================================
>>>>>
>>>>> bl_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 bl_brightness_max.
>>>>
>>>> Do we need to split this up into two props for sw/hw state? The privacy screen
>>>> stuff needed this, but you're pretty familiar with that. :)
>>>
>>> Luckily that won't be necessary, since the privacy-screen is a security
>>> feature the firmware/embedded-controller may refuse our requests
>>> (may temporarily lock-out changes) and/or may make changes without
>>> us requesting them itself. Neither is really the case with the
>>> brightness setting of displays.
>>>
>>>>> bl_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 (yet).
>>>>
>>>> I don't think we actually need that one. Integer KMS props all have a
>>>> range which can be fetched via drmModeGetProperty. The max can be
>>>> exposed via this range. Example with the existing alpha prop:
>>>>
>>>>     "alpha": range [0, UINT16_MAX] = 65535
>>>
>>> Right, I already knew that, which is why I explicitly added a range
>>> to the props already. The problem is that the range must be set
>>> before registering the connector and when the backlight driver
>>> only shows up (much) later during boot then we don't know the
>>> range when registering the connector. I guess we could "patch-up"
>>> the range later. But AFAIK that would be a bit of abuse of the
>>> property API as the range is intended to never change, not
>>> even after hotplug uevents. At least atm there is no infra
>>> in the kernel to change the range later.
>>>
>>> Which is why I added an explicit bl_brightness_max property
>>> of which the value gives the actual effective maximum of the
>>> brightness.
> 
> Uh ... I'm not a huge fan tbh. The thing is, if we allow hotplugging
> brightness control later on then we just perpetuate the nonsense we have
> right now, forever.
> 
> Imo we should support two kinds of drivers:
> 
> - drivers which are non-crap, and make sure their backlight driver is
>   loaded before they register the drm_device (or at least the
>   drm_connector). For those we want the drm_connector->backlight pointer
>   to bit static over the lifetime of the connector, and then we can also
>   set up the brightness range correctly.

The only problem is that outside of device-tree platforms where
we can have a backlight link in a devicetree display-connector node,
there are no non crap devices and thus no non crap drivers.

> - funny drivers which implement the glorious fallback dance which
>   libbacklight implements currently in userspace. Imo for these drivers we
>   should have a libbacklight_heuristics_backlight, which normalizes or
>   whatever, and is also ways there. And then internally handles the
>   fallback mess to the "right" backlight driver.

So this will be pretty much all of them including i915 and nouveau.

My first thoughts where the same as yours and we can mostly guarantee
that the drm_connector->backlight pointer is static over lifetime of
the connector. But the problem is with the backlight device-s provided
by things like the dell-laptop, thinkpad_acpi, etc. drivers which are
still necessary / used for backlight control on core2duo era laptops
which are still being active used by people.

Basically atm the kernel code to determine which backlight-device
to use (which assumes a single internal LCD panel) goes like this (1):

1. Check cmdline-override, DMI quirks (and return their value if set)
2. If ACPI video extensions are not supported then expect a backlight
   device of the dell-laptop, thinkpad_acpi, etc. type, and use that.
3. If the ACPI tables have been written for Windows8 or later and
   the GPU driver offers a GPU native backlight device use that.
4. Use the ACPI video extensions backlight device

> We might have some gaps on acpi systems to make sure the drm driver can
> wait for the backlight driver to show up, but that's about it.

The problem here is 2. or IOW devices which don't support the
ACPI video extensions, these typically (always?) also don't offer
a GPU native backlight device, instead relying on
the embedded-controller for backlight control using some vendor
specific firmware API to talk to the EC.

For the other cases there are indeed some gaps which I plan to close
so that we can make sure that the backlight device will be in place
when we register the connector.

But the old devices without ACPI video extensions case is a big
problem and more then just some gaps" and that is a path which all
major x86 drivers may hit.

In some cases I even expect the backlight_device to simply never
show up when hitting 2. Either because the necessary driver is
not enabled in the kernel or because no-one ever added support for
the specific fw interface used on the laptop in question. But I
do expect this to be quite rare.

For the privacy-screen case where we had a similar issue this
was solved by in essence duplicating the detection part of the
privacy-screen drivers inside the drm_privacy code and use
-EPROBE_DEFER to wait for the privacy-screen driver to load.

But in this case that is not really feasible IMHO because:

[hans@shalem linux]$ ack -l backlight_device_register drivers/platform/x86
drivers/platform/x86/toshiba_acpi.c
drivers/platform/x86/intel/oaktrail.c
drivers/platform/x86/dell/dell-laptop.c
drivers/platform/x86/msi-laptop.c
drivers/platform/x86/panasonic-laptop.c
drivers/platform/x86/ideapad-laptop.c
drivers/platform/x86/sony-laptop.c
drivers/platform/x86/thinkpad_acpi.c
drivers/platform/x86/acer-wmi.c
drivers/platform/x86/samsung-q10.c
drivers/platform/x86/asus-wmi.c
drivers/platform/x86/apple-gmux.c
drivers/platform/x86/nvidia-wmi-ec-backlight.c
drivers/platform/x86/msi-wmi.c
drivers/platform/x86/asus-laptop.c
drivers/platform/x86/classmate-laptop.c
drivers/platform/x86/eeepc-laptop.c
drivers/platform/x86/fujitsu-laptop.c
drivers/platform/x86/samsung-laptop.c
drivers/platform/x86/compal-laptop.c
[hans@shalem linux]$ ack -l backlight_device_register drivers/platform/x86 | wc -l
20

Duplicating 20 wildly different ACPI/WMI backlight detection
routines is a bit much; and also something which I cannot test
easily and doing EPROBE_DEFER like behavior will require all
of these to also be available in the initrd.

So IMHO at least for devices relying on these it is best to allow
having the bl_brightness* properties be presend on the internal
LCD connector at registration time with a hint that they are
not functional and then send an uevent when they become functional.

I really see no other way to deal with these (old) devices.

Regards,

Hans


1) For now I, intend to extend this with detection of Apple GMUX and
   NVIDIA_WMI_EC_BACKLIGHT support


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-08  9:58         ` Hans de Goede
@ 2022-04-08 10:09           ` Hans de Goede
  2022-04-08 10:16             ` Simon Ser
  2022-04-08 10:23           ` Hans de Goede
  1 sibling, 1 reply; 44+ messages in thread
From: Hans de Goede @ 2022-04-08 10:09 UTC (permalink / raw)
  To: Daniel Vetter, Alex Deucher
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

Hi,

On 4/8/22 11:58, Hans de Goede wrote:
> Hi Daniel,
> 
> On 4/8/22 10:07, Daniel Vetter wrote:
>> On Thu, Apr 07, 2022 at 05:05:52PM -0400, Alex Deucher wrote:
>>> On Thu, Apr 7, 2022 at 1:43 PM Hans de Goede <hdegoede@redhat.com> wrote:
>>>>
>>>> Hi Simon,
>>>>
>>>> On 4/7/22 18:51, Simon Ser wrote:
>>>>> Very nice plan! Big +1 for the overall approach.
>>>>
>>>> Thanks.
>>>>
>>>>> On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
>>>>>
>>>>>> The drm_connector brightness properties
>>>>>> =======================================
>>>>>>
>>>>>> bl_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 bl_brightness_max.
>>>>>
>>>>> Do we need to split this up into two props for sw/hw state? The privacy screen
>>>>> stuff needed this, but you're pretty familiar with that. :)
>>>>
>>>> Luckily that won't be necessary, since the privacy-screen is a security
>>>> feature the firmware/embedded-controller may refuse our requests
>>>> (may temporarily lock-out changes) and/or may make changes without
>>>> us requesting them itself. Neither is really the case with the
>>>> brightness setting of displays.
>>>>
>>>>>> bl_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 (yet).
>>>>>
>>>>> I don't think we actually need that one. Integer KMS props all have a
>>>>> range which can be fetched via drmModeGetProperty. The max can be
>>>>> exposed via this range. Example with the existing alpha prop:
>>>>>
>>>>>     "alpha": range [0, UINT16_MAX] = 65535
>>>>
>>>> Right, I already knew that, which is why I explicitly added a range
>>>> to the props already. The problem is that the range must be set
>>>> before registering the connector and when the backlight driver
>>>> only shows up (much) later during boot then we don't know the
>>>> range when registering the connector. I guess we could "patch-up"
>>>> the range later. But AFAIK that would be a bit of abuse of the
>>>> property API as the range is intended to never change, not
>>>> even after hotplug uevents. At least atm there is no infra
>>>> in the kernel to change the range later.
>>>>
>>>> Which is why I added an explicit bl_brightness_max property
>>>> of which the value gives the actual effective maximum of the
>>>> brightness.
>>
>> Uh ... I'm not a huge fan tbh. The thing is, if we allow hotplugging
>> brightness control later on then we just perpetuate the nonsense we have
>> right now, forever.
>>
>> Imo we should support two kinds of drivers:
>>
>> - drivers which are non-crap, and make sure their backlight driver is
>>   loaded before they register the drm_device (or at least the
>>   drm_connector). For those we want the drm_connector->backlight pointer
>>   to bit static over the lifetime of the connector, and then we can also
>>   set up the brightness range correctly.
> 
> The only problem is that outside of device-tree platforms where
> we can have a backlight link in a devicetree display-connector node,
> there are no non crap devices and thus no non crap drivers.
> 
>> - funny drivers which implement the glorious fallback dance which
>>   libbacklight implements currently in userspace. Imo for these drivers we
>>   should have a libbacklight_heuristics_backlight, which normalizes or
>>   whatever, and is also ways there. And then internally handles the
>>   fallback mess to the "right" backlight driver.
> 
> So this will be pretty much all of them including i915 and nouveau.
> 
> My first thoughts where the same as yours and we can mostly guarantee
> that the drm_connector->backlight pointer is static over lifetime of
> the connector. But the problem is with the backlight device-s provided
> by things like the dell-laptop, thinkpad_acpi, etc. drivers which are
> still necessary / used for backlight control on core2duo era laptops
> which are still being active used by people.
> 
> Basically atm the kernel code to determine which backlight-device
> to use (which assumes a single internal LCD panel) goes like this (1):
> 
> 1. Check cmdline-override, DMI quirks (and return their value if set)
> 2. If ACPI video extensions are not supported then expect a backlight
>    device of the dell-laptop, thinkpad_acpi, etc. type, and use that.
> 3. If the ACPI tables have been written for Windows8 or later and
>    the GPU driver offers a GPU native backlight device use that.
> 4. Use the ACPI video extensions backlight device
> 
>> We might have some gaps on acpi systems to make sure the drm driver can
>> wait for the backlight driver to show up, but that's about it.
> 
> The problem here is 2. or IOW devices which don't support the
> ACPI video extensions, these typically (always?) also don't offer
> a GPU native backlight device, instead relying on
> the embedded-controller for backlight control using some vendor
> specific firmware API to talk to the EC.
> 
> For the other cases there are indeed some gaps which I plan to close
> so that we can make sure that the backlight device will be in place
> when we register the connector.
> 
> But the old devices without ACPI video extensions case is a big
> problem and more then just some gaps" and that is a path which all
> major x86 drivers may hit.
> 
> In some cases I even expect the backlight_device to simply never
> show up when hitting 2. Either because the necessary driver is
> not enabled in the kernel or because no-one ever added support for
> the specific fw interface used on the laptop in question. But I
> do expect this to be quite rare.
> 
> For the privacy-screen case where we had a similar issue this
> was solved by in essence duplicating the detection part of the
> privacy-screen drivers inside the drm_privacy code and use
> -EPROBE_DEFER to wait for the privacy-screen driver to load.
> 
> But in this case that is not really feasible IMHO because:
> 
> [hans@shalem linux]$ ack -l backlight_device_register drivers/platform/x86
> drivers/platform/x86/toshiba_acpi.c
> drivers/platform/x86/intel/oaktrail.c
> drivers/platform/x86/dell/dell-laptop.c
> drivers/platform/x86/msi-laptop.c
> drivers/platform/x86/panasonic-laptop.c
> drivers/platform/x86/ideapad-laptop.c
> drivers/platform/x86/sony-laptop.c
> drivers/platform/x86/thinkpad_acpi.c
> drivers/platform/x86/acer-wmi.c
> drivers/platform/x86/samsung-q10.c
> drivers/platform/x86/asus-wmi.c
> drivers/platform/x86/apple-gmux.c
> drivers/platform/x86/nvidia-wmi-ec-backlight.c
> drivers/platform/x86/msi-wmi.c
> drivers/platform/x86/asus-laptop.c
> drivers/platform/x86/classmate-laptop.c
> drivers/platform/x86/eeepc-laptop.c
> drivers/platform/x86/fujitsu-laptop.c
> drivers/platform/x86/samsung-laptop.c
> drivers/platform/x86/compal-laptop.c
> [hans@shalem linux]$ ack -l backlight_device_register drivers/platform/x86 | wc -l
> 20
> 
> Duplicating 20 wildly different ACPI/WMI backlight detection
> routines is a bit much; and also something which I cannot test
> easily and doing EPROBE_DEFER like behavior will require all
> of these to also be available in the initrd.
> 
> So IMHO at least for devices relying on these it is best to allow
> having the bl_brightness* properties be presend on the internal
> LCD connector at registration time with a hint that they are
> not functional and then send an uevent when they become functional.
> 
> I really see no other way to deal with these (old) devices.

Oh and one important thing which I forgot to add, it is these
old vendor specific firmware APIs for setting the backlight which
have the issue of having only say 8 levels, so scaling those
to 0-65535 leads to the:

"E.g GNOME decides
  on a step size for the hotkeys by doing min(brightness_max/20, 1).
  Some of the vendor specific backlight fw APIs (e.g. dell-laptop) have
  only 8 steps. When giving userspace the actual max_brightness value, then
  this will all work just fine. When hardcode brightness_max to 65535 OTOH
  then in this case GNOME will still give the user 20 steps where only 1
  in every 2-3 steps actually changes the brightness which IMHO is
  an unacceptably bad user experience."

problem from my original email starting the thread. One thing which
I did consider is to always scale to 0-65535 and then add a
"bl_brightness_step_size" property which would then be set to
65535/8 = 8192 in this case. But there are 2 disadvantages to this:

1. We still need a uevent for when the step-size changes once
the backlight-device finally shows up on impacted old devices
2. Scaling between the backlight device and the property value
sooner or later may lead to drift due to rounding issues.

So I don't really see this as better, TBH the whole scaling
+ reporting step-size thing feels significantly worse then
just updating brightness_max.

And then we would need to report step-size = 0 to report no
backlight device is available yet, which also feels worse then
using brightness_max=0 to indicate lack of brightness control.

Regards,

Hans


> 1) For now I, intend to extend this with detection of Apple GMUX and
>    NVIDIA_WMI_EC_BACKLIGHT support
> 


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-08 10:09           ` Hans de Goede
@ 2022-04-08 10:16             ` Simon Ser
  2022-04-08 10:26               ` Hans de Goede
  0 siblings, 1 reply; 44+ messages in thread
From: Simon Ser @ 2022-04-08 10:16 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

Would it be an option to only support the KMS prop for Good devices,
and continue using the suboptimal existing sysfs API for Bad devices?

(I'm just throwing ideas around to see what sticks, feel free to ignore.)

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-08  9:58         ` Hans de Goede
  2022-04-08 10:09           ` Hans de Goede
@ 2022-04-08 10:23           ` Hans de Goede
  1 sibling, 0 replies; 44+ messages in thread
From: Hans de Goede @ 2022-04-08 10:23 UTC (permalink / raw)
  To: Daniel Vetter, Alex Deucher, Carsten Haitzler
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

Hi,

On 4/8/22 11:58, Hans de Goede wrote:
> Hi Daniel,
> 
> On 4/8/22 10:07, Daniel Vetter wrote:
>> On Thu, Apr 07, 2022 at 05:05:52PM -0400, Alex Deucher wrote:
>>> On Thu, Apr 7, 2022 at 1:43 PM Hans de Goede <hdegoede@redhat.com> wrote:
>>>>
>>>> Hi Simon,
>>>>
>>>> On 4/7/22 18:51, Simon Ser wrote:
>>>>> Very nice plan! Big +1 for the overall approach.
>>>>
>>>> Thanks.
>>>>
>>>>> On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
>>>>>
>>>>>> The drm_connector brightness properties
>>>>>> =======================================
>>>>>>
>>>>>> bl_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 bl_brightness_max.
>>>>>
>>>>> Do we need to split this up into two props for sw/hw state? The privacy screen
>>>>> stuff needed this, but you're pretty familiar with that. :)
>>>>
>>>> Luckily that won't be necessary, since the privacy-screen is a security
>>>> feature the firmware/embedded-controller may refuse our requests
>>>> (may temporarily lock-out changes) and/or may make changes without
>>>> us requesting them itself. Neither is really the case with the
>>>> brightness setting of displays.
>>>>
>>>>>> bl_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 (yet).
>>>>>
>>>>> I don't think we actually need that one. Integer KMS props all have a
>>>>> range which can be fetched via drmModeGetProperty. The max can be
>>>>> exposed via this range. Example with the existing alpha prop:
>>>>>
>>>>>     "alpha": range [0, UINT16_MAX] = 65535
>>>>
>>>> Right, I already knew that, which is why I explicitly added a range
>>>> to the props already. The problem is that the range must be set
>>>> before registering the connector and when the backlight driver
>>>> only shows up (much) later during boot then we don't know the
>>>> range when registering the connector. I guess we could "patch-up"
>>>> the range later. But AFAIK that would be a bit of abuse of the
>>>> property API as the range is intended to never change, not
>>>> even after hotplug uevents. At least atm there is no infra
>>>> in the kernel to change the range later.
>>>>
>>>> Which is why I added an explicit bl_brightness_max property
>>>> of which the value gives the actual effective maximum of the
>>>> brightness.
>>
>> Uh ... I'm not a huge fan tbh. The thing is, if we allow hotplugging
>> brightness control later on then we just perpetuate the nonsense we have
>> right now, forever.
>>
>> Imo we should support two kinds of drivers:
>>
>> - drivers which are non-crap, and make sure their backlight driver is
>>   loaded before they register the drm_device (or at least the
>>   drm_connector). For those we want the drm_connector->backlight pointer
>>   to bit static over the lifetime of the connector, and then we can also
>>   set up the brightness range correctly.
> 
> The only problem is that outside of device-tree platforms where
> we can have a backlight link in a devicetree display-connector node,
> there are no non crap devices and thus no non crap drivers.
> 
>> - funny drivers which implement the glorious fallback dance which
>>   libbacklight implements currently in userspace. Imo for these drivers we
>>   should have a libbacklight_heuristics_backlight, which normalizes or
>>   whatever, and is also ways there. And then internally handles the
>>   fallback mess to the "right" backlight driver.
> 
> So this will be pretty much all of them including i915 and nouveau.
> 
> My first thoughts where the same as yours and we can mostly guarantee
> that the drm_connector->backlight pointer is static over lifetime of
> the connector. But the problem is with the backlight device-s provided
> by things like the dell-laptop, thinkpad_acpi, etc. drivers which are
> still necessary / used for backlight control on core2duo era laptops
> which are still being active used by people.
> 
> Basically atm the kernel code to determine which backlight-device
> to use (which assumes a single internal LCD panel) goes like this (1):
> 
> 1. Check cmdline-override, DMI quirks (and return their value if set)
> 2. If ACPI video extensions are not supported then expect a backlight
>    device of the dell-laptop, thinkpad_acpi, etc. type, and use that.
> 3. If the ACPI tables have been written for Windows8 or later and
>    the GPU driver offers a GPU native backlight device use that.
> 4. Use the ACPI video extensions backlight device
> 
>> We might have some gaps on acpi systems to make sure the drm driver can
>> wait for the backlight driver to show up, but that's about it.
> 
> The problem here is 2. or IOW devices which don't support the
> ACPI video extensions, these typically (always?) also don't offer
> a GPU native backlight device, instead relying on
> the embedded-controller for backlight control using some vendor
> specific firmware API to talk to the EC.
> 
> For the other cases there are indeed some gaps which I plan to close
> so that we can make sure that the backlight device will be in place
> when we register the connector.
> 
> But the old devices without ACPI video extensions case is a big
> problem and more then just some gaps" and that is a path which all
> major x86 drivers may hit.
> 
> In some cases I even expect the backlight_device to simply never
> show up when hitting 2. Either because the necessary driver is
> not enabled in the kernel or because no-one ever added support for
> the specific fw interface used on the laptop in question. But I
> do expect this to be quite rare.
> 
> For the privacy-screen case where we had a similar issue this
> was solved by in essence duplicating the detection part of the
> privacy-screen drivers inside the drm_privacy code and use
> -EPROBE_DEFER to wait for the privacy-screen driver to load.
> 
> But in this case that is not really feasible IMHO because:
> 
> [hans@shalem linux]$ ack -l backlight_device_register drivers/platform/x86
> drivers/platform/x86/toshiba_acpi.c
> drivers/platform/x86/intel/oaktrail.c
> drivers/platform/x86/dell/dell-laptop.c
> drivers/platform/x86/msi-laptop.c
> drivers/platform/x86/panasonic-laptop.c
> drivers/platform/x86/ideapad-laptop.c
> drivers/platform/x86/sony-laptop.c
> drivers/platform/x86/thinkpad_acpi.c
> drivers/platform/x86/acer-wmi.c
> drivers/platform/x86/samsung-q10.c
> drivers/platform/x86/asus-wmi.c
> drivers/platform/x86/apple-gmux.c
> drivers/platform/x86/nvidia-wmi-ec-backlight.c
> drivers/platform/x86/msi-wmi.c
> drivers/platform/x86/asus-laptop.c
> drivers/platform/x86/classmate-laptop.c
> drivers/platform/x86/eeepc-laptop.c
> drivers/platform/x86/fujitsu-laptop.c
> drivers/platform/x86/samsung-laptop.c
> drivers/platform/x86/compal-laptop.c
> [hans@shalem linux]$ ack -l backlight_device_register drivers/platform/x86 | wc -l
> 20
> 
> Duplicating 20 wildly different ACPI/WMI backlight detection
> routines is a bit much; and also something which I cannot test
> easily and doing EPROBE_DEFER like behavior will require all
> of these to also be available in the initrd.
> 
> So IMHO at least for devices relying on these it is best to allow
> having the bl_brightness* properties be presend on the internal
> LCD connector at registration time with a hint that they are
> not functional and then send an uevent when they become functional.
> 
> I really see no other way to deal with these (old) devices.

Oh and I just realized another important reason why we really
need to the support for this to be dynamic.

The reason why I've started looking into this (again) is because
Sebastian Wick has been looking into HDR support and he inquired
about support the brightness of external monitors through DDC/CI
and while we were discussing that a series was posted to add
DDC/CI support to /sys/class/backlight, which I nacked because
that would make the backlight-dev <-> connector mapping problem
a lot bigger:
https://lore.kernel.org/lkml/20220403230850.2986-1-yusisamerican@gmail.com/

But there clearly is demand for offering brightness control over
DDC/CI and the intend of this proposal is to also cover that.

But external devices can be plugged/unplugged and then DDC/CI
support may come and go and/or if a different monitor gets
plugged in the range may change. So we need support for brightness
control going away (brightness_max becomes 0) and for the range
changing on the fly regardless of the whole internal panel
discussion.

At least we must support this to support DDC/CI which at least
for me is an explicit goal here.

Regards,

Hans


> 1) For now I, intend to extend this with detection of Apple GMUX and
>    NVIDIA_WMI_EC_BACKLIGHT support


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-08 10:16             ` Simon Ser
@ 2022-04-08 10:26               ` Hans de Goede
  2022-04-13  8:32                 ` Daniel Vetter
  0 siblings, 1 reply; 44+ messages in thread
From: Hans de Goede @ 2022-04-08 10:26 UTC (permalink / raw)
  To: Simon Ser
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

Hi,

On 4/8/22 12:16, Simon Ser wrote:
> Would it be an option to only support the KMS prop for Good devices,
> and continue using the suboptimal existing sysfs API for Bad devices?
> 
> (I'm just throwing ideas around to see what sticks, feel free to ignore.)

Currently suid-root or pkexec helpers are used to deal with the
/sys/class/backlight requires root rights issue. I really want to
be able to disable these helpers at build time in e.g. GNOME once
the new properties are supported in GNOME.  So that distros with
a new enough kernel can reduce their attack surface this way.

Regards,

Hans



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-08  8:07       ` Daniel Vetter
  2022-04-08  9:58         ` Hans de Goede
@ 2022-04-08 14:08         ` Alex Deucher
  2022-04-08 14:55           ` Hans de Goede
  1 sibling, 1 reply; 44+ messages in thread
From: Alex Deucher @ 2022-04-08 14:08 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	Hans de Goede, dri-devel, Yusuf Khan

On Fri, Apr 8, 2022 at 4:07 AM Daniel Vetter <daniel@ffwll.ch> wrote:
>
> On Thu, Apr 07, 2022 at 05:05:52PM -0400, Alex Deucher wrote:
> > On Thu, Apr 7, 2022 at 1:43 PM Hans de Goede <hdegoede@redhat.com> wrote:
> > >
> > > Hi Simon,
> > >
> > > On 4/7/22 18:51, Simon Ser wrote:
> > > > Very nice plan! Big +1 for the overall approach.
> > >
> > > Thanks.
> > >
> > > > On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
> > > >
> > > >> The drm_connector brightness properties
> > > >> =======================================
> > > >>
> > > >> bl_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 bl_brightness_max.
> > > >
> > > > Do we need to split this up into two props for sw/hw state? The privacy screen
> > > > stuff needed this, but you're pretty familiar with that. :)
> > >
> > > Luckily that won't be necessary, since the privacy-screen is a security
> > > feature the firmware/embedded-controller may refuse our requests
> > > (may temporarily lock-out changes) and/or may make changes without
> > > us requesting them itself. Neither is really the case with the
> > > brightness setting of displays.
> > >
> > > >> bl_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 (yet).
> > > >
> > > > I don't think we actually need that one. Integer KMS props all have a
> > > > range which can be fetched via drmModeGetProperty. The max can be
> > > > exposed via this range. Example with the existing alpha prop:
> > > >
> > > >     "alpha": range [0, UINT16_MAX] = 65535
> > >
> > > Right, I already knew that, which is why I explicitly added a range
> > > to the props already. The problem is that the range must be set
> > > before registering the connector and when the backlight driver
> > > only shows up (much) later during boot then we don't know the
> > > range when registering the connector. I guess we could "patch-up"
> > > the range later. But AFAIK that would be a bit of abuse of the
> > > property API as the range is intended to never change, not
> > > even after hotplug uevents. At least atm there is no infra
> > > in the kernel to change the range later.
> > >
> > > Which is why I added an explicit bl_brightness_max property
> > > of which the value gives the actual effective maximum of the
> > > brightness.
>
> Uh ... I'm not a huge fan tbh. The thing is, if we allow hotplugging
> brightness control later on then we just perpetuate the nonsense we have
> right now, forever.
>
> Imo we should support two kinds of drivers:
>
> - drivers which are non-crap, and make sure their backlight driver is
>   loaded before they register the drm_device (or at least the
>   drm_connector). For those we want the drm_connector->backlight pointer
>   to bit static over the lifetime of the connector, and then we can also
>   set up the brightness range correctly.
>
> - funny drivers which implement the glorious fallback dance which
>   libbacklight implements currently in userspace. Imo for these drivers we
>   should have a libbacklight_heuristics_backlight, which normalizes or
>   whatever, and is also ways there. And then internally handles the
>   fallback mess to the "right" backlight driver.
>
> We might have some gaps on acpi systems to make sure the drm driver can
> wait for the backlight driver to show up, but that's about it.
>
> Hotplugging random pieces later on is really not how drivers work nowadays
> with deferred probe and component framework and all that.
>
> > > I did consider using the range for this and updating it
> > > on the fly I think nothing is really preventing us from
> > > doing so, but it very much feels like abusing the generic
> > > properties API.
> > >
> > > >> bl_brightness_0_is_min_brightness: ro, boolean
> > > >> When this is set to true then it is safe to set brightness to 0
> > > >> without worrying that this completely turns the backlight off causing
> > > >> the screen to become unreadable. When this is false setting brightness
> > > >> to 0 may turn the backlight off, but this is not guaranteed.
> > > >> This will e.g. be true when directly driving a PWM and the video-BIOS
> > > >> has provided a minimum (non 0) duty-cycle below which the driver will
> > > >> never go.
> > > >
> > > > Hm. It's quite unfortunate that it's impossible to have strong guarantees
> > > > here.
> > > >
> > > > Is there any way we can avoid this prop?
> > >
> > > Not really, the problem is that we really don't know if 0 is off
> > > or min-brightness. In the given example where we actually never go
> > > down to a duty-cycle of 0% because the video BIOS tables tell us
> > > not to, we can be certain that setting the brightness prop to 0
> > > will not turn of the backlight, since we then set the duty-cycle
> > > to the VBT provided minimum. Note the intend here is to only set
> > > the boolean to true if the VBT provided minimum is _not_ 0, 0
> > > just means the vendor did not bother to provide a minimum.
> > >
> > > Currently e.g. GNOME never goes lower then something like 5%
> > > of brightness_max to avoid accidentally turning the screen off.
> > >
> > > Turning the screen off is quite bad to do on e.g. tablets where
> > > the GUI is the only way to undo the brightness change and now
> > > the user can no longer see the GUI.
> > >
> > > The idea behind this boolean is to give e.g. GNOME a way to
> > > know that it is safe to go down to 0% and for it to use
> > > the entire range.
> >
> > Why not just make it policy that 0 is defined as minimum brightness,
> > not off, and have all drivers conform to that?
>
> Because the backlight subsystem isn't as consistent on this, and it's been
> an epic source of confusion since forever.
>
> What's worse, there's both userspace out there which assumes brightness =
> 0 is a really fast dpms off _and_ userspace that assumes that brightness =
> 0 is the lowest setting. Of course on different sets of machines.
>
> So yeah we're screwed. I have no idea how to get out of this.

Yes, but this is a new API.  So can't we do better?  Sure the old
backlight interface is broken, but why carry around clunky workarounds
for new interfaces?

Alex

> -Daniel
>
> >
> > Alex
> >
> > >
> > > > For instance if we can guarantee that the min level won't turn the screen
> > > > completely off we could make the range start from 1 instead of 0.
> > > > Or allow -1 to mean "minimum value, maybe completely off".
> > >
> > > Right, the problem is we really don't know and when the range is
> > > e.g. 0-65535 then something like 1 will almost always still just
> > > turn the screen completely off. There will be a value of say like
> > > 150 or some such which is then the actual minimum value to still
> > > get the backlight to light up at all. The problem is we have
> > > no clue what the actual minimum is. And if the PWM output does
> > > not directly drive the LEDs but is used as an input for some
> > > LED backlight driver chip, that chip itself may have a lookup
> > > table (which may also take care of doing perceived brightness
> > > mapping) and may guarantee a minimum backlight even when given
> > > a 0% duty cycle PWM signal...
> > >
> > > This prop is sort of orthogonal to the generic change to
> > > drm_connector props, so we could also do this later as a follow up
> > > change. At a minimum when I code this up this should be in its
> > > own commit(s) I believe.
> > >
> > > But I do think having this will be useful for the above
> > > GNOME example.
> > >
> > > >> bl_brightness_control_method: ro, enum, possible values:
> > > >> none: The GPU driver expects brightness control to be provided by another
> > > >> driver and that driver has not loaded yet.
> > > >> unknown: The underlying control mechanism is unknown.
> > > >> pwm: The brightness property directly controls the duty-cycle of a PWM
> > > >> output.
> > > >> firmware: The brightness is controlled through firmware calls.
> > > >> DDC/CI: The brightness is controlled through the DDC/CI protocol.
> > > >> gmux: The brightness is controlled by the GMUX.
> > > >> Note this enum may be extended in the future, so other values may
> > > >> be read, these should be treated as "unknown".
> > > >>
> > > >> When brightness control becomes available after being reported
> > > >> as not available before (bl_brightness_control_method=="none")
> > > >> a uevent with CONNECTOR=<connector-id> and
> > > >>
> > > >> PROPERTY=<bl_brightness_control_method-id> will be generated
> > > >>
> > > >> at this point all the properties must be re-read.
> > > >>
> > > >> When/once brightness control is available then all the read-only
> > > >> properties are fixed and will never change.
> > > >>
> > > >> Besides the "none" value for no driver having loaded yet,
> > > >> the different bl_brightness_control_method values are intended for
> > > >> (userspace) heuristics for such things as the brightness setting
> > > >> linearly controlling electrical power or setting perceived brightness.
> > > >
> > > > Can you elaborate? I don't know enough about brightness control to
> > > > understand all of the implications here.
> > >
> > > So after sending this email I was already thinking myself that this
> > > one might not be the best idea. Another shortcoming of the current
> > > backlight API is that it does not let userspace know if the
> > > number is a linear control of the time the LEDs are on vs off
> > > (assuming a LED backlight) or if some component already uses a
> > > lookup table to make 0-100% be more of a linear scale in the
> > > human perception, which is very much non linear. See e.g.:
> > >
> > > https://www.sciencedirect.com/topics/computer-science/perceived-brightness
> > >
> > > "refers to the perceived amount of light coming from self-luminous sources"
> > > "Perceived brightness is a very nonlinear function of the amount of light emitted by a lamp."
> > >
> > > The problem is that at the kernel level we have no idea if
> > > we are controlling "the amount of light emitted" or
> > > perceived brightness and it would be sorta nice for userspace
> > > to know. So the idea here is/was to allow userspace to make some
> > > educated guess here. E.g. a bl_brightness_control_method of "PWM"
> > > hints strongly at "the amount of light emitted" (but this is
> > > not true 100% of the time).  ATM userspace does not do any
> > > "perceived brightness" curve correction so for the first
> > > implementation of moving brightness control to drm properties
> > > I believe it might be better to just park the whole
> > > bl_brightness_control_method propery idea.
> > >
> > > Which would leave the problem of communicating the control_method=="none"
> > > case but we can just use bl_brightness_max == 0 for that.
> > >
> > > Regards,
> > >
> > > Hans
> > >
> > >
> > >
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-08 14:08         ` Alex Deucher
@ 2022-04-08 14:55           ` Hans de Goede
  2022-04-08 15:11             ` Alex Deucher
  0 siblings, 1 reply; 44+ messages in thread
From: Hans de Goede @ 2022-04-08 14:55 UTC (permalink / raw)
  To: Alex Deucher, Daniel Vetter
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

Hi,

On 4/8/22 16:08, Alex Deucher wrote:
> On Fri, Apr 8, 2022 at 4:07 AM Daniel Vetter <daniel@ffwll.ch> wrote:
>>
>> On Thu, Apr 07, 2022 at 05:05:52PM -0400, Alex Deucher wrote:
>>> On Thu, Apr 7, 2022 at 1:43 PM Hans de Goede <hdegoede@redhat.com> wrote:
>>>>
>>>> Hi Simon,
>>>>
>>>> On 4/7/22 18:51, Simon Ser wrote:
>>>>> Very nice plan! Big +1 for the overall approach.
>>>>
>>>> Thanks.
>>>>
>>>>> On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
>>>>>
>>>>>> The drm_connector brightness properties
>>>>>> =======================================
>>>>>>
>>>>>> bl_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 bl_brightness_max.
>>>>>
>>>>> Do we need to split this up into two props for sw/hw state? The privacy screen
>>>>> stuff needed this, but you're pretty familiar with that. :)
>>>>
>>>> Luckily that won't be necessary, since the privacy-screen is a security
>>>> feature the firmware/embedded-controller may refuse our requests
>>>> (may temporarily lock-out changes) and/or may make changes without
>>>> us requesting them itself. Neither is really the case with the
>>>> brightness setting of displays.
>>>>
>>>>>> bl_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 (yet).
>>>>>
>>>>> I don't think we actually need that one. Integer KMS props all have a
>>>>> range which can be fetched via drmModeGetProperty. The max can be
>>>>> exposed via this range. Example with the existing alpha prop:
>>>>>
>>>>>     "alpha": range [0, UINT16_MAX] = 65535
>>>>
>>>> Right, I already knew that, which is why I explicitly added a range
>>>> to the props already. The problem is that the range must be set
>>>> before registering the connector and when the backlight driver
>>>> only shows up (much) later during boot then we don't know the
>>>> range when registering the connector. I guess we could "patch-up"
>>>> the range later. But AFAIK that would be a bit of abuse of the
>>>> property API as the range is intended to never change, not
>>>> even after hotplug uevents. At least atm there is no infra
>>>> in the kernel to change the range later.
>>>>
>>>> Which is why I added an explicit bl_brightness_max property
>>>> of which the value gives the actual effective maximum of the
>>>> brightness.
>>
>> Uh ... I'm not a huge fan tbh. The thing is, if we allow hotplugging
>> brightness control later on then we just perpetuate the nonsense we have
>> right now, forever.
>>
>> Imo we should support two kinds of drivers:
>>
>> - drivers which are non-crap, and make sure their backlight driver is
>>   loaded before they register the drm_device (or at least the
>>   drm_connector). For those we want the drm_connector->backlight pointer
>>   to bit static over the lifetime of the connector, and then we can also
>>   set up the brightness range correctly.
>>
>> - funny drivers which implement the glorious fallback dance which
>>   libbacklight implements currently in userspace. Imo for these drivers we
>>   should have a libbacklight_heuristics_backlight, which normalizes or
>>   whatever, and is also ways there. And then internally handles the
>>   fallback mess to the "right" backlight driver.
>>
>> We might have some gaps on acpi systems to make sure the drm driver can
>> wait for the backlight driver to show up, but that's about it.
>>
>> Hotplugging random pieces later on is really not how drivers work nowadays
>> with deferred probe and component framework and all that.
>>
>>>> I did consider using the range for this and updating it
>>>> on the fly I think nothing is really preventing us from
>>>> doing so, but it very much feels like abusing the generic
>>>> properties API.
>>>>
>>>>>> bl_brightness_0_is_min_brightness: ro, boolean
>>>>>> When this is set to true then it is safe to set brightness to 0
>>>>>> without worrying that this completely turns the backlight off causing
>>>>>> the screen to become unreadable. When this is false setting brightness
>>>>>> to 0 may turn the backlight off, but this is not guaranteed.
>>>>>> This will e.g. be true when directly driving a PWM and the video-BIOS
>>>>>> has provided a minimum (non 0) duty-cycle below which the driver will
>>>>>> never go.
>>>>>
>>>>> Hm. It's quite unfortunate that it's impossible to have strong guarantees
>>>>> here.
>>>>>
>>>>> Is there any way we can avoid this prop?
>>>>
>>>> Not really, the problem is that we really don't know if 0 is off
>>>> or min-brightness. In the given example where we actually never go
>>>> down to a duty-cycle of 0% because the video BIOS tables tell us
>>>> not to, we can be certain that setting the brightness prop to 0
>>>> will not turn of the backlight, since we then set the duty-cycle
>>>> to the VBT provided minimum. Note the intend here is to only set
>>>> the boolean to true if the VBT provided minimum is _not_ 0, 0
>>>> just means the vendor did not bother to provide a minimum.
>>>>
>>>> Currently e.g. GNOME never goes lower then something like 5%
>>>> of brightness_max to avoid accidentally turning the screen off.
>>>>
>>>> Turning the screen off is quite bad to do on e.g. tablets where
>>>> the GUI is the only way to undo the brightness change and now
>>>> the user can no longer see the GUI.
>>>>
>>>> The idea behind this boolean is to give e.g. GNOME a way to
>>>> know that it is safe to go down to 0% and for it to use
>>>> the entire range.
>>>
>>> Why not just make it policy that 0 is defined as minimum brightness,
>>> not off, and have all drivers conform to that?
>>
>> Because the backlight subsystem isn't as consistent on this, and it's been
>> an epic source of confusion since forever.
>>
>> What's worse, there's both userspace out there which assumes brightness =
>> 0 is a really fast dpms off _and_ userspace that assumes that brightness =
>> 0 is the lowest setting. Of course on different sets of machines.
>>
>> So yeah we're screwed. I have no idea how to get out of this.
> 
> Yes, but this is a new API.  So can't we do better?  Sure the old
> backlight interface is broken, but why carry around clunky workarounds
> for new interfaces?

Right we certainly need to define the behavior of the new API
clearly, so that userspace does not misuse / misinterpret it.

The intend is for brightness=0 to mean minimum brightness
to still be able to see what is on the screen. But the problem
is that in many cases the GPU driver directly controls a PWM
output, no minimum PWM value is given in the video BIOS tables
and actually setting the PWM to 0% dutycycle turns off the
screen.

So we can only promise a best-effort to make brightness=0
mean minimum brightness, combined with documenting that it
may turn off the backlight and that userspace _must_ never
depend on it turning off the backlight.

Also note that setting a direct PWM output to duty-cycle 0%
does not guarantee that the backlight goes off, this may be
an input for a special backlight LED driver IC like the
TI LP855x series which can have an internal lookup
table causing it to actually output a minimum brightness
when its PWM input is at 0% dutycycle.  So this is a case
where we just don't get enough info from the fw/hw to be able
to offer the guarantees which we would like to guarantee.

Regards,

Hans






^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-08  8:22     ` Simon Ser
@ 2022-04-08 15:00       ` Hans de Goede
  2022-04-11 10:35       ` Hans de Goede
  1 sibling, 0 replies; 44+ messages in thread
From: Hans de Goede @ 2022-04-08 15:00 UTC (permalink / raw)
  To: Simon Ser
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

Hi Simon,

On 4/8/22 10:22, Simon Ser wrote:
> Hi Hans,
> 
> Thanks for your details replies!
> 
> On Thursday, April 7th, 2022 at 19:43, Hans de Goede <hdegoede@redhat.com> wrote:
> 
>>> On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
>>>
>>>> The drm_connector brightness properties
>>>> =======================================
>>>>
>>>> bl_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 bl_brightness_max.
>>>
>>> Do we need to split this up into two props for sw/hw state? The privacy screen
>>> stuff needed this, but you're pretty familiar with that. :)
>>
>> Luckily that won't be necessary, since the privacy-screen is a security
>> feature the firmware/embedded-controller may refuse our requests
>> (may temporarily lock-out changes) and/or may make changes without
>> us requesting them itself. Neither is really the case with the
>> brightness setting of displays.
> 
> Cool, makes sense to me!
> 
>>>> bl_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 (yet).
>>>
>>> I don't think we actually need that one. Integer KMS props all have a
>>> range which can be fetched via drmModeGetProperty. The max can be
>>> exposed via this range. Example with the existing alpha prop:
>>>
>>>     "alpha": range [0, UINT16_MAX] = 65535
>>
>> Right, I already knew that, which is why I explicitly added a range
>> to the props already. The problem is that the range must be set
>> before registering the connector and when the backlight driver
>> only shows up (much) later during boot then we don't know the
>> range when registering the connector. I guess we could "patch-up"
>> the range later. But AFAIK that would be a bit of abuse of the
>> property API as the range is intended to never change, not
>> even after hotplug uevents. At least atm there is no infra
>> in the kernel to change the range later.
>>
>> Which is why I added an explicit bl_brightness_max property
>> of which the value gives the actual effective maximum of the
>> brightness.
>>
>> I did consider using the range for this and updating it
>> on the fly I think nothing is really preventing us from
>> doing so, but it very much feels like abusing the generic
>> properties API.
> 
> Since this is new uAPI there's no concern about backwards compat here. So it's
> pretty much a matter of how we want the uAPI to look like. I was suggesting
> using a range because it's self-describing, but maybe it's an abuse.
> 
> Daniel Vetter, what do you think? If a property's range is going to be updated
> on the fly, should we go for it, or should we use a separate prop to describe
> the max value?
> 
>>>> bl_brightness_0_is_min_brightness: ro, boolean
>>>> When this is set to true then it is safe to set brightness to 0
>>>> without worrying that this completely turns the backlight off causing
>>>> the screen to become unreadable. When this is false setting brightness
>>>> to 0 may turn the backlight off, but this is not guaranteed.
>>>> This will e.g. be true when directly driving a PWM and the video-BIOS
>>>> has provided a minimum (non 0) duty-cycle below which the driver will
>>>> never go.
>>>
>>> Hm. It's quite unfortunate that it's impossible to have strong guarantees
>>> here.
>>>
>>> Is there any way we can avoid this prop?
>>
>> Not really, the problem is that we really don't know if 0 is off
>> or min-brightness. In the given example where we actually never go
>> down to a duty-cycle of 0% because the video BIOS tables tell us
>> not to, we can be certain that setting the brightness prop to 0
>> will not turn of the backlight, since we then set the duty-cycle
>> to the VBT provided minimum. Note the intend here is to only set
>> the boolean to true if the VBT provided minimum is _not_ 0, 0
>> just means the vendor did not bother to provide a minimum.
>>
>> Currently e.g. GNOME never goes lower then something like 5%
>> of brightness_max to avoid accidentally turning the screen off.
>>
>> Turning the screen off is quite bad to do on e.g. tablets where
>> the GUI is the only way to undo the brightness change and now
>> the user can no longer see the GUI.
>>
>> The idea behind this boolean is to give e.g. GNOME a way to
>> know that it is safe to go down to 0% and for it to use
>> the entire range.
>>
>>> For instance if we can guarantee that the min level won't turn the screen
>>> completely off we could make the range start from 1 instead of 0.
>>> Or allow -1 to mean "minimum value, maybe completely off".
>>
>> Right, the problem is we really don't know and when the range is
>> e.g. 0-65535 then something like 1 will almost always still just
>> turn the screen completely off. There will be a value of say like
>> 150 or some such which is then the actual minimum value to still
>> get the backlight to light up at all. The problem is we have
>> no clue what the actual minimum is. And if the PWM output does
>> not directly drive the LEDs but is used as an input for some
>> LED backlight driver chip, that chip itself may have a lookup
>> table (which may also take care of doing perceived brightness
>> mapping) and may guarantee a minimum backlight even when given
>> a 0% duty cycle PWM signal...
> 
> Oh, what a fun world we live in.
> 
> Would it be completely unreasonable to have a hwdb in the kernel to know the
> real minimum value if it hasn't been provided by the VBT? Or would that be too
> much of a colossal effort?

I'm afraid that that is not feasible, there are way to many laptop
models and for a single model different batches often use different
panels, so the amount model + panel combos such a hwdb would need
to contain is very large.
> What happens in the DDC/CI world? What does 0 mean there? Is it the same messy
> situation again?

I would expect 0 to pretty much always be min brightness there I
don't expect an external  monitor to allow turning off the backlight
outside of DPMS, otherwise if the brightness is controlled through the
OSD users won't be able to get it back to a functional value and
they will get way too much support calls.

> 
>> This prop is sort of orthogonal to the generic change to
>> drm_connector props, so we could also do this later as a follow up
>> change. At a minimum when I code this up this should be in its
>> own commit(s) I believe.
>>
>> But I do think having this will be useful for the above
>> GNOME example.
>>
>>>> bl_brightness_control_method: ro, enum, possible values:
>>>> none: The GPU driver expects brightness control to be provided by another
>>>> driver and that driver has not loaded yet.
>>>> unknown: The underlying control mechanism is unknown.
>>>> pwm: The brightness property directly controls the duty-cycle of a PWM
>>>> output.
>>>> firmware: The brightness is controlled through firmware calls.
>>>> DDC/CI: The brightness is controlled through the DDC/CI protocol.
>>>> gmux: The brightness is controlled by the GMUX.
>>>> Note this enum may be extended in the future, so other values may
>>>> be read, these should be treated as "unknown".
>>>>
>>>> When brightness control becomes available after being reported
>>>> as not available before (bl_brightness_control_method=="none")
>>>> a uevent with CONNECTOR=<connector-id> and
>>>>
>>>> PROPERTY=<bl_brightness_control_method-id> will be generated
>>>>
>>>> at this point all the properties must be re-read.
>>>>
>>>> When/once brightness control is available then all the read-only
>>>> properties are fixed and will never change.
>>>>
>>>> Besides the "none" value for no driver having loaded yet,
>>>> the different bl_brightness_control_method values are intended for
>>>> (userspace) heuristics for such things as the brightness setting
>>>> linearly controlling electrical power or setting perceived brightness.
>>>
>>> Can you elaborate? I don't know enough about brightness control to
>>> understand all of the implications here.
>>
>> So after sending this email I was already thinking myself that this
>> one might not be the best idea. Another shortcoming of the current
>> backlight API is that it does not let userspace know if the
>> number is a linear control of the time the LEDs are on vs off
>> (assuming a LED backlight) or if some component already uses a
>> lookup table to make 0-100% be more of a linear scale in the
>> human perception, which is very much non linear. See e.g.:
>>
>> https://www.sciencedirect.com/topics/computer-science/perceived-brightness
>>
>> "refers to the perceived amount of light coming from self-luminous sources"
>> "Perceived brightness is a very nonlinear function of the amount of light emitted by a lamp."
>>
>> The problem is that at the kernel level we have no idea if
>> we are controlling "the amount of light emitted" or
>> perceived brightness and it would be sorta nice for userspace
>> to know. So the idea here is/was to allow userspace to make some
>> educated guess here. E.g. a bl_brightness_control_method of "PWM"
>> hints strongly at "the amount of light emitted" (but this is
>> not true 100% of the time).  ATM userspace does not do any
>> "perceived brightness" curve correction so for the first
>> implementation of moving brightness control to drm properties
>> I believe it might be better to just park the whole
>> bl_brightness_control_method propery idea.
> 
> Hm, I see.
> 
> Are there other use-cases for this property besides the perceived brightness?

No not really, the more I think about it the more I think that this is
a half-baked idea and for now I plan to not add this property to any
patches implementing this proposal.

Regards,

Hans


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-08 14:55           ` Hans de Goede
@ 2022-04-08 15:11             ` Alex Deucher
  2022-04-11 10:18               ` Hans de Goede
  0 siblings, 1 reply; 44+ messages in thread
From: Alex Deucher @ 2022-04-08 15:11 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

On Fri, Apr 8, 2022 at 10:56 AM Hans de Goede <hdegoede@redhat.com> wrote:
>
> Hi,
>
> On 4/8/22 16:08, Alex Deucher wrote:
> > On Fri, Apr 8, 2022 at 4:07 AM Daniel Vetter <daniel@ffwll.ch> wrote:
> >>
> >> On Thu, Apr 07, 2022 at 05:05:52PM -0400, Alex Deucher wrote:
> >>> On Thu, Apr 7, 2022 at 1:43 PM Hans de Goede <hdegoede@redhat.com> wrote:
> >>>>
> >>>> Hi Simon,
> >>>>
> >>>> On 4/7/22 18:51, Simon Ser wrote:
> >>>>> Very nice plan! Big +1 for the overall approach.
> >>>>
> >>>> Thanks.
> >>>>
> >>>>> On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
> >>>>>
> >>>>>> The drm_connector brightness properties
> >>>>>> =======================================
> >>>>>>
> >>>>>> bl_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 bl_brightness_max.
> >>>>>
> >>>>> Do we need to split this up into two props for sw/hw state? The privacy screen
> >>>>> stuff needed this, but you're pretty familiar with that. :)
> >>>>
> >>>> Luckily that won't be necessary, since the privacy-screen is a security
> >>>> feature the firmware/embedded-controller may refuse our requests
> >>>> (may temporarily lock-out changes) and/or may make changes without
> >>>> us requesting them itself. Neither is really the case with the
> >>>> brightness setting of displays.
> >>>>
> >>>>>> bl_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 (yet).
> >>>>>
> >>>>> I don't think we actually need that one. Integer KMS props all have a
> >>>>> range which can be fetched via drmModeGetProperty. The max can be
> >>>>> exposed via this range. Example with the existing alpha prop:
> >>>>>
> >>>>>     "alpha": range [0, UINT16_MAX] = 65535
> >>>>
> >>>> Right, I already knew that, which is why I explicitly added a range
> >>>> to the props already. The problem is that the range must be set
> >>>> before registering the connector and when the backlight driver
> >>>> only shows up (much) later during boot then we don't know the
> >>>> range when registering the connector. I guess we could "patch-up"
> >>>> the range later. But AFAIK that would be a bit of abuse of the
> >>>> property API as the range is intended to never change, not
> >>>> even after hotplug uevents. At least atm there is no infra
> >>>> in the kernel to change the range later.
> >>>>
> >>>> Which is why I added an explicit bl_brightness_max property
> >>>> of which the value gives the actual effective maximum of the
> >>>> brightness.
> >>
> >> Uh ... I'm not a huge fan tbh. The thing is, if we allow hotplugging
> >> brightness control later on then we just perpetuate the nonsense we have
> >> right now, forever.
> >>
> >> Imo we should support two kinds of drivers:
> >>
> >> - drivers which are non-crap, and make sure their backlight driver is
> >>   loaded before they register the drm_device (or at least the
> >>   drm_connector). For those we want the drm_connector->backlight pointer
> >>   to bit static over the lifetime of the connector, and then we can also
> >>   set up the brightness range correctly.
> >>
> >> - funny drivers which implement the glorious fallback dance which
> >>   libbacklight implements currently in userspace. Imo for these drivers we
> >>   should have a libbacklight_heuristics_backlight, which normalizes or
> >>   whatever, and is also ways there. And then internally handles the
> >>   fallback mess to the "right" backlight driver.
> >>
> >> We might have some gaps on acpi systems to make sure the drm driver can
> >> wait for the backlight driver to show up, but that's about it.
> >>
> >> Hotplugging random pieces later on is really not how drivers work nowadays
> >> with deferred probe and component framework and all that.
> >>
> >>>> I did consider using the range for this and updating it
> >>>> on the fly I think nothing is really preventing us from
> >>>> doing so, but it very much feels like abusing the generic
> >>>> properties API.
> >>>>
> >>>>>> bl_brightness_0_is_min_brightness: ro, boolean
> >>>>>> When this is set to true then it is safe to set brightness to 0
> >>>>>> without worrying that this completely turns the backlight off causing
> >>>>>> the screen to become unreadable. When this is false setting brightness
> >>>>>> to 0 may turn the backlight off, but this is not guaranteed.
> >>>>>> This will e.g. be true when directly driving a PWM and the video-BIOS
> >>>>>> has provided a minimum (non 0) duty-cycle below which the driver will
> >>>>>> never go.
> >>>>>
> >>>>> Hm. It's quite unfortunate that it's impossible to have strong guarantees
> >>>>> here.
> >>>>>
> >>>>> Is there any way we can avoid this prop?
> >>>>
> >>>> Not really, the problem is that we really don't know if 0 is off
> >>>> or min-brightness. In the given example where we actually never go
> >>>> down to a duty-cycle of 0% because the video BIOS tables tell us
> >>>> not to, we can be certain that setting the brightness prop to 0
> >>>> will not turn of the backlight, since we then set the duty-cycle
> >>>> to the VBT provided minimum. Note the intend here is to only set
> >>>> the boolean to true if the VBT provided minimum is _not_ 0, 0
> >>>> just means the vendor did not bother to provide a minimum.
> >>>>
> >>>> Currently e.g. GNOME never goes lower then something like 5%
> >>>> of brightness_max to avoid accidentally turning the screen off.
> >>>>
> >>>> Turning the screen off is quite bad to do on e.g. tablets where
> >>>> the GUI is the only way to undo the brightness change and now
> >>>> the user can no longer see the GUI.
> >>>>
> >>>> The idea behind this boolean is to give e.g. GNOME a way to
> >>>> know that it is safe to go down to 0% and for it to use
> >>>> the entire range.
> >>>
> >>> Why not just make it policy that 0 is defined as minimum brightness,
> >>> not off, and have all drivers conform to that?
> >>
> >> Because the backlight subsystem isn't as consistent on this, and it's been
> >> an epic source of confusion since forever.
> >>
> >> What's worse, there's both userspace out there which assumes brightness =
> >> 0 is a really fast dpms off _and_ userspace that assumes that brightness =
> >> 0 is the lowest setting. Of course on different sets of machines.
> >>
> >> So yeah we're screwed. I have no idea how to get out of this.
> >
> > Yes, but this is a new API.  So can't we do better?  Sure the old
> > backlight interface is broken, but why carry around clunky workarounds
> > for new interfaces?
>
> Right we certainly need to define the behavior of the new API
> clearly, so that userspace does not misuse / misinterpret it.
>
> The intend is for brightness=0 to mean minimum brightness
> to still be able to see what is on the screen. But the problem
> is that in many cases the GPU driver directly controls a PWM
> output, no minimum PWM value is given in the video BIOS tables
> and actually setting the PWM to 0% dutycycle turns off the
> screen.

Sure.  So have the GPU driver map 0 to some valid minimum if that is
the case or might be the case.  If bugs come up, we can add quirks in
the GPU drivers.

>
> So we can only promise a best-effort to make brightness=0
> mean minimum brightness, combined with documenting that it
> may turn off the backlight and that userspace _must_ never
> depend on it turning off the backlight.
>
> Also note that setting a direct PWM output to duty-cycle 0%
> does not guarantee that the backlight goes off, this may be
> an input for a special backlight LED driver IC like the
> TI LP855x series which can have an internal lookup
> table causing it to actually output a minimum brightness
> when its PWM input is at 0% dutycycle.  So this is a case
> where we just don't get enough info from the fw/hw to be able
> to offer the guarantees which we would like to guarantee.

So set it to a level we can guarantee can call it 0.  If we have the
flag we are just punting on the problem in my opinion.  The kernel
driver would seem to have a better idea what is a valid minimum than
some arbitrary userspace application.  Plus then if we need a
workaround for what is the minimum valid brightness, we can fix it one
place rather than letting every application try and fix it.

Alex


>
> Regards,
>
> Hans
>
>
>
>
>

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-08 15:11             ` Alex Deucher
@ 2022-04-11 10:18               ` Hans de Goede
  2022-04-11 11:34                 ` Pekka Paalanen
  2022-04-11 14:11                 ` Alex Deucher
  0 siblings, 2 replies; 44+ messages in thread
From: Hans de Goede @ 2022-04-11 10:18 UTC (permalink / raw)
  To: Alex Deucher
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

Hi,

On 4/8/22 17:11, Alex Deucher wrote:
> On Fri, Apr 8, 2022 at 10:56 AM Hans de Goede <hdegoede@redhat.com> wrote:
>>
>> Hi,
>>
>> On 4/8/22 16:08, Alex Deucher wrote:
>>> On Fri, Apr 8, 2022 at 4:07 AM Daniel Vetter <daniel@ffwll.ch> wrote:
>>>>
>>>> On Thu, Apr 07, 2022 at 05:05:52PM -0400, Alex Deucher wrote:
>>>>> On Thu, Apr 7, 2022 at 1:43 PM Hans de Goede <hdegoede@redhat.com> wrote:
>>>>>>
>>>>>> Hi Simon,
>>>>>>
>>>>>> On 4/7/22 18:51, Simon Ser wrote:
>>>>>>> Very nice plan! Big +1 for the overall approach.
>>>>>>
>>>>>> Thanks.
>>>>>>
>>>>>>> On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
>>>>>>>
>>>>>>>> The drm_connector brightness properties
>>>>>>>> =======================================
>>>>>>>>
>>>>>>>> bl_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 bl_brightness_max.
>>>>>>>
>>>>>>> Do we need to split this up into two props for sw/hw state? The privacy screen
>>>>>>> stuff needed this, but you're pretty familiar with that. :)
>>>>>>
>>>>>> Luckily that won't be necessary, since the privacy-screen is a security
>>>>>> feature the firmware/embedded-controller may refuse our requests
>>>>>> (may temporarily lock-out changes) and/or may make changes without
>>>>>> us requesting them itself. Neither is really the case with the
>>>>>> brightness setting of displays.
>>>>>>
>>>>>>>> bl_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 (yet).
>>>>>>>
>>>>>>> I don't think we actually need that one. Integer KMS props all have a
>>>>>>> range which can be fetched via drmModeGetProperty. The max can be
>>>>>>> exposed via this range. Example with the existing alpha prop:
>>>>>>>
>>>>>>>     "alpha": range [0, UINT16_MAX] = 65535
>>>>>>
>>>>>> Right, I already knew that, which is why I explicitly added a range
>>>>>> to the props already. The problem is that the range must be set
>>>>>> before registering the connector and when the backlight driver
>>>>>> only shows up (much) later during boot then we don't know the
>>>>>> range when registering the connector. I guess we could "patch-up"
>>>>>> the range later. But AFAIK that would be a bit of abuse of the
>>>>>> property API as the range is intended to never change, not
>>>>>> even after hotplug uevents. At least atm there is no infra
>>>>>> in the kernel to change the range later.
>>>>>>
>>>>>> Which is why I added an explicit bl_brightness_max property
>>>>>> of which the value gives the actual effective maximum of the
>>>>>> brightness.
>>>>
>>>> Uh ... I'm not a huge fan tbh. The thing is, if we allow hotplugging
>>>> brightness control later on then we just perpetuate the nonsense we have
>>>> right now, forever.
>>>>
>>>> Imo we should support two kinds of drivers:
>>>>
>>>> - drivers which are non-crap, and make sure their backlight driver is
>>>>   loaded before they register the drm_device (or at least the
>>>>   drm_connector). For those we want the drm_connector->backlight pointer
>>>>   to bit static over the lifetime of the connector, and then we can also
>>>>   set up the brightness range correctly.
>>>>
>>>> - funny drivers which implement the glorious fallback dance which
>>>>   libbacklight implements currently in userspace. Imo for these drivers we
>>>>   should have a libbacklight_heuristics_backlight, which normalizes or
>>>>   whatever, and is also ways there. And then internally handles the
>>>>   fallback mess to the "right" backlight driver.
>>>>
>>>> We might have some gaps on acpi systems to make sure the drm driver can
>>>> wait for the backlight driver to show up, but that's about it.
>>>>
>>>> Hotplugging random pieces later on is really not how drivers work nowadays
>>>> with deferred probe and component framework and all that.
>>>>
>>>>>> I did consider using the range for this and updating it
>>>>>> on the fly I think nothing is really preventing us from
>>>>>> doing so, but it very much feels like abusing the generic
>>>>>> properties API.
>>>>>>
>>>>>>>> bl_brightness_0_is_min_brightness: ro, boolean
>>>>>>>> When this is set to true then it is safe to set brightness to 0
>>>>>>>> without worrying that this completely turns the backlight off causing
>>>>>>>> the screen to become unreadable. When this is false setting brightness
>>>>>>>> to 0 may turn the backlight off, but this is not guaranteed.
>>>>>>>> This will e.g. be true when directly driving a PWM and the video-BIOS
>>>>>>>> has provided a minimum (non 0) duty-cycle below which the driver will
>>>>>>>> never go.
>>>>>>>
>>>>>>> Hm. It's quite unfortunate that it's impossible to have strong guarantees
>>>>>>> here.
>>>>>>>
>>>>>>> Is there any way we can avoid this prop?
>>>>>>
>>>>>> Not really, the problem is that we really don't know if 0 is off
>>>>>> or min-brightness. In the given example where we actually never go
>>>>>> down to a duty-cycle of 0% because the video BIOS tables tell us
>>>>>> not to, we can be certain that setting the brightness prop to 0
>>>>>> will not turn of the backlight, since we then set the duty-cycle
>>>>>> to the VBT provided minimum. Note the intend here is to only set
>>>>>> the boolean to true if the VBT provided minimum is _not_ 0, 0
>>>>>> just means the vendor did not bother to provide a minimum.
>>>>>>
>>>>>> Currently e.g. GNOME never goes lower then something like 5%
>>>>>> of brightness_max to avoid accidentally turning the screen off.
>>>>>>
>>>>>> Turning the screen off is quite bad to do on e.g. tablets where
>>>>>> the GUI is the only way to undo the brightness change and now
>>>>>> the user can no longer see the GUI.
>>>>>>
>>>>>> The idea behind this boolean is to give e.g. GNOME a way to
>>>>>> know that it is safe to go down to 0% and for it to use
>>>>>> the entire range.
>>>>>
>>>>> Why not just make it policy that 0 is defined as minimum brightness,
>>>>> not off, and have all drivers conform to that?
>>>>
>>>> Because the backlight subsystem isn't as consistent on this, and it's been
>>>> an epic source of confusion since forever.
>>>>
>>>> What's worse, there's both userspace out there which assumes brightness =
>>>> 0 is a really fast dpms off _and_ userspace that assumes that brightness =
>>>> 0 is the lowest setting. Of course on different sets of machines.
>>>>
>>>> So yeah we're screwed. I have no idea how to get out of this.
>>>
>>> Yes, but this is a new API.  So can't we do better?  Sure the old
>>> backlight interface is broken, but why carry around clunky workarounds
>>> for new interfaces?
>>
>> Right we certainly need to define the behavior of the new API
>> clearly, so that userspace does not misuse / misinterpret it.
>>
>> The intend is for brightness=0 to mean minimum brightness
>> to still be able to see what is on the screen. But the problem
>> is that in many cases the GPU driver directly controls a PWM
>> output, no minimum PWM value is given in the video BIOS tables
>> and actually setting the PWM to 0% dutycycle turns off the
>> screen.
> 
> Sure.  So have the GPU driver map 0 to some valid minimum if that is
> the case or might be the case.  If bugs come up, we can add quirks in
> the GPU drivers.

The problem is that when 0% duty-cycle is not off, but minimum
brightness because there is some smart backlight-controller involved
downstream of the pwm, then of we limit it to say min 5% then we
have just limited the range of the brightness. GNOME already does
this in userspace now and it is already receiving bug-reports
from users that GNOME does not allow the brightness to go as low
as they like to have it in a dark(ish) room.

And in some cases 5% is likely not enough for the backlight to
actually turn on. So it will be wrong in one direction on some
devices and wrong in the other direction in other devices.

Which means that to satisfy everyone here we will need a ton
of quirks, much too many to maintain in the kernel IMHO.


>> So we can only promise a best-effort to make brightness=0
>> mean minimum brightness, combined with documenting that it
>> may turn off the backlight and that userspace _must_ never
>> depend on it turning off the backlight.
>>
>> Also note that setting a direct PWM output to duty-cycle 0%
>> does not guarantee that the backlight goes off, this may be
>> an input for a special backlight LED driver IC like the
>> TI LP855x series which can have an internal lookup
>> table causing it to actually output a minimum brightness
>> when its PWM input is at 0% dutycycle.  So this is a case
>> where we just don't get enough info from the fw/hw to be able
>> to offer the guarantees which we would like to guarantee.
> 
> So set it to a level we can guarantee can call it 0.  If we have the
> flag we are just punting on the problem in my opinion.

Right this an impossible problem to solve so the intent is indeed
to punt this to userspace, which IMHO is the best thing we can do
here.  The idea behind the "bl_brightness_0_is_min_brightness:
ro, boolean" property is to provide a hint to userspace to help
userspace deal with this (and if userspace ends up using e.g.
systemd's hwdb for this to avoid unnecessary entries in hwdb).

>  The kernel
> driver would seem to have a better idea what is a valid minimum than
> some arbitrary userspace application.

If the kernel driver knows the valid minimum then it can make 0
actually be that valid minimum as you suggest and it can set the
hint flag to let userspace know this. OTOH there are many cases
where the kernel's guess is just as bad as userspace's guess and
there are too many laptops where this is the case to quirk
ourselves out of this situation.

> Plus then if we need a
> workaround for what is the minimum valid brightness, we can fix it one
> place rather than letting every application try and fix it.

I wish we could solve this in the kernel, but at least on
laptops with Intel integrated gfx many vendors don't bother
to put a non 0 value in the minimum duty-cycle field of the
VBT, so there really is no good way to solve this.

If the userspace folks ever want to do a database for this,
I would expect them to do something with hwdb + udev which
can then be shared between the different desktop-environments.

Regards,

Hans


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-07 18:58 ` Carsten Haitzler
@ 2022-04-11 10:27   ` Hans de Goede
  2022-04-11 11:14     ` Carsten Haitzler
  0 siblings, 1 reply; 44+ messages in thread
From: Hans de Goede @ 2022-04-11 10:27 UTC (permalink / raw)
  To: Carsten Haitzler
  Cc: Yusuf Khan, Sebastian Wick, Martin Roukala, dri-devel, wayland

Hi,

On 4/7/22 20:58, Carsten Haitzler wrote:
> On Thu, 7 Apr 2022 17:38:59 +0200 Hans de Goede <hdegoede@redhat.com> said:
> 
> Below you covered our usual /sys/class/backlight device friends... what about
> DDC monitor controls? These function similarly but just remotely control a
> screen via I2C and also suffer from the same problems of "need root" and "have
> to do some fun in mapping them to a given screen".

Right, supporting this definitely is part of the plan, this is why my original
email had the following footnote:

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/

:)
 
> Otherwise I welcome this de-uglification of the backlight device and putting it
> together with the drm device that controls that monitor.

Thx.

> Just to make life more fun ... DDC does much more than backlight controls. It
> can control essentially anything that is in the OSD for your monitor (contrast,
> brightness, backlight, sharpness, color temperatures, input to display (DP vs
> HDMI vs DVI etc.), an for extra fun points can even tel you the current
> rotation state of your monitor. All of these do make sense to live as drm
> connector properties too. Perhaps not a first iteration but something to
> consider in this design.

One thing which I do want to take into account is to make sure that userspace
can still do DDC/CI for all the other features. I know there is demand for
adding brightness control over DDC/CI. I'm not aware of any concrete use-cases
for the other DDC/CI settings. Also DDC/CI can include some pretty crazy
stuff like setting up picture in picture using 2 different inputs of the
monitor, which is very vendor specific. So all in all I think that we should
just punt most of the DDC/CI stuff to userspace.

With that said I agree that it would be good to think about possibly other
some of the other settings in case some use-case does show up for those.

The biggest problem with doing this is coming up with some prefix to
namespace things. I've gone with bl_brightness to avoid a conflict
with the existing TV specific properties which have plain "brightness"
put if we want to e.g. also add DDC/CI contrast as a property later
then it might be good to come up with another more generic prefix
which can be shared between laptop-panel-brightness, DDC/CI-brightness
and DDC/CI-contrast ... ?

So any suggestions for a better prefix?

Regards,

Hans





> 
>> 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.
>>
>> 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.
>>
>>
>> What scale to use for the drm_connector bl_brightness property?
>> ===============================================================
>>
>> The tricky part of this plan is phase 2 and then esp. defining what the
>> new brightness properties will look like and how they will work.
>>
>> The biggest challenge here is to decide on a fixed scale for the main
>> brightness property, say 0-65535, using scaling where the actual hw scale
>> is different, or if this should simply be a 1:1 mirror of the current
>> backlight interface, with the actual hw scale / brightness_max value
>> exposed as a drm_connector property.
>>
>> 1:1 advantages / 0-65535 disadvantages
>> - Userspace will likely move over to the connector-props quite slowly and
>>   we can expect various userspace bits, esp. also custom user scripts, to
>>   keep using the old uAPI for a long time. Using the 2 APIs are intermixed
>>   is fine when using a 1:1 brightness scale mapping. But if we end up doing
>>   a scaling round-trip all the time then eventually the brightness is going
>>   do drift. This can even happen if the user never changes the brightness
>>   when userspace saves it over suspend/resume or reboots.
>> - Almost all laptops have brightness up/down hotkeys. E.g GNOME decides
>>   on a step size for the hotkeys by doing min(brightness_max/20, 1).
>>   Some of the vendor specific backlight fw APIs (e.g. dell-laptop) have
>>   only 8 steps. When giving userspace the actual max_brightness value, then
>>   this will all work just fine. When hardcode brightness_max to 65535 OTOH
>>   then in this case GNOME will still give the user 20 steps where only 1
>>   in every 2-3 steps actually changes the brightness which IMHO is
>>   an unacceptably bad user experience.
>>
>> 0-65535 advantages / 1:1 disadvantages
>> - Without a fixed scale for the brightness property the brightness_max
>>   value may change after an userspace application's initial enumeration
>>   of the drm_connector. This can happen when neither the native GPU nor
>>   the acpi_video backlight devices are present/usable in this case
>>   acpi_video_get_backlight_type() will _assume_ a vendor specific fw API
>>   will be used for backlight control and the driver proving the "vendor"
>>   backlight device will show up much later and may even never show-up,
>>   so waiting for it is not an option. With a fixed 0-65535 scale userspace
>>   can just always assume this and the drm_connector backlight props helper
>>   code can even cache writes and send it to the actual backlight device
>>   when it shows up. With a 1:1 mapping userspace needs to listen for
>>   a uevent and then update the brightness range on such an event.
>>
>> I believe that the 1:1 mapping advantages out way the disadvantages
>> here. Also note that current userspace already blindly assumes that
>> all relevant drivers are loaded before the graphical-environment
>> starts and all the desktop environments as such already only do
>> a single scan of /sys/class/backlight when they start. So when
>> userspace forgets to add code to listen for the uevent when switching
>> to the new API nothing changes; and with the uevent userspace actually
>> gets a good mechanism to detect backlight drivers loading after
>> the graphical-environment has already started.
>>
>> So based on this here is my proposal for a set of new brightness
>> properties on the drm_connector object. Note these are all prefixed with
>> bl which stands for backlight, which is technically not correct for OLED.
>> But we need a prefix to avoid a name collision with the "brightness"
>> attribute which is part of the existing TV specific properties and IMHO
>> it is good to have a common prefix to make it clear that these all
>> belong together.
>>
>>
>> The drm_connector brightness properties
>> =======================================
>>
>> bl_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 bl_brightness_max.
>>
>> bl_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 (yet).
>>
>> bl_brightness_0_is_min_brightness: ro, boolean
>> When this is set to true then it is safe to set brightness to 0
>> without worrying that this completely turns the backlight off causing
>> the screen to become unreadable. When this is false setting brightness
>> to 0 may turn the backlight off, but this is _not_ guaranteed.
>> This will e.g. be true when directly driving a PWM and the video-BIOS
>> has provided a minimum (non 0) duty-cycle below which the driver will
>> never go.
>>
>> bl_brightness_control_method: ro, enum, possible values:
>> none:     The GPU driver expects brightness control to be provided by another
>>           driver and that driver has not loaded yet.
>> unknown:  The underlying control mechanism is unknown.
>> pwm:      The brightness property directly controls the duty-cycle of a PWM
>>           output.
>> firmware: The brightness is controlled through firmware calls.
>> DDC/CI:   The brightness is controlled through the DDC/CI protocol.
>> gmux:     The brightness is controlled by the GMUX.
>> Note this enum may be extended in the future, so other values may
>> be read, these should be treated as "unknown".
>>
>> When brightness control becomes available after being reported
>> as not available before (bl_brightness_control_method=="none")
>> a uevent with CONNECTOR=<connector-id> and
>> PROPERTY=<bl_brightness_control_method-id> will be generated
>> at this point all the properties must be re-read.
>>
>> When/once brightness control is available then all the read-only
>> properties are fixed and will never change.
>>
>> Besides the "none" value for no driver having loaded yet,
>> the different bl_brightness_control_method values are intended for
>> (userspace) heuristics for such things as the brightness setting
>> linearly controlling electrical power or setting perceived brightness.
>>
>> 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
>>
> 
> 


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-08  8:22     ` Simon Ser
  2022-04-08 15:00       ` Hans de Goede
@ 2022-04-11 10:35       ` Hans de Goede
  1 sibling, 0 replies; 44+ messages in thread
From: Hans de Goede @ 2022-04-11 10:35 UTC (permalink / raw)
  To: Simon Ser
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

Hi Simon,

On 4/8/22 10:22, Simon Ser wrote:
> Hi Hans,
> 
> Thanks for your details replies!
> 
> On Thursday, April 7th, 2022 at 19:43, Hans de Goede <hdegoede@redhat.com> wrote:
> 
>>> On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
>>>
>>>> The drm_connector brightness properties
>>>> =======================================
>>>>
>>>> bl_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 bl_brightness_max.
>>>
>>> Do we need to split this up into two props for sw/hw state? The privacy screen
>>> stuff needed this, but you're pretty familiar with that. :)
>>
>> Luckily that won't be necessary, since the privacy-screen is a security
>> feature the firmware/embedded-controller may refuse our requests
>> (may temporarily lock-out changes) and/or may make changes without
>> us requesting them itself. Neither is really the case with the
>> brightness setting of displays.
> 
> Cool, makes sense to me!
> 
>>>> bl_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 (yet).
>>>
>>> I don't think we actually need that one. Integer KMS props all have a
>>> range which can be fetched via drmModeGetProperty. The max can be
>>> exposed via this range. Example with the existing alpha prop:
>>>
>>>     "alpha": range [0, UINT16_MAX] = 65535
>>
>> Right, I already knew that, which is why I explicitly added a range
>> to the props already. The problem is that the range must be set
>> before registering the connector and when the backlight driver
>> only shows up (much) later during boot then we don't know the
>> range when registering the connector. I guess we could "patch-up"
>> the range later. But AFAIK that would be a bit of abuse of the
>> property API as the range is intended to never change, not
>> even after hotplug uevents. At least atm there is no infra
>> in the kernel to change the range later.
>>
>> Which is why I added an explicit bl_brightness_max property
>> of which the value gives the actual effective maximum of the
>> brightness.
>>
>> I did consider using the range for this and updating it
>> on the fly I think nothing is really preventing us from
>> doing so, but it very much feels like abusing the generic
>> properties API.
> 
> Since this is new uAPI there's no concern about backwards compat here. So it's
> pretty much a matter of how we want the uAPI to look like. I was suggesting
> using a range because it's self-describing, but maybe it's an abuse.
> 
> Daniel Vetter, what do you think? If a property's range is going to be updated
> on the fly, should we go for it, or should we use a separate prop to describe
> the max value?

Daniel, as explained in my replies to you, I do believe that dynamically
updating the range is unavoidable. Especially once we also add support
for setting a monitor's brightness over DDC/CI.

Since external monitors (with/without DDC/CI support) can come and go and
since properties cannot be added/removed after connector registration, we
need a way to let userspace know if brightness control is actually available
or not and what the range is. We can use a max value of 0 for not available
and other values for the actual range, which I believe is a sane API.

But the question from Simon then still remains, do we update the range
of the property on the fly, followed by a connector hotplug uevent; or
do we use a separate brightness_max property for this?

Note that as Rasterman indicated that with DDC/CI support we could also
offer other properties (for which I see no reason atm) and if we do
say also add a contrast property over DDC/CI then if we go the
separate brightness_max route that would mean adding 2 props for
each setting which we want to support.

Regards,

Hans



^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-11 10:27   ` Hans de Goede
@ 2022-04-11 11:14     ` Carsten Haitzler
  0 siblings, 0 replies; 44+ messages in thread
From: Carsten Haitzler @ 2022-04-11 11:14 UTC (permalink / raw)
  To: Hans de Goede
  Cc: wayland, Sebastian Wick, Martin Roukala, dri-devel, Yusuf Khan

On Mon, 11 Apr 2022 12:27:37 +0200 Hans de Goede <hdegoede@redhat.com> said:

> Hi,
> 
> On 4/7/22 20:58, Carsten Haitzler wrote:
> > On Thu, 7 Apr 2022 17:38:59 +0200 Hans de Goede <hdegoede@redhat.com> said:
> > 
> > Below you covered our usual /sys/class/backlight device friends... what
> > about DDC monitor controls? These function similarly but just remotely
> > control a screen via I2C and also suffer from the same problems of "need
> > root" and "have to do some fun in mapping them to a given screen".
> 
> Right, supporting this definitely is part of the plan, this is why my original
> email had the following footnote:

Yay!

> 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/

Oh gee - I missed that. my bad!

> :)
>  
> > Otherwise I welcome this de-uglification of the backlight device and
> > putting it together with the drm device that controls that monitor.
> 
> Thx.

Having to deal with the backlight device madness is a big pain (have already
done it - DDC included) and properly exposing these things attached to the
proper KMS device is absolutely the right thing. Admittedly this punts the job
of matching a backlight device to the right video output in KMS to the kernel
so at least it gets solved in one place rather than it being re-invented again
and again per wm/desktop/compositor.

> > Just to make life more fun ... DDC does much more than backlight controls.
> > It can control essentially anything that is in the OSD for your monitor
> > (contrast, brightness, backlight, sharpness, color temperatures, input to
> > display (DP vs HDMI vs DVI etc.), an for extra fun points can even tel you
> > the current rotation state of your monitor. All of these do make sense to
> > live as drm connector properties too. Perhaps not a first iteration but
> > something to consider in this design.
> 
> One thing which I do want to take into account is to make sure that userspace
> can still do DDC/CI for all the other features. I know there is demand for
> adding brightness control over DDC/CI. I'm not aware of any concrete use-cases
> for the other DDC/CI settings. Also DDC/CI can include some pretty crazy
> stuff like setting up picture in picture using 2 different inputs of the
> monitor, which is very vendor specific. So all in all I think that we should
> just punt most of the DDC/CI stuff to userspace.

Having spent some time with DDC you're right - it can have some interesting
properties, but a wide number seem to be highly common between monitors and
make total sense to regularly use if available. Backlight/brightness is just
the immediate focus here.

> With that said I agree that it would be good to think about possibly other
> some of the other settings in case some use-case does show up for those.
> 
> The biggest problem with doing this is coming up with some prefix to
> namespace things. I've gone with bl_brightness to avoid a conflict
> with the existing TV specific properties which have plain "brightness"
> put if we want to e.g. also add DDC/CI contrast as a property later
> then it might be good to come up with another more generic prefix
> which can be shared between laptop-panel-brightness, DDC/CI-brightness
> and DDC/CI-contrast ... ?
> 
> So any suggestions for a better prefix?

Well here is my take. Have DDC properties separate from a build-in backlight
device. Userspace code will have to essentially do something like:

if (built_in_backlight_exists(output)) // built in backlight device
  set_backlight_brightness(output, val);
else if (ddc_prop_exists(output, 0x10)) // 0x10 is ddc brightness/backlight
  set_ddc_int_val(output, 0x10, val);
else // fallback for ye olde setuid tooling
  { ...
  }

DDC properties are quite simple in essence so just exposing the set so you can
read/write them (and check if they exist at all) would do the right thing - tie
DDC to the output visa KMS, (you still could use I2C directly if you like and
go behind KMS's back) but it'd then punt the policy decision of which
properties are common/sane to userspace without adding a possibly "endless" set
of "let's now adopt/abstract this DDC property" discussions. Wayland
compositors can adopts the properties they see as most useful for their uses.
Xorg could expose them via XRR output properties. So my take at least is to give
DDC it's own property namespace/set that allows an arbitrary set of numbered
properties and leave it pretty raw.

> Regards,
> 
> Hans
> 
> 
> 
> 
> 
> > 
> >> 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.
> >>
> >> 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.
> >>
> >>
> >> What scale to use for the drm_connector bl_brightness property?
> >> ===============================================================
> >>
> >> The tricky part of this plan is phase 2 and then esp. defining what the
> >> new brightness properties will look like and how they will work.
> >>
> >> The biggest challenge here is to decide on a fixed scale for the main
> >> brightness property, say 0-65535, using scaling where the actual hw scale
> >> is different, or if this should simply be a 1:1 mirror of the current
> >> backlight interface, with the actual hw scale / brightness_max value
> >> exposed as a drm_connector property.
> >>
> >> 1:1 advantages / 0-65535 disadvantages
> >> - Userspace will likely move over to the connector-props quite slowly and
> >>   we can expect various userspace bits, esp. also custom user scripts, to
> >>   keep using the old uAPI for a long time. Using the 2 APIs are intermixed
> >>   is fine when using a 1:1 brightness scale mapping. But if we end up doing
> >>   a scaling round-trip all the time then eventually the brightness is going
> >>   do drift. This can even happen if the user never changes the brightness
> >>   when userspace saves it over suspend/resume or reboots.
> >> - Almost all laptops have brightness up/down hotkeys. E.g GNOME decides
> >>   on a step size for the hotkeys by doing min(brightness_max/20, 1).
> >>   Some of the vendor specific backlight fw APIs (e.g. dell-laptop) have
> >>   only 8 steps. When giving userspace the actual max_brightness value, then
> >>   this will all work just fine. When hardcode brightness_max to 65535 OTOH
> >>   then in this case GNOME will still give the user 20 steps where only 1
> >>   in every 2-3 steps actually changes the brightness which IMHO is
> >>   an unacceptably bad user experience.
> >>
> >> 0-65535 advantages / 1:1 disadvantages
> >> - Without a fixed scale for the brightness property the brightness_max
> >>   value may change after an userspace application's initial enumeration
> >>   of the drm_connector. This can happen when neither the native GPU nor
> >>   the acpi_video backlight devices are present/usable in this case
> >>   acpi_video_get_backlight_type() will _assume_ a vendor specific fw API
> >>   will be used for backlight control and the driver proving the "vendor"
> >>   backlight device will show up much later and may even never show-up,
> >>   so waiting for it is not an option. With a fixed 0-65535 scale userspace
> >>   can just always assume this and the drm_connector backlight props helper
> >>   code can even cache writes and send it to the actual backlight device
> >>   when it shows up. With a 1:1 mapping userspace needs to listen for
> >>   a uevent and then update the brightness range on such an event.
> >>
> >> I believe that the 1:1 mapping advantages out way the disadvantages
> >> here. Also note that current userspace already blindly assumes that
> >> all relevant drivers are loaded before the graphical-environment
> >> starts and all the desktop environments as such already only do
> >> a single scan of /sys/class/backlight when they start. So when
> >> userspace forgets to add code to listen for the uevent when switching
> >> to the new API nothing changes; and with the uevent userspace actually
> >> gets a good mechanism to detect backlight drivers loading after
> >> the graphical-environment has already started.
> >>
> >> So based on this here is my proposal for a set of new brightness
> >> properties on the drm_connector object. Note these are all prefixed with
> >> bl which stands for backlight, which is technically not correct for OLED.
> >> But we need a prefix to avoid a name collision with the "brightness"
> >> attribute which is part of the existing TV specific properties and IMHO
> >> it is good to have a common prefix to make it clear that these all
> >> belong together.
> >>
> >>
> >> The drm_connector brightness properties
> >> =======================================
> >>
> >> bl_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 bl_brightness_max.
> >>
> >> bl_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 (yet).
> >>
> >> bl_brightness_0_is_min_brightness: ro, boolean
> >> When this is set to true then it is safe to set brightness to 0
> >> without worrying that this completely turns the backlight off causing
> >> the screen to become unreadable. When this is false setting brightness
> >> to 0 may turn the backlight off, but this is _not_ guaranteed.
> >> This will e.g. be true when directly driving a PWM and the video-BIOS
> >> has provided a minimum (non 0) duty-cycle below which the driver will
> >> never go.
> >>
> >> bl_brightness_control_method: ro, enum, possible values:
> >> none:     The GPU driver expects brightness control to be provided by
> >> another driver and that driver has not loaded yet.
> >> unknown:  The underlying control mechanism is unknown.
> >> pwm:      The brightness property directly controls the duty-cycle of a PWM
> >>           output.
> >> firmware: The brightness is controlled through firmware calls.
> >> DDC/CI:   The brightness is controlled through the DDC/CI protocol.
> >> gmux:     The brightness is controlled by the GMUX.
> >> Note this enum may be extended in the future, so other values may
> >> be read, these should be treated as "unknown".
> >>
> >> When brightness control becomes available after being reported
> >> as not available before (bl_brightness_control_method=="none")
> >> a uevent with CONNECTOR=<connector-id> and
> >> PROPERTY=<bl_brightness_control_method-id> will be generated
> >> at this point all the properties must be re-read.
> >>
> >> When/once brightness control is available then all the read-only
> >> properties are fixed and will never change.
> >>
> >> Besides the "none" value for no driver having loaded yet,
> >> the different bl_brightness_control_method values are intended for
> >> (userspace) heuristics for such things as the brightness setting
> >> linearly controlling electrical power or setting perceived brightness.
> >>
> >> 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
> >>
> > 
> > 
> 


-- 
------------- Codito, ergo sum - "I code, therefore I am" --------------
Carsten Haitzler - raster@rasterman.com


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-11 10:18               ` Hans de Goede
@ 2022-04-11 11:34                 ` Pekka Paalanen
  2022-04-11 11:50                   ` Hans de Goede
  2022-04-11 14:11                 ` Alex Deucher
  1 sibling, 1 reply; 44+ messages in thread
From: Pekka Paalanen @ 2022-04-11 11:34 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Sebastian Wick, Martin Roukala, dri-devel, wayland,
	Christoph Grenz, Yusuf Khan

[-- Attachment #1: Type: text/plain, Size: 3679 bytes --]

On Mon, 11 Apr 2022 12:18:30 +0200
Hans de Goede <hdegoede@redhat.com> wrote:

> Hi,
> 
> On 4/8/22 17:11, Alex Deucher wrote:
> > On Fri, Apr 8, 2022 at 10:56 AM Hans de Goede <hdegoede@redhat.com> wrote:  
> >>

...

> > So set it to a level we can guarantee can call it 0.  If we have the
> > flag we are just punting on the problem in my opinion.  
> 
> Right this an impossible problem to solve so the intent is indeed
> to punt this to userspace, which IMHO is the best thing we can do
> here.  The idea behind the "bl_brightness_0_is_min_brightness:
> ro, boolean" property is to provide a hint to userspace to help
> userspace deal with this (and if userspace ends up using e.g.
> systemd's hwdb for this to avoid unnecessary entries in hwdb).
> 
> >  The kernel
> > driver would seem to have a better idea what is a valid minimum than
> > some arbitrary userspace application.  
> 
> If the kernel driver knows the valid minimum then it can make 0
> actually be that valid minimum as you suggest and it can set the
> hint flag to let userspace know this. OTOH there are many cases
> where the kernel's guess is just as bad as userspace's guess and
> there are too many laptops where this is the case to quirk
> ourselves out of this situation.
> 
> > Plus then if we need a
> > workaround for what is the minimum valid brightness, we can fix it one
> > place rather than letting every application try and fix it.  
> 
> I wish we could solve this in the kernel, but at least on
> laptops with Intel integrated gfx many vendors don't bother
> to put a non 0 value in the minimum duty-cycle field of the
> VBT, so there really is no good way to solve this.
> 
> If the userspace folks ever want to do a database for this,
> I would expect them to do something with hwdb + udev which
> can then be shared between the different desktop-environments.

Hi Hans,

assuming that it is impossible to reach a reasonable user experience by
having a quirk database in the kernel in order to offer a consistent
definition of bl_brightness=0, then should you not be recommending a
userspace hwdb solution with full steam, rather than adding a hint in
the kernel that might be just enough to have no-one ever bother
investing in a proper solution?

Re-reading your "bl_brightness_0_is_min_brightness" definition, it
seems to be specified as exposing a certain condition in the system.
When it is true, you imply that userspace can safely use value 0 as min
brightness, but that is assuming the hint is correct. How likely
is the hint incorrect? If the hint can be incorrect, does this hint
actually give anything to userspace, or would userspace still choose to
be safer than sorry and ignore the hint by assuming the worst?

Is this situation much different to the quirk database libinput needs
to work beautifully out of the box?

Should desktop environments offer a couple more "advanced
configuration" knobs for the lowest safe brightness value and the
value-to-perceived brightness mapping to calibrate the familiar
brightness slider? E.g. something like "click this button as soon as
you see it on the display" for finding the lowest usable brightness,
with defaults coming from a database.

If the situation is as grim as you say, I would propose to drop
"bl_brightness_0_is_min_brightness" (and
"bl_brightness_control_method"), and document the dangers of using too
low brightness values. Maybe also start looking for a project that
would be appropriate for hosting such a database, just to point people
to cooperate in a single place rather than each DE coming up with their
own.


Thanks,
pq

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-11 11:34                 ` Pekka Paalanen
@ 2022-04-11 11:50                   ` Hans de Goede
  2022-04-11 13:11                     ` Mikhail Gusarov
  0 siblings, 1 reply; 44+ messages in thread
From: Hans de Goede @ 2022-04-11 11:50 UTC (permalink / raw)
  To: Pekka Paalanen
  Cc: Sebastian Wick, Martin Roukala, dri-devel, wayland,
	Christoph Grenz, Yusuf Khan

Hi Pekka,

On 4/11/22 13:34, Pekka Paalanen wrote:
> On Mon, 11 Apr 2022 12:18:30 +0200
> Hans de Goede <hdegoede@redhat.com> wrote:
> 
>> Hi,
>>
>> On 4/8/22 17:11, Alex Deucher wrote:
>>> On Fri, Apr 8, 2022 at 10:56 AM Hans de Goede <hdegoede@redhat.com> wrote:  
>>>>
> 
> ...
> 
>>> So set it to a level we can guarantee can call it 0.  If we have the
>>> flag we are just punting on the problem in my opinion.  
>>
>> Right this an impossible problem to solve so the intent is indeed
>> to punt this to userspace, which IMHO is the best thing we can do
>> here.  The idea behind the "bl_brightness_0_is_min_brightness:
>> ro, boolean" property is to provide a hint to userspace to help
>> userspace deal with this (and if userspace ends up using e.g.
>> systemd's hwdb for this to avoid unnecessary entries in hwdb).
>>
>>>  The kernel
>>> driver would seem to have a better idea what is a valid minimum than
>>> some arbitrary userspace application.  
>>
>> If the kernel driver knows the valid minimum then it can make 0
>> actually be that valid minimum as you suggest and it can set the
>> hint flag to let userspace know this. OTOH there are many cases
>> where the kernel's guess is just as bad as userspace's guess and
>> there are too many laptops where this is the case to quirk
>> ourselves out of this situation.
>>
>>> Plus then if we need a
>>> workaround for what is the minimum valid brightness, we can fix it one
>>> place rather than letting every application try and fix it.  
>>
>> I wish we could solve this in the kernel, but at least on
>> laptops with Intel integrated gfx many vendors don't bother
>> to put a non 0 value in the minimum duty-cycle field of the
>> VBT, so there really is no good way to solve this.
>>
>> If the userspace folks ever want to do a database for this,
>> I would expect them to do something with hwdb + udev which
>> can then be shared between the different desktop-environments.
> 
> Hi Hans,
> 
> assuming that it is impossible to reach a reasonable user experience by
> having a quirk database in the kernel in order to offer a consistent
> definition of bl_brightness=0, then should you not be recommending a
> userspace hwdb solution with full steam, rather than adding a hint in
> the kernel that might be just enough to have no-one ever bother
> investing in a proper solution?

The problem is we already lack the manpower for a quirk database,
and even if we ever get the manpower then it would still be good
to avoid the work necessary to add models to the database where
the kernel already knows how things work, see below.

As for no-one ever bothering coming up with a full-steam hwdb
solution for the cases where the kernel has no idea what
bl_brightness=0 means, yes that is likely, but that already
is the status quo, the hint will at least allow using the
full brightness range on devices where the kernel knows
(with certainty) that this is correct.

> Re-reading your "bl_brightness_0_is_min_brightness" definition, it
> seems to be specified as exposing a certain condition in the system.
> When it is true, you imply that userspace can safely use value 0 as min
> brightness, but that is assuming the hint is correct. How likely
> is the hint incorrect?

It should never be incorrect, there are cases when the kernel knows
reliably that bl_brightness=0 means minimum brightness
(and NOT backlight off).

> If the hint can be incorrect, does this hint
> actually give anything to userspace, or would userspace still choose to
> be safer than sorry and ignore the hint by assuming the worst?

If the hint is incorrect then that would be a kernel bug and that
should be fixed in the kernel. The whole idea behind the hind is
that userspace can absolutely trust it to be correct when set to true
(false basically means that the kernel does not know of 0=off or not).

> Is this situation much different to the quirk database libinput needs
> to work beautifully out of the box?

libinput's quirk database is relatively pretty small and a lot
of effort is done to fix things in generic ways where possible,
to avoid growing it.

As a general rule quirks should only be used to handle exceptions
to general rules, the problem here is that bl_brightness=0 being
backlight off is not a true exception it happens quite often.

Which is also why I believe that a hwdb for this is not necessarily
a great idea, because maintaining it will be a lot of work.

> Should desktop environments offer a couple more "advanced
> configuration" knobs for the lowest safe brightness value and the
> value-to-perceived brightness mapping to calibrate the familiar
> brightness slider? E.g. something like "click this button as soon as
> you see it on the display" for finding the lowest usable brightness,
> with defaults coming from a database.

Maybe, but that would defeat all the attempts done to make Linux
on the desktop just work.

> If the situation is as grim as you say, I would propose to drop
> "bl_brightness_0_is_min_brightness" (and
> "bl_brightness_control_method"), and document the dangers of using too
> low brightness values. Maybe also start looking for a project that
> would be appropriate for hosting such a database, just to point people
> to cooperate in a single place rather than each DE coming up with their
> own.

I agree with dropping bl_brightness_control_method, but I do
believe that bl_brightness_0_is_min_brightness will be actually
useful to have, see above.

As for starting a database for this. I gave a talk about improving the
backlight situation under Linux in 2014, nothing has happened since
then. I think we need to be realistic here and accept that we don't
have the manpower to do something like a database here.

Regards,

Hans


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-11 11:50                   ` Hans de Goede
@ 2022-04-11 13:11                     ` Mikhail Gusarov
  0 siblings, 0 replies; 44+ messages in thread
From: Mikhail Gusarov @ 2022-04-11 13:11 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

On 11 Apr 2022, at 13:50, Hans de Goede wrote:

> The problem is we already lack the manpower for a quirk database,
> and even if we ever get the manpower then it would still be good
> to avoid the work necessary to add models to the database where
> the kernel already knows how things work, see below.

I wonder how Windows developers solve this problem, and do they at all?

Best,
Mikhail.

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-11 10:18               ` Hans de Goede
  2022-04-11 11:34                 ` Pekka Paalanen
@ 2022-04-11 14:11                 ` Alex Deucher
  2022-04-14 10:24                   ` Jani Nikula
  1 sibling, 1 reply; 44+ messages in thread
From: Alex Deucher @ 2022-04-11 14:11 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

On Mon, Apr 11, 2022 at 6:18 AM Hans de Goede <hdegoede@redhat.com> wrote:
>
> Hi,
>
> On 4/8/22 17:11, Alex Deucher wrote:
> > On Fri, Apr 8, 2022 at 10:56 AM Hans de Goede <hdegoede@redhat.com> wrote:
> >>
> >> Hi,
> >>
> >> On 4/8/22 16:08, Alex Deucher wrote:
> >>> On Fri, Apr 8, 2022 at 4:07 AM Daniel Vetter <daniel@ffwll.ch> wrote:
> >>>>
> >>>> On Thu, Apr 07, 2022 at 05:05:52PM -0400, Alex Deucher wrote:
> >>>>> On Thu, Apr 7, 2022 at 1:43 PM Hans de Goede <hdegoede@redhat.com> wrote:
> >>>>>>
> >>>>>> Hi Simon,
> >>>>>>
> >>>>>> On 4/7/22 18:51, Simon Ser wrote:
> >>>>>>> Very nice plan! Big +1 for the overall approach.
> >>>>>>
> >>>>>> Thanks.
> >>>>>>
> >>>>>>> On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
> >>>>>>>
> >>>>>>>> The drm_connector brightness properties
> >>>>>>>> =======================================
> >>>>>>>>
> >>>>>>>> bl_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 bl_brightness_max.
> >>>>>>>
> >>>>>>> Do we need to split this up into two props for sw/hw state? The privacy screen
> >>>>>>> stuff needed this, but you're pretty familiar with that. :)
> >>>>>>
> >>>>>> Luckily that won't be necessary, since the privacy-screen is a security
> >>>>>> feature the firmware/embedded-controller may refuse our requests
> >>>>>> (may temporarily lock-out changes) and/or may make changes without
> >>>>>> us requesting them itself. Neither is really the case with the
> >>>>>> brightness setting of displays.
> >>>>>>
> >>>>>>>> bl_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 (yet).
> >>>>>>>
> >>>>>>> I don't think we actually need that one. Integer KMS props all have a
> >>>>>>> range which can be fetched via drmModeGetProperty. The max can be
> >>>>>>> exposed via this range. Example with the existing alpha prop:
> >>>>>>>
> >>>>>>>     "alpha": range [0, UINT16_MAX] = 65535
> >>>>>>
> >>>>>> Right, I already knew that, which is why I explicitly added a range
> >>>>>> to the props already. The problem is that the range must be set
> >>>>>> before registering the connector and when the backlight driver
> >>>>>> only shows up (much) later during boot then we don't know the
> >>>>>> range when registering the connector. I guess we could "patch-up"
> >>>>>> the range later. But AFAIK that would be a bit of abuse of the
> >>>>>> property API as the range is intended to never change, not
> >>>>>> even after hotplug uevents. At least atm there is no infra
> >>>>>> in the kernel to change the range later.
> >>>>>>
> >>>>>> Which is why I added an explicit bl_brightness_max property
> >>>>>> of which the value gives the actual effective maximum of the
> >>>>>> brightness.
> >>>>
> >>>> Uh ... I'm not a huge fan tbh. The thing is, if we allow hotplugging
> >>>> brightness control later on then we just perpetuate the nonsense we have
> >>>> right now, forever.
> >>>>
> >>>> Imo we should support two kinds of drivers:
> >>>>
> >>>> - drivers which are non-crap, and make sure their backlight driver is
> >>>>   loaded before they register the drm_device (or at least the
> >>>>   drm_connector). For those we want the drm_connector->backlight pointer
> >>>>   to bit static over the lifetime of the connector, and then we can also
> >>>>   set up the brightness range correctly.
> >>>>
> >>>> - funny drivers which implement the glorious fallback dance which
> >>>>   libbacklight implements currently in userspace. Imo for these drivers we
> >>>>   should have a libbacklight_heuristics_backlight, which normalizes or
> >>>>   whatever, and is also ways there. And then internally handles the
> >>>>   fallback mess to the "right" backlight driver.
> >>>>
> >>>> We might have some gaps on acpi systems to make sure the drm driver can
> >>>> wait for the backlight driver to show up, but that's about it.
> >>>>
> >>>> Hotplugging random pieces later on is really not how drivers work nowadays
> >>>> with deferred probe and component framework and all that.
> >>>>
> >>>>>> I did consider using the range for this and updating it
> >>>>>> on the fly I think nothing is really preventing us from
> >>>>>> doing so, but it very much feels like abusing the generic
> >>>>>> properties API.
> >>>>>>
> >>>>>>>> bl_brightness_0_is_min_brightness: ro, boolean
> >>>>>>>> When this is set to true then it is safe to set brightness to 0
> >>>>>>>> without worrying that this completely turns the backlight off causing
> >>>>>>>> the screen to become unreadable. When this is false setting brightness
> >>>>>>>> to 0 may turn the backlight off, but this is not guaranteed.
> >>>>>>>> This will e.g. be true when directly driving a PWM and the video-BIOS
> >>>>>>>> has provided a minimum (non 0) duty-cycle below which the driver will
> >>>>>>>> never go.
> >>>>>>>
> >>>>>>> Hm. It's quite unfortunate that it's impossible to have strong guarantees
> >>>>>>> here.
> >>>>>>>
> >>>>>>> Is there any way we can avoid this prop?
> >>>>>>
> >>>>>> Not really, the problem is that we really don't know if 0 is off
> >>>>>> or min-brightness. In the given example where we actually never go
> >>>>>> down to a duty-cycle of 0% because the video BIOS tables tell us
> >>>>>> not to, we can be certain that setting the brightness prop to 0
> >>>>>> will not turn of the backlight, since we then set the duty-cycle
> >>>>>> to the VBT provided minimum. Note the intend here is to only set
> >>>>>> the boolean to true if the VBT provided minimum is _not_ 0, 0
> >>>>>> just means the vendor did not bother to provide a minimum.
> >>>>>>
> >>>>>> Currently e.g. GNOME never goes lower then something like 5%
> >>>>>> of brightness_max to avoid accidentally turning the screen off.
> >>>>>>
> >>>>>> Turning the screen off is quite bad to do on e.g. tablets where
> >>>>>> the GUI is the only way to undo the brightness change and now
> >>>>>> the user can no longer see the GUI.
> >>>>>>
> >>>>>> The idea behind this boolean is to give e.g. GNOME a way to
> >>>>>> know that it is safe to go down to 0% and for it to use
> >>>>>> the entire range.
> >>>>>
> >>>>> Why not just make it policy that 0 is defined as minimum brightness,
> >>>>> not off, and have all drivers conform to that?
> >>>>
> >>>> Because the backlight subsystem isn't as consistent on this, and it's been
> >>>> an epic source of confusion since forever.
> >>>>
> >>>> What's worse, there's both userspace out there which assumes brightness =
> >>>> 0 is a really fast dpms off _and_ userspace that assumes that brightness =
> >>>> 0 is the lowest setting. Of course on different sets of machines.
> >>>>
> >>>> So yeah we're screwed. I have no idea how to get out of this.
> >>>
> >>> Yes, but this is a new API.  So can't we do better?  Sure the old
> >>> backlight interface is broken, but why carry around clunky workarounds
> >>> for new interfaces?
> >>
> >> Right we certainly need to define the behavior of the new API
> >> clearly, so that userspace does not misuse / misinterpret it.
> >>
> >> The intend is for brightness=0 to mean minimum brightness
> >> to still be able to see what is on the screen. But the problem
> >> is that in many cases the GPU driver directly controls a PWM
> >> output, no minimum PWM value is given in the video BIOS tables
> >> and actually setting the PWM to 0% dutycycle turns off the
> >> screen.
> >
> > Sure.  So have the GPU driver map 0 to some valid minimum if that is
> > the case or might be the case.  If bugs come up, we can add quirks in
> > the GPU drivers.
>
> The problem is that when 0% duty-cycle is not off, but minimum
> brightness because there is some smart backlight-controller involved
> downstream of the pwm, then of we limit it to say min 5% then we
> have just limited the range of the brightness. GNOME already does
> this in userspace now and it is already receiving bug-reports
> from users that GNOME does not allow the brightness to go as low
> as they like to have it in a dark(ish) room.
>
> And in some cases 5% is likely not enough for the backlight to
> actually turn on. So it will be wrong in one direction on some
> devices and wrong in the other direction in other devices.
>
> Which means that to satisfy everyone here we will need a ton
> of quirks, much too many to maintain in the kernel IMHO.
>
>
> >> So we can only promise a best-effort to make brightness=0
> >> mean minimum brightness, combined with documenting that it
> >> may turn off the backlight and that userspace _must_ never
> >> depend on it turning off the backlight.
> >>
> >> Also note that setting a direct PWM output to duty-cycle 0%
> >> does not guarantee that the backlight goes off, this may be
> >> an input for a special backlight LED driver IC like the
> >> TI LP855x series which can have an internal lookup
> >> table causing it to actually output a minimum brightness
> >> when its PWM input is at 0% dutycycle.  So this is a case
> >> where we just don't get enough info from the fw/hw to be able
> >> to offer the guarantees which we would like to guarantee.
> >
> > So set it to a level we can guarantee can call it 0.  If we have the
> > flag we are just punting on the problem in my opinion.
>
> Right this an impossible problem to solve so the intent is indeed
> to punt this to userspace, which IMHO is the best thing we can do
> here.  The idea behind the "bl_brightness_0_is_min_brightness:
> ro, boolean" property is to provide a hint to userspace to help
> userspace deal with this (and if userspace ends up using e.g.
> systemd's hwdb for this to avoid unnecessary entries in hwdb).
>
> >  The kernel
> > driver would seem to have a better idea what is a valid minimum than
> > some arbitrary userspace application.
>
> If the kernel driver knows the valid minimum then it can make 0
> actually be that valid minimum as you suggest and it can set the
> hint flag to let userspace know this. OTOH there are many cases
> where the kernel's guess is just as bad as userspace's guess and
> there are too many laptops where this is the case to quirk
> ourselves out of this situation.
>
> > Plus then if we need a
> > workaround for what is the minimum valid brightness, we can fix it one
> > place rather than letting every application try and fix it.
>
> I wish we could solve this in the kernel, but at least on
> laptops with Intel integrated gfx many vendors don't bother
> to put a non 0 value in the minimum duty-cycle field of the
> VBT, so there really is no good way to solve this.

We have similar issues with AMD platforms.  Some platforms don't
populate the min value tables, but in the driver we set the minimum
safe value as the default min value when that happens.  It may not
always go as low as the platform may be capable of, but at least we
have consistent behavior and it's all controlled in one place.

>
> If the userspace folks ever want to do a database for this,
> I would expect them to do something with hwdb + udev which
> can then be shared between the different desktop-environments.

So why not do it in the kernel?  At least that way everyone will get
it the fixes as they happen.  A big user database may or may not
happen and behavior will be inconsistent across desktop environments
until that does.  I don't really see any value in having the flag.
There will be cases where the flag is wrong and will require kernel
fixes anyway (e.g., OEM switches panel due to supply chain issues and
forgets to update the vbios, etc.), so why not just define 0 as
minimum safe backlight value?  If it's too low and flickers or turns
the backlight off, we quirk it.  If a particular platform can go
lower, we can quirk it.  If we add the flag then we need to not only
add quirks for the minimum value, but we also have to deal with quirks
for when the flag is set wrong.  So now we are maintaining two quirks
instead of one.

Alex

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-08 10:26               ` Hans de Goede
@ 2022-04-13  8:32                 ` Daniel Vetter
  2022-04-13  8:38                   ` Simon Ser
  2022-04-13  9:44                   ` Hans de Goede
  0 siblings, 2 replies; 44+ messages in thread
From: Daniel Vetter @ 2022-04-13  8:32 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

On Fri, Apr 08, 2022 at 12:26:24PM +0200, Hans de Goede wrote:
> Hi,
> 
> On 4/8/22 12:16, Simon Ser wrote:
> > Would it be an option to only support the KMS prop for Good devices,
> > and continue using the suboptimal existing sysfs API for Bad devices?
> > 
> > (I'm just throwing ideas around to see what sticks, feel free to ignore.)
> 
> Currently suid-root or pkexec helpers are used to deal with the
> /sys/class/backlight requires root rights issue. I really want to
> be able to disable these helpers at build time in e.g. GNOME once
> the new properties are supported in GNOME.  So that distros with
> a new enough kernel can reduce their attack surface this way.

Yeah but otoh perpetuating a bad interface forever isn't a great idea
either. I think the pragmatic plan here is
- Implement this properly on good devices, i.e. anything new.
- Do some runtime disabling in the pkexec helpers if they detect a modern
  system (we should be able to put a proper symlink into the drm sysfs
  connector directories, to make this easy to detect). It's not as great
  as doing this at compile time, but it's a step.
- Figure out a solution for the old crap. We can't really change anything
  with the load ordering for existing systems, so if the hacked-up compat
  libbacklight-backlight isn't an option then I guess we need some quirk
  list/extracted code which makes i915/nouveau/radeon driver load fail
  until the right backlight shows up. And that needs to be behind a
  Kconfig to avoid breaking existing systems.

Inflicting hotplug complications on all userspace (including uevent
handling for this hotpluggable backlight and everything) just because
fixing the old crap systems is work is imo really not a good idea. Much
better if we get to the correct future step-by-step.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-13  8:32                 ` Daniel Vetter
@ 2022-04-13  8:38                   ` Simon Ser
  2022-04-13  9:44                   ` Hans de Goede
  1 sibling, 0 replies; 44+ messages in thread
From: Simon Ser @ 2022-04-13  8:38 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	Hans de Goede, dri-devel, Yusuf Khan

On Wednesday, April 13th, 2022 at 10:32, Daniel Vetter <daniel@ffwll.ch> wrote:

> Inflicting hotplug complications on all userspace (including uevent
> handling for this hotpluggable backlight and everything) just because
> fixing the old crap systems is work is imo really not a good idea. Much
> better if we get to the correct future step-by-step.

Yup, I fully agree. As a user-space dev I'm perfectly fine with an API
only available on some systems as a first step.

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-13  8:32                 ` Daniel Vetter
  2022-04-13  8:38                   ` Simon Ser
@ 2022-04-13  9:44                   ` Hans de Goede
  1 sibling, 0 replies; 44+ messages in thread
From: Hans de Goede @ 2022-04-13  9:44 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

Hi,

On 4/13/22 10:32, Daniel Vetter wrote:
> On Fri, Apr 08, 2022 at 12:26:24PM +0200, Hans de Goede wrote:
>> Hi,
>>
>> On 4/8/22 12:16, Simon Ser wrote:
>>> Would it be an option to only support the KMS prop for Good devices,
>>> and continue using the suboptimal existing sysfs API for Bad devices?
>>>
>>> (I'm just throwing ideas around to see what sticks, feel free to ignore.)
>>
>> Currently suid-root or pkexec helpers are used to deal with the
>> /sys/class/backlight requires root rights issue. I really want to
>> be able to disable these helpers at build time in e.g. GNOME once
>> the new properties are supported in GNOME.  So that distros with
>> a new enough kernel can reduce their attack surface this way.
> 
> Yeah but otoh perpetuating a bad interface forever isn't a great idea
> either. I think the pragmatic plan here is
> - Implement this properly on good devices, i.e. anything new.
> - Do some runtime disabling in the pkexec helpers if they detect a modern
>   system (we should be able to put a proper symlink into the drm sysfs
>   connector directories, to make this easy to detect). It's not as great
>   as doing this at compile time, but it's a step.
> - Figure out a solution for the old crap. We can't really change anything
>   with the load ordering for existing systems, so if the hacked-up compat
>   libbacklight-backlight isn't an option then I guess we need some quirk
>   list/extracted code which makes i915/nouveau/radeon driver load fail
>   until the right backlight shows up. And that needs to be behind a
>   Kconfig to avoid breaking existing systems.
> 
> Inflicting hotplug complications on all userspace (including uevent
> handling for this hotpluggable backlight and everything) just because
> fixing the old crap systems is work is imo really not a good idea. Much
> better if we get to the correct future step-by-step.

This assumes that we only use the new brightness properties for laptop
internal LCD panels.

But what about controlling the brightness of external monitors through
DDC/CI? If we do that we need hotplug support for this regardless since
external monitors can be hotplugged.

As I mentioned in other parts of the thread one of the reasons why
I've started looking into this again is because of people being
interested in this (1).

And even just taking internal LCD panels into account, there are
hybrid GPU laptops where the backlight is directly controlled by
the GPU (native type backlight driver) connected to the panel(2),
if we runtime switch the GPU attached to the panel there, then we
will get an actual hotplug of the LCD connector and I'm not sure if
we can always detect the maximum value of the brightness on the GPU
which is not connected to the panel at boot. So in this case we
need userspace to support re-reading the brightness max at
a hotplug event regardless.

So in all in all I feel that supporting hotplug events is
unavoidable here.

Regards,

Hans


1) Including attempting to do this through the old /sys/class/backlight
interface which IMHO would be quite bad to do:
https://lore.kernel.org/lkml/20220403230850.2986-1-yusisamerican@gmail.com/

2) E.g. gnome-settings-daemon has special code to detect which native
backlight interface to use if there are 2 native backlight devices on
a single laptop, see:
https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/blob/master/plugins/power/gsd-backlight.c#L95





^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-11 14:11                 ` Alex Deucher
@ 2022-04-14 10:24                   ` Jani Nikula
  2022-04-27 14:03                     ` Daniel Vetter
  0 siblings, 1 reply; 44+ messages in thread
From: Jani Nikula @ 2022-04-14 10:24 UTC (permalink / raw)
  To: Alex Deucher, Hans de Goede
  Cc: Sebastian Wick, Martin Roukala, dri-devel, wayland,
	Christoph Grenz, Yusuf Khan

On Mon, 11 Apr 2022, Alex Deucher <alexdeucher@gmail.com> wrote:
> On Mon, Apr 11, 2022 at 6:18 AM Hans de Goede <hdegoede@redhat.com> wrote:
>>
>> Hi,
>>
>> On 4/8/22 17:11, Alex Deucher wrote:
>> > On Fri, Apr 8, 2022 at 10:56 AM Hans de Goede <hdegoede@redhat.com> wrote:
>> >>
>> >> Hi,
>> >>
>> >> On 4/8/22 16:08, Alex Deucher wrote:
>> >>> On Fri, Apr 8, 2022 at 4:07 AM Daniel Vetter <daniel@ffwll.ch> wrote:
>> >>>>
>> >>>> On Thu, Apr 07, 2022 at 05:05:52PM -0400, Alex Deucher wrote:
>> >>>>> On Thu, Apr 7, 2022 at 1:43 PM Hans de Goede <hdegoede@redhat.com> wrote:
>> >>>>>>
>> >>>>>> Hi Simon,
>> >>>>>>
>> >>>>>> On 4/7/22 18:51, Simon Ser wrote:
>> >>>>>>> Very nice plan! Big +1 for the overall approach.
>> >>>>>>
>> >>>>>> Thanks.
>> >>>>>>
>> >>>>>>> On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
>> >>>>>>>
>> >>>>>>>> The drm_connector brightness properties
>> >>>>>>>> =======================================
>> >>>>>>>>
>> >>>>>>>> bl_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 bl_brightness_max.
>> >>>>>>>
>> >>>>>>> Do we need to split this up into two props for sw/hw state? The privacy screen
>> >>>>>>> stuff needed this, but you're pretty familiar with that. :)
>> >>>>>>
>> >>>>>> Luckily that won't be necessary, since the privacy-screen is a security
>> >>>>>> feature the firmware/embedded-controller may refuse our requests
>> >>>>>> (may temporarily lock-out changes) and/or may make changes without
>> >>>>>> us requesting them itself. Neither is really the case with the
>> >>>>>> brightness setting of displays.
>> >>>>>>
>> >>>>>>>> bl_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 (yet).
>> >>>>>>>
>> >>>>>>> I don't think we actually need that one. Integer KMS props all have a
>> >>>>>>> range which can be fetched via drmModeGetProperty. The max can be
>> >>>>>>> exposed via this range. Example with the existing alpha prop:
>> >>>>>>>
>> >>>>>>>     "alpha": range [0, UINT16_MAX] = 65535
>> >>>>>>
>> >>>>>> Right, I already knew that, which is why I explicitly added a range
>> >>>>>> to the props already. The problem is that the range must be set
>> >>>>>> before registering the connector and when the backlight driver
>> >>>>>> only shows up (much) later during boot then we don't know the
>> >>>>>> range when registering the connector. I guess we could "patch-up"
>> >>>>>> the range later. But AFAIK that would be a bit of abuse of the
>> >>>>>> property API as the range is intended to never change, not
>> >>>>>> even after hotplug uevents. At least atm there is no infra
>> >>>>>> in the kernel to change the range later.
>> >>>>>>
>> >>>>>> Which is why I added an explicit bl_brightness_max property
>> >>>>>> of which the value gives the actual effective maximum of the
>> >>>>>> brightness.
>> >>>>
>> >>>> Uh ... I'm not a huge fan tbh. The thing is, if we allow hotplugging
>> >>>> brightness control later on then we just perpetuate the nonsense we have
>> >>>> right now, forever.
>> >>>>
>> >>>> Imo we should support two kinds of drivers:
>> >>>>
>> >>>> - drivers which are non-crap, and make sure their backlight driver is
>> >>>>   loaded before they register the drm_device (or at least the
>> >>>>   drm_connector). For those we want the drm_connector->backlight pointer
>> >>>>   to bit static over the lifetime of the connector, and then we can also
>> >>>>   set up the brightness range correctly.
>> >>>>
>> >>>> - funny drivers which implement the glorious fallback dance which
>> >>>>   libbacklight implements currently in userspace. Imo for these drivers we
>> >>>>   should have a libbacklight_heuristics_backlight, which normalizes or
>> >>>>   whatever, and is also ways there. And then internally handles the
>> >>>>   fallback mess to the "right" backlight driver.
>> >>>>
>> >>>> We might have some gaps on acpi systems to make sure the drm driver can
>> >>>> wait for the backlight driver to show up, but that's about it.
>> >>>>
>> >>>> Hotplugging random pieces later on is really not how drivers work nowadays
>> >>>> with deferred probe and component framework and all that.
>> >>>>
>> >>>>>> I did consider using the range for this and updating it
>> >>>>>> on the fly I think nothing is really preventing us from
>> >>>>>> doing so, but it very much feels like abusing the generic
>> >>>>>> properties API.
>> >>>>>>
>> >>>>>>>> bl_brightness_0_is_min_brightness: ro, boolean
>> >>>>>>>> When this is set to true then it is safe to set brightness to 0
>> >>>>>>>> without worrying that this completely turns the backlight off causing
>> >>>>>>>> the screen to become unreadable. When this is false setting brightness
>> >>>>>>>> to 0 may turn the backlight off, but this is not guaranteed.
>> >>>>>>>> This will e.g. be true when directly driving a PWM and the video-BIOS
>> >>>>>>>> has provided a minimum (non 0) duty-cycle below which the driver will
>> >>>>>>>> never go.
>> >>>>>>>
>> >>>>>>> Hm. It's quite unfortunate that it's impossible to have strong guarantees
>> >>>>>>> here.
>> >>>>>>>
>> >>>>>>> Is there any way we can avoid this prop?
>> >>>>>>
>> >>>>>> Not really, the problem is that we really don't know if 0 is off
>> >>>>>> or min-brightness. In the given example where we actually never go
>> >>>>>> down to a duty-cycle of 0% because the video BIOS tables tell us
>> >>>>>> not to, we can be certain that setting the brightness prop to 0
>> >>>>>> will not turn of the backlight, since we then set the duty-cycle
>> >>>>>> to the VBT provided minimum. Note the intend here is to only set
>> >>>>>> the boolean to true if the VBT provided minimum is _not_ 0, 0
>> >>>>>> just means the vendor did not bother to provide a minimum.
>> >>>>>>
>> >>>>>> Currently e.g. GNOME never goes lower then something like 5%
>> >>>>>> of brightness_max to avoid accidentally turning the screen off.
>> >>>>>>
>> >>>>>> Turning the screen off is quite bad to do on e.g. tablets where
>> >>>>>> the GUI is the only way to undo the brightness change and now
>> >>>>>> the user can no longer see the GUI.
>> >>>>>>
>> >>>>>> The idea behind this boolean is to give e.g. GNOME a way to
>> >>>>>> know that it is safe to go down to 0% and for it to use
>> >>>>>> the entire range.
>> >>>>>
>> >>>>> Why not just make it policy that 0 is defined as minimum brightness,
>> >>>>> not off, and have all drivers conform to that?
>> >>>>
>> >>>> Because the backlight subsystem isn't as consistent on this, and it's been
>> >>>> an epic source of confusion since forever.
>> >>>>
>> >>>> What's worse, there's both userspace out there which assumes brightness =
>> >>>> 0 is a really fast dpms off _and_ userspace that assumes that brightness =
>> >>>> 0 is the lowest setting. Of course on different sets of machines.
>> >>>>
>> >>>> So yeah we're screwed. I have no idea how to get out of this.
>> >>>
>> >>> Yes, but this is a new API.  So can't we do better?  Sure the old
>> >>> backlight interface is broken, but why carry around clunky workarounds
>> >>> for new interfaces?
>> >>
>> >> Right we certainly need to define the behavior of the new API
>> >> clearly, so that userspace does not misuse / misinterpret it.
>> >>
>> >> The intend is for brightness=0 to mean minimum brightness
>> >> to still be able to see what is on the screen. But the problem
>> >> is that in many cases the GPU driver directly controls a PWM
>> >> output, no minimum PWM value is given in the video BIOS tables
>> >> and actually setting the PWM to 0% dutycycle turns off the
>> >> screen.
>> >
>> > Sure.  So have the GPU driver map 0 to some valid minimum if that is
>> > the case or might be the case.  If bugs come up, we can add quirks in
>> > the GPU drivers.
>>
>> The problem is that when 0% duty-cycle is not off, but minimum
>> brightness because there is some smart backlight-controller involved
>> downstream of the pwm, then of we limit it to say min 5% then we
>> have just limited the range of the brightness. GNOME already does
>> this in userspace now and it is already receiving bug-reports
>> from users that GNOME does not allow the brightness to go as low
>> as they like to have it in a dark(ish) room.
>>
>> And in some cases 5% is likely not enough for the backlight to
>> actually turn on. So it will be wrong in one direction on some
>> devices and wrong in the other direction in other devices.
>>
>> Which means that to satisfy everyone here we will need a ton
>> of quirks, much too many to maintain in the kernel IMHO.
>>
>>
>> >> So we can only promise a best-effort to make brightness=0
>> >> mean minimum brightness, combined with documenting that it
>> >> may turn off the backlight and that userspace _must_ never
>> >> depend on it turning off the backlight.
>> >>
>> >> Also note that setting a direct PWM output to duty-cycle 0%
>> >> does not guarantee that the backlight goes off, this may be
>> >> an input for a special backlight LED driver IC like the
>> >> TI LP855x series which can have an internal lookup
>> >> table causing it to actually output a minimum brightness
>> >> when its PWM input is at 0% dutycycle.  So this is a case
>> >> where we just don't get enough info from the fw/hw to be able
>> >> to offer the guarantees which we would like to guarantee.
>> >
>> > So set it to a level we can guarantee can call it 0.  If we have the
>> > flag we are just punting on the problem in my opinion.
>>
>> Right this an impossible problem to solve so the intent is indeed
>> to punt this to userspace, which IMHO is the best thing we can do
>> here.  The idea behind the "bl_brightness_0_is_min_brightness:
>> ro, boolean" property is to provide a hint to userspace to help
>> userspace deal with this (and if userspace ends up using e.g.
>> systemd's hwdb for this to avoid unnecessary entries in hwdb).
>>
>> >  The kernel
>> > driver would seem to have a better idea what is a valid minimum than
>> > some arbitrary userspace application.
>>
>> If the kernel driver knows the valid minimum then it can make 0
>> actually be that valid minimum as you suggest and it can set the
>> hint flag to let userspace know this. OTOH there are many cases
>> where the kernel's guess is just as bad as userspace's guess and
>> there are too many laptops where this is the case to quirk
>> ourselves out of this situation.
>>
>> > Plus then if we need a
>> > workaround for what is the minimum valid brightness, we can fix it one
>> > place rather than letting every application try and fix it.
>>
>> I wish we could solve this in the kernel, but at least on
>> laptops with Intel integrated gfx many vendors don't bother
>> to put a non 0 value in the minimum duty-cycle field of the
>> VBT, so there really is no good way to solve this.
>
> We have similar issues with AMD platforms.  Some platforms don't
> populate the min value tables, but in the driver we set the minimum
> safe value as the default min value when that happens.  It may not
> always go as low as the platform may be capable of, but at least we
> have consistent behavior and it's all controlled in one place.
>
>>
>> If the userspace folks ever want to do a database for this,
>> I would expect them to do something with hwdb + udev which
>> can then be shared between the different desktop-environments.
>
> So why not do it in the kernel?  At least that way everyone will get
> it the fixes as they happen.  A big user database may or may not
> happen and behavior will be inconsistent across desktop environments
> until that does.  I don't really see any value in having the flag.
> There will be cases where the flag is wrong and will require kernel
> fixes anyway (e.g., OEM switches panel due to supply chain issues and
> forgets to update the vbios, etc.), so why not just define 0 as
> minimum safe backlight value?  If it's too low and flickers or turns
> the backlight off, we quirk it.  If a particular platform can go
> lower, we can quirk it.  If we add the flag then we need to not only
> add quirks for the minimum value, but we also have to deal with quirks
> for when the flag is set wrong.  So now we are maintaining two quirks
> instead of one.

Just chiming in, there are certainly plenty of panels and designs where
0 PWM duty cycle is physically not possible, and thus 0 brightness
simply can't universally mean off.

Daniel referred to a case where 0 brightness was used as fast mini dpms
off, and I think it's fundamentally a broken use case. We can't
guarantee to be able to support that. I think the appeal was partly in
being able to do it without access to kms api, quick and dirty via
sysfs.

Please let's just make 0 the minimum but not off. If you want off, you
do modeset, and the driver can follow panel timings etc.

I think that's also something the kernel can actually guarantee, while
we can't guarantee 0 is off.


BR,
Jani.




-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-07 15:38 [RFC] drm/kms: control display brightness through drm_connector properties Hans de Goede
  2022-04-07 16:51 ` Simon Ser
  2022-04-07 18:58 ` Carsten Haitzler
@ 2022-04-14 13:10 ` Jani Nikula
  2022-05-18 12:59   ` Hans de Goede
  2022-08-24  2:18 ` Yusuf Khan
  3 siblings, 1 reply; 44+ messages in thread
From: Jani Nikula @ 2022-04-14 13:10 UTC (permalink / raw)
  To: Hans de Goede, dri-devel, wayland
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, Yusuf Khan

On Thu, 07 Apr 2022, Hans de Goede <hdegoede@redhat.com> wrote:
> 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.
>
> 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.
>
>
> What scale to use for the drm_connector bl_brightness property?
> ===============================================================
>
> The tricky part of this plan is phase 2 and then esp. defining what the
> new brightness properties will look like and how they will work.
>
> The biggest challenge here is to decide on a fixed scale for the main
> brightness property, say 0-65535, using scaling where the actual hw scale
> is different, or if this should simply be a 1:1 mirror of the current
> backlight interface, with the actual hw scale / brightness_max value
> exposed as a drm_connector property.
>
> 1:1 advantages / 0-65535 disadvantages
> - Userspace will likely move over to the connector-props quite slowly and
>   we can expect various userspace bits, esp. also custom user scripts, to
>   keep using the old uAPI for a long time. Using the 2 APIs are intermixed
>   is fine when using a 1:1 brightness scale mapping. But if we end up doing
>   a scaling round-trip all the time then eventually the brightness is going
>   do drift. This can even happen if the user never changes the brightness
>   when userspace saves it over suspend/resume or reboots.
> - Almost all laptops have brightness up/down hotkeys. E.g GNOME decides
>   on a step size for the hotkeys by doing min(brightness_max/20, 1).
>   Some of the vendor specific backlight fw APIs (e.g. dell-laptop) have
>   only 8 steps. When giving userspace the actual max_brightness value, then
>   this will all work just fine. When hardcode brightness_max to 65535 OTOH
>   then in this case GNOME will still give the user 20 steps where only 1
>   in every 2-3 steps actually changes the brightness which IMHO is
>   an unacceptably bad user experience.
>
> 0-65535 advantages / 1:1 disadvantages
> - Without a fixed scale for the brightness property the brightness_max
>   value may change after an userspace application's initial enumeration
>   of the drm_connector. This can happen when neither the native GPU nor
>   the acpi_video backlight devices are present/usable in this case
>   acpi_video_get_backlight_type() will _assume_ a vendor specific fw API
>   will be used for backlight control and the driver proving the "vendor"
>   backlight device will show up much later and may even never show-up,
>   so waiting for it is not an option. With a fixed 0-65535 scale userspace
>   can just always assume this and the drm_connector backlight props helper
>   code can even cache writes and send it to the actual backlight device
>   when it shows up. With a 1:1 mapping userspace needs to listen for
>   a uevent and then update the brightness range on such an event.
>
> I believe that the 1:1 mapping advantages out way the disadvantages
> here. Also note that current userspace already blindly assumes that
> all relevant drivers are loaded before the graphical-environment
> starts and all the desktop environments as such already only do
> a single scan of /sys/class/backlight when they start. So when
> userspace forgets to add code to listen for the uevent when switching
> to the new API nothing changes; and with the uevent userspace actually
> gets a good mechanism to detect backlight drivers loading after
> the graphical-environment has already started.
>
> So based on this here is my proposal for a set of new brightness
> properties on the drm_connector object. Note these are all prefixed with
> bl which stands for backlight, which is technically not correct for OLED.
> But we need a prefix to avoid a name collision with the "brightness"
> attribute which is part of the existing TV specific properties and IMHO
> it is good to have a common prefix to make it clear that these all
> belong together.
>
>
> The drm_connector brightness properties
> =======================================
>
> bl_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 bl_brightness_max.
>
> bl_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 (yet).
>
> bl_brightness_0_is_min_brightness: ro, boolean
> When this is set to true then it is safe to set brightness to 0
> without worrying that this completely turns the backlight off causing
> the screen to become unreadable. When this is false setting brightness
> to 0 may turn the backlight off, but this is _not_ guaranteed.
> This will e.g. be true when directly driving a PWM and the video-BIOS
> has provided a minimum (non 0) duty-cycle below which the driver will
> never go.
>
> bl_brightness_control_method: ro, enum, possible values:
> none:     The GPU driver expects brightness control to be provided by another
>           driver and that driver has not loaded yet.
> unknown:  The underlying control mechanism is unknown.
> pwm:      The brightness property directly controls the duty-cycle of a PWM
>           output.
> firmware: The brightness is controlled through firmware calls.
> DDC/CI:   The brightness is controlled through the DDC/CI protocol.
> gmux:     The brightness is controlled by the GMUX.
> Note this enum may be extended in the future, so other values may
> be read, these should be treated as "unknown".

Some eDP panels support brightness control via DPCD, in complex
ways. Some of them support mixed modes via both DPCD and PWM
simultaneously. Some of them support luminance based control.

DSI command mode panels support brightness control via DCS commands.

> When brightness control becomes available after being reported
> as not available before (bl_brightness_control_method=="none")
> a uevent with CONNECTOR=<connector-id> and
> PROPERTY=<bl_brightness_control_method-id> will be generated
> at this point all the properties must be re-read.
>
> When/once brightness control is available then all the read-only
> properties are fixed and will never change.
>
> Besides the "none" value for no driver having loaded yet,
> the different bl_brightness_control_method values are intended for
> (userspace) heuristics for such things as the brightness setting
> linearly controlling electrical power or setting perceived brightness.

I'm not sure if it's a good idea to expose this with the goal that it's
to be used for heuristics. We usually don't even know if we're
controlling actual backlight brightness or just the OLED
brightness. Basically any of the methods could be used to control OLED,
or some HDR display with luminance based controls, and the heuristics
would be off.

There are some cases where we can actually get a rough PWM/luminance
curve from i915 opregion. I think maybe 16 data points. We've never
exposed that. My idea was that you'd have a property where you could add
data points for the curve, it could get pre-populated by the kernel if
the kernel knows how to do it, defaulting to linear, but it could also
be set or adjusted by userspace. The point would be that the userspace
adjusts brightness linearly, and the kernel would use the curve data
points to adjust it non-linearly. The userspace could have completely
separated brightness adjustment and curve adjustment, and the brightness
adjustment would be dead simple.

Finally, I'd drop "backlight" as a term throughout. It's brightness
we're setting, and backlight is just a panel implementation detail.


BR,
Jani.

>
> 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
>

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-14 10:24                   ` Jani Nikula
@ 2022-04-27 14:03                     ` Daniel Vetter
  2022-04-27 14:23                       ` Jani Nikula
  0 siblings, 1 reply; 44+ messages in thread
From: Daniel Vetter @ 2022-04-27 14:03 UTC (permalink / raw)
  To: Jani Nikula
  Cc: Sebastian Wick, Martin Roukala, dri-devel, wayland,
	Hans de Goede, Christoph Grenz, Yusuf Khan

On Thu, Apr 14, 2022 at 01:24:30PM +0300, Jani Nikula wrote:
> On Mon, 11 Apr 2022, Alex Deucher <alexdeucher@gmail.com> wrote:
> > On Mon, Apr 11, 2022 at 6:18 AM Hans de Goede <hdegoede@redhat.com> wrote:
> >>
> >> Hi,
> >>
> >> On 4/8/22 17:11, Alex Deucher wrote:
> >> > On Fri, Apr 8, 2022 at 10:56 AM Hans de Goede <hdegoede@redhat.com> wrote:
> >> >>
> >> >> Hi,
> >> >>
> >> >> On 4/8/22 16:08, Alex Deucher wrote:
> >> >>> On Fri, Apr 8, 2022 at 4:07 AM Daniel Vetter <daniel@ffwll.ch> wrote:
> >> >>>>
> >> >>>> On Thu, Apr 07, 2022 at 05:05:52PM -0400, Alex Deucher wrote:
> >> >>>>> On Thu, Apr 7, 2022 at 1:43 PM Hans de Goede <hdegoede@redhat.com> wrote:
> >> >>>>>>
> >> >>>>>> Hi Simon,
> >> >>>>>>
> >> >>>>>> On 4/7/22 18:51, Simon Ser wrote:
> >> >>>>>>> Very nice plan! Big +1 for the overall approach.
> >> >>>>>>
> >> >>>>>> Thanks.
> >> >>>>>>
> >> >>>>>>> On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
> >> >>>>>>>
> >> >>>>>>>> The drm_connector brightness properties
> >> >>>>>>>> =======================================
> >> >>>>>>>>
> >> >>>>>>>> bl_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 bl_brightness_max.
> >> >>>>>>>
> >> >>>>>>> Do we need to split this up into two props for sw/hw state? The privacy screen
> >> >>>>>>> stuff needed this, but you're pretty familiar with that. :)
> >> >>>>>>
> >> >>>>>> Luckily that won't be necessary, since the privacy-screen is a security
> >> >>>>>> feature the firmware/embedded-controller may refuse our requests
> >> >>>>>> (may temporarily lock-out changes) and/or may make changes without
> >> >>>>>> us requesting them itself. Neither is really the case with the
> >> >>>>>> brightness setting of displays.
> >> >>>>>>
> >> >>>>>>>> bl_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 (yet).
> >> >>>>>>>
> >> >>>>>>> I don't think we actually need that one. Integer KMS props all have a
> >> >>>>>>> range which can be fetched via drmModeGetProperty. The max can be
> >> >>>>>>> exposed via this range. Example with the existing alpha prop:
> >> >>>>>>>
> >> >>>>>>>     "alpha": range [0, UINT16_MAX] = 65535
> >> >>>>>>
> >> >>>>>> Right, I already knew that, which is why I explicitly added a range
> >> >>>>>> to the props already. The problem is that the range must be set
> >> >>>>>> before registering the connector and when the backlight driver
> >> >>>>>> only shows up (much) later during boot then we don't know the
> >> >>>>>> range when registering the connector. I guess we could "patch-up"
> >> >>>>>> the range later. But AFAIK that would be a bit of abuse of the
> >> >>>>>> property API as the range is intended to never change, not
> >> >>>>>> even after hotplug uevents. At least atm there is no infra
> >> >>>>>> in the kernel to change the range later.
> >> >>>>>>
> >> >>>>>> Which is why I added an explicit bl_brightness_max property
> >> >>>>>> of which the value gives the actual effective maximum of the
> >> >>>>>> brightness.
> >> >>>>
> >> >>>> Uh ... I'm not a huge fan tbh. The thing is, if we allow hotplugging
> >> >>>> brightness control later on then we just perpetuate the nonsense we have
> >> >>>> right now, forever.
> >> >>>>
> >> >>>> Imo we should support two kinds of drivers:
> >> >>>>
> >> >>>> - drivers which are non-crap, and make sure their backlight driver is
> >> >>>>   loaded before they register the drm_device (or at least the
> >> >>>>   drm_connector). For those we want the drm_connector->backlight pointer
> >> >>>>   to bit static over the lifetime of the connector, and then we can also
> >> >>>>   set up the brightness range correctly.
> >> >>>>
> >> >>>> - funny drivers which implement the glorious fallback dance which
> >> >>>>   libbacklight implements currently in userspace. Imo for these drivers we
> >> >>>>   should have a libbacklight_heuristics_backlight, which normalizes or
> >> >>>>   whatever, and is also ways there. And then internally handles the
> >> >>>>   fallback mess to the "right" backlight driver.
> >> >>>>
> >> >>>> We might have some gaps on acpi systems to make sure the drm driver can
> >> >>>> wait for the backlight driver to show up, but that's about it.
> >> >>>>
> >> >>>> Hotplugging random pieces later on is really not how drivers work nowadays
> >> >>>> with deferred probe and component framework and all that.
> >> >>>>
> >> >>>>>> I did consider using the range for this and updating it
> >> >>>>>> on the fly I think nothing is really preventing us from
> >> >>>>>> doing so, but it very much feels like abusing the generic
> >> >>>>>> properties API.
> >> >>>>>>
> >> >>>>>>>> bl_brightness_0_is_min_brightness: ro, boolean
> >> >>>>>>>> When this is set to true then it is safe to set brightness to 0
> >> >>>>>>>> without worrying that this completely turns the backlight off causing
> >> >>>>>>>> the screen to become unreadable. When this is false setting brightness
> >> >>>>>>>> to 0 may turn the backlight off, but this is not guaranteed.
> >> >>>>>>>> This will e.g. be true when directly driving a PWM and the video-BIOS
> >> >>>>>>>> has provided a minimum (non 0) duty-cycle below which the driver will
> >> >>>>>>>> never go.
> >> >>>>>>>
> >> >>>>>>> Hm. It's quite unfortunate that it's impossible to have strong guarantees
> >> >>>>>>> here.
> >> >>>>>>>
> >> >>>>>>> Is there any way we can avoid this prop?
> >> >>>>>>
> >> >>>>>> Not really, the problem is that we really don't know if 0 is off
> >> >>>>>> or min-brightness. In the given example where we actually never go
> >> >>>>>> down to a duty-cycle of 0% because the video BIOS tables tell us
> >> >>>>>> not to, we can be certain that setting the brightness prop to 0
> >> >>>>>> will not turn of the backlight, since we then set the duty-cycle
> >> >>>>>> to the VBT provided minimum. Note the intend here is to only set
> >> >>>>>> the boolean to true if the VBT provided minimum is _not_ 0, 0
> >> >>>>>> just means the vendor did not bother to provide a minimum.
> >> >>>>>>
> >> >>>>>> Currently e.g. GNOME never goes lower then something like 5%
> >> >>>>>> of brightness_max to avoid accidentally turning the screen off.
> >> >>>>>>
> >> >>>>>> Turning the screen off is quite bad to do on e.g. tablets where
> >> >>>>>> the GUI is the only way to undo the brightness change and now
> >> >>>>>> the user can no longer see the GUI.
> >> >>>>>>
> >> >>>>>> The idea behind this boolean is to give e.g. GNOME a way to
> >> >>>>>> know that it is safe to go down to 0% and for it to use
> >> >>>>>> the entire range.
> >> >>>>>
> >> >>>>> Why not just make it policy that 0 is defined as minimum brightness,
> >> >>>>> not off, and have all drivers conform to that?
> >> >>>>
> >> >>>> Because the backlight subsystem isn't as consistent on this, and it's been
> >> >>>> an epic source of confusion since forever.
> >> >>>>
> >> >>>> What's worse, there's both userspace out there which assumes brightness =
> >> >>>> 0 is a really fast dpms off _and_ userspace that assumes that brightness =
> >> >>>> 0 is the lowest setting. Of course on different sets of machines.
> >> >>>>
> >> >>>> So yeah we're screwed. I have no idea how to get out of this.
> >> >>>
> >> >>> Yes, but this is a new API.  So can't we do better?  Sure the old
> >> >>> backlight interface is broken, but why carry around clunky workarounds
> >> >>> for new interfaces?
> >> >>
> >> >> Right we certainly need to define the behavior of the new API
> >> >> clearly, so that userspace does not misuse / misinterpret it.
> >> >>
> >> >> The intend is for brightness=0 to mean minimum brightness
> >> >> to still be able to see what is on the screen. But the problem
> >> >> is that in many cases the GPU driver directly controls a PWM
> >> >> output, no minimum PWM value is given in the video BIOS tables
> >> >> and actually setting the PWM to 0% dutycycle turns off the
> >> >> screen.
> >> >
> >> > Sure.  So have the GPU driver map 0 to some valid minimum if that is
> >> > the case or might be the case.  If bugs come up, we can add quirks in
> >> > the GPU drivers.
> >>
> >> The problem is that when 0% duty-cycle is not off, but minimum
> >> brightness because there is some smart backlight-controller involved
> >> downstream of the pwm, then of we limit it to say min 5% then we
> >> have just limited the range of the brightness. GNOME already does
> >> this in userspace now and it is already receiving bug-reports
> >> from users that GNOME does not allow the brightness to go as low
> >> as they like to have it in a dark(ish) room.
> >>
> >> And in some cases 5% is likely not enough for the backlight to
> >> actually turn on. So it will be wrong in one direction on some
> >> devices and wrong in the other direction in other devices.
> >>
> >> Which means that to satisfy everyone here we will need a ton
> >> of quirks, much too many to maintain in the kernel IMHO.
> >>
> >>
> >> >> So we can only promise a best-effort to make brightness=0
> >> >> mean minimum brightness, combined with documenting that it
> >> >> may turn off the backlight and that userspace _must_ never
> >> >> depend on it turning off the backlight.
> >> >>
> >> >> Also note that setting a direct PWM output to duty-cycle 0%
> >> >> does not guarantee that the backlight goes off, this may be
> >> >> an input for a special backlight LED driver IC like the
> >> >> TI LP855x series which can have an internal lookup
> >> >> table causing it to actually output a minimum brightness
> >> >> when its PWM input is at 0% dutycycle.  So this is a case
> >> >> where we just don't get enough info from the fw/hw to be able
> >> >> to offer the guarantees which we would like to guarantee.
> >> >
> >> > So set it to a level we can guarantee can call it 0.  If we have the
> >> > flag we are just punting on the problem in my opinion.
> >>
> >> Right this an impossible problem to solve so the intent is indeed
> >> to punt this to userspace, which IMHO is the best thing we can do
> >> here.  The idea behind the "bl_brightness_0_is_min_brightness:
> >> ro, boolean" property is to provide a hint to userspace to help
> >> userspace deal with this (and if userspace ends up using e.g.
> >> systemd's hwdb for this to avoid unnecessary entries in hwdb).
> >>
> >> >  The kernel
> >> > driver would seem to have a better idea what is a valid minimum than
> >> > some arbitrary userspace application.
> >>
> >> If the kernel driver knows the valid minimum then it can make 0
> >> actually be that valid minimum as you suggest and it can set the
> >> hint flag to let userspace know this. OTOH there are many cases
> >> where the kernel's guess is just as bad as userspace's guess and
> >> there are too many laptops where this is the case to quirk
> >> ourselves out of this situation.
> >>
> >> > Plus then if we need a
> >> > workaround for what is the minimum valid brightness, we can fix it one
> >> > place rather than letting every application try and fix it.
> >>
> >> I wish we could solve this in the kernel, but at least on
> >> laptops with Intel integrated gfx many vendors don't bother
> >> to put a non 0 value in the minimum duty-cycle field of the
> >> VBT, so there really is no good way to solve this.
> >
> > We have similar issues with AMD platforms.  Some platforms don't
> > populate the min value tables, but in the driver we set the minimum
> > safe value as the default min value when that happens.  It may not
> > always go as low as the platform may be capable of, but at least we
> > have consistent behavior and it's all controlled in one place.
> >
> >>
> >> If the userspace folks ever want to do a database for this,
> >> I would expect them to do something with hwdb + udev which
> >> can then be shared between the different desktop-environments.
> >
> > So why not do it in the kernel?  At least that way everyone will get
> > it the fixes as they happen.  A big user database may or may not
> > happen and behavior will be inconsistent across desktop environments
> > until that does.  I don't really see any value in having the flag.
> > There will be cases where the flag is wrong and will require kernel
> > fixes anyway (e.g., OEM switches panel due to supply chain issues and
> > forgets to update the vbios, etc.), so why not just define 0 as
> > minimum safe backlight value?  If it's too low and flickers or turns
> > the backlight off, we quirk it.  If a particular platform can go
> > lower, we can quirk it.  If we add the flag then we need to not only
> > add quirks for the minimum value, but we also have to deal with quirks
> > for when the flag is set wrong.  So now we are maintaining two quirks
> > instead of one.
> 
> Just chiming in, there are certainly plenty of panels and designs where
> 0 PWM duty cycle is physically not possible, and thus 0 brightness
> simply can't universally mean off.
> 
> Daniel referred to a case where 0 brightness was used as fast mini dpms
> off, and I think it's fundamentally a broken use case. We can't
> guarantee to be able to support that. I think the appeal was partly in
> being able to do it without access to kms api, quick and dirty via
> sysfs.
> 
> Please let's just make 0 the minimum but not off. If you want off, you
> do modeset, and the driver can follow panel timings etc.
> 
> I think that's also something the kernel can actually guarantee, while
> we can't guarantee 0 is off.

Yes.

The trouble is that we have platforms where it works like this, and so
retroactively redefining what brightness 0 means would be a regression. I
guess just another reason for why we should roll this out step by step,
with latest platforms first.

Or we shrug and decide to break things like that and redefine the
backlight semantics a bit. Or well define them properly to begin with :-)
-Daniel

> 
> 
> BR,
> Jani.
> 
> 
> 
> 
> -- 
> Jani Nikula, Intel Open Source Graphics Center

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-27 14:03                     ` Daniel Vetter
@ 2022-04-27 14:23                       ` Jani Nikula
  2022-04-27 14:26                         ` Daniel Vetter
  0 siblings, 1 reply; 44+ messages in thread
From: Jani Nikula @ 2022-04-27 14:23 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Sebastian Wick, Martin Roukala, dri-devel, wayland,
	Hans de Goede, Christoph Grenz, Yusuf Khan

On Wed, 27 Apr 2022, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Thu, Apr 14, 2022 at 01:24:30PM +0300, Jani Nikula wrote:
>> On Mon, 11 Apr 2022, Alex Deucher <alexdeucher@gmail.com> wrote:
>> > On Mon, Apr 11, 2022 at 6:18 AM Hans de Goede <hdegoede@redhat.com> wrote:
>> >>
>> >> Hi,
>> >>
>> >> On 4/8/22 17:11, Alex Deucher wrote:
>> >> > On Fri, Apr 8, 2022 at 10:56 AM Hans de Goede <hdegoede@redhat.com> wrote:
>> >> >>
>> >> >> Hi,
>> >> >>
>> >> >> On 4/8/22 16:08, Alex Deucher wrote:
>> >> >>> On Fri, Apr 8, 2022 at 4:07 AM Daniel Vetter <daniel@ffwll.ch> wrote:
>> >> >>>>
>> >> >>>> On Thu, Apr 07, 2022 at 05:05:52PM -0400, Alex Deucher wrote:
>> >> >>>>> On Thu, Apr 7, 2022 at 1:43 PM Hans de Goede <hdegoede@redhat.com> wrote:
>> >> >>>>>>
>> >> >>>>>> Hi Simon,
>> >> >>>>>>
>> >> >>>>>> On 4/7/22 18:51, Simon Ser wrote:
>> >> >>>>>>> Very nice plan! Big +1 for the overall approach.
>> >> >>>>>>
>> >> >>>>>> Thanks.
>> >> >>>>>>
>> >> >>>>>>> On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
>> >> >>>>>>>
>> >> >>>>>>>> The drm_connector brightness properties
>> >> >>>>>>>> =======================================
>> >> >>>>>>>>
>> >> >>>>>>>> bl_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 bl_brightness_max.
>> >> >>>>>>>
>> >> >>>>>>> Do we need to split this up into two props for sw/hw state? The privacy screen
>> >> >>>>>>> stuff needed this, but you're pretty familiar with that. :)
>> >> >>>>>>
>> >> >>>>>> Luckily that won't be necessary, since the privacy-screen is a security
>> >> >>>>>> feature the firmware/embedded-controller may refuse our requests
>> >> >>>>>> (may temporarily lock-out changes) and/or may make changes without
>> >> >>>>>> us requesting them itself. Neither is really the case with the
>> >> >>>>>> brightness setting of displays.
>> >> >>>>>>
>> >> >>>>>>>> bl_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 (yet).
>> >> >>>>>>>
>> >> >>>>>>> I don't think we actually need that one. Integer KMS props all have a
>> >> >>>>>>> range which can be fetched via drmModeGetProperty. The max can be
>> >> >>>>>>> exposed via this range. Example with the existing alpha prop:
>> >> >>>>>>>
>> >> >>>>>>>     "alpha": range [0, UINT16_MAX] = 65535
>> >> >>>>>>
>> >> >>>>>> Right, I already knew that, which is why I explicitly added a range
>> >> >>>>>> to the props already. The problem is that the range must be set
>> >> >>>>>> before registering the connector and when the backlight driver
>> >> >>>>>> only shows up (much) later during boot then we don't know the
>> >> >>>>>> range when registering the connector. I guess we could "patch-up"
>> >> >>>>>> the range later. But AFAIK that would be a bit of abuse of the
>> >> >>>>>> property API as the range is intended to never change, not
>> >> >>>>>> even after hotplug uevents. At least atm there is no infra
>> >> >>>>>> in the kernel to change the range later.
>> >> >>>>>>
>> >> >>>>>> Which is why I added an explicit bl_brightness_max property
>> >> >>>>>> of which the value gives the actual effective maximum of the
>> >> >>>>>> brightness.
>> >> >>>>
>> >> >>>> Uh ... I'm not a huge fan tbh. The thing is, if we allow hotplugging
>> >> >>>> brightness control later on then we just perpetuate the nonsense we have
>> >> >>>> right now, forever.
>> >> >>>>
>> >> >>>> Imo we should support two kinds of drivers:
>> >> >>>>
>> >> >>>> - drivers which are non-crap, and make sure their backlight driver is
>> >> >>>>   loaded before they register the drm_device (or at least the
>> >> >>>>   drm_connector). For those we want the drm_connector->backlight pointer
>> >> >>>>   to bit static over the lifetime of the connector, and then we can also
>> >> >>>>   set up the brightness range correctly.
>> >> >>>>
>> >> >>>> - funny drivers which implement the glorious fallback dance which
>> >> >>>>   libbacklight implements currently in userspace. Imo for these drivers we
>> >> >>>>   should have a libbacklight_heuristics_backlight, which normalizes or
>> >> >>>>   whatever, and is also ways there. And then internally handles the
>> >> >>>>   fallback mess to the "right" backlight driver.
>> >> >>>>
>> >> >>>> We might have some gaps on acpi systems to make sure the drm driver can
>> >> >>>> wait for the backlight driver to show up, but that's about it.
>> >> >>>>
>> >> >>>> Hotplugging random pieces later on is really not how drivers work nowadays
>> >> >>>> with deferred probe and component framework and all that.
>> >> >>>>
>> >> >>>>>> I did consider using the range for this and updating it
>> >> >>>>>> on the fly I think nothing is really preventing us from
>> >> >>>>>> doing so, but it very much feels like abusing the generic
>> >> >>>>>> properties API.
>> >> >>>>>>
>> >> >>>>>>>> bl_brightness_0_is_min_brightness: ro, boolean
>> >> >>>>>>>> When this is set to true then it is safe to set brightness to 0
>> >> >>>>>>>> without worrying that this completely turns the backlight off causing
>> >> >>>>>>>> the screen to become unreadable. When this is false setting brightness
>> >> >>>>>>>> to 0 may turn the backlight off, but this is not guaranteed.
>> >> >>>>>>>> This will e.g. be true when directly driving a PWM and the video-BIOS
>> >> >>>>>>>> has provided a minimum (non 0) duty-cycle below which the driver will
>> >> >>>>>>>> never go.
>> >> >>>>>>>
>> >> >>>>>>> Hm. It's quite unfortunate that it's impossible to have strong guarantees
>> >> >>>>>>> here.
>> >> >>>>>>>
>> >> >>>>>>> Is there any way we can avoid this prop?
>> >> >>>>>>
>> >> >>>>>> Not really, the problem is that we really don't know if 0 is off
>> >> >>>>>> or min-brightness. In the given example where we actually never go
>> >> >>>>>> down to a duty-cycle of 0% because the video BIOS tables tell us
>> >> >>>>>> not to, we can be certain that setting the brightness prop to 0
>> >> >>>>>> will not turn of the backlight, since we then set the duty-cycle
>> >> >>>>>> to the VBT provided minimum. Note the intend here is to only set
>> >> >>>>>> the boolean to true if the VBT provided minimum is _not_ 0, 0
>> >> >>>>>> just means the vendor did not bother to provide a minimum.
>> >> >>>>>>
>> >> >>>>>> Currently e.g. GNOME never goes lower then something like 5%
>> >> >>>>>> of brightness_max to avoid accidentally turning the screen off.
>> >> >>>>>>
>> >> >>>>>> Turning the screen off is quite bad to do on e.g. tablets where
>> >> >>>>>> the GUI is the only way to undo the brightness change and now
>> >> >>>>>> the user can no longer see the GUI.
>> >> >>>>>>
>> >> >>>>>> The idea behind this boolean is to give e.g. GNOME a way to
>> >> >>>>>> know that it is safe to go down to 0% and for it to use
>> >> >>>>>> the entire range.
>> >> >>>>>
>> >> >>>>> Why not just make it policy that 0 is defined as minimum brightness,
>> >> >>>>> not off, and have all drivers conform to that?
>> >> >>>>
>> >> >>>> Because the backlight subsystem isn't as consistent on this, and it's been
>> >> >>>> an epic source of confusion since forever.
>> >> >>>>
>> >> >>>> What's worse, there's both userspace out there which assumes brightness =
>> >> >>>> 0 is a really fast dpms off _and_ userspace that assumes that brightness =
>> >> >>>> 0 is the lowest setting. Of course on different sets of machines.
>> >> >>>>
>> >> >>>> So yeah we're screwed. I have no idea how to get out of this.
>> >> >>>
>> >> >>> Yes, but this is a new API.  So can't we do better?  Sure the old
>> >> >>> backlight interface is broken, but why carry around clunky workarounds
>> >> >>> for new interfaces?
>> >> >>
>> >> >> Right we certainly need to define the behavior of the new API
>> >> >> clearly, so that userspace does not misuse / misinterpret it.
>> >> >>
>> >> >> The intend is for brightness=0 to mean minimum brightness
>> >> >> to still be able to see what is on the screen. But the problem
>> >> >> is that in many cases the GPU driver directly controls a PWM
>> >> >> output, no minimum PWM value is given in the video BIOS tables
>> >> >> and actually setting the PWM to 0% dutycycle turns off the
>> >> >> screen.
>> >> >
>> >> > Sure.  So have the GPU driver map 0 to some valid minimum if that is
>> >> > the case or might be the case.  If bugs come up, we can add quirks in
>> >> > the GPU drivers.
>> >>
>> >> The problem is that when 0% duty-cycle is not off, but minimum
>> >> brightness because there is some smart backlight-controller involved
>> >> downstream of the pwm, then of we limit it to say min 5% then we
>> >> have just limited the range of the brightness. GNOME already does
>> >> this in userspace now and it is already receiving bug-reports
>> >> from users that GNOME does not allow the brightness to go as low
>> >> as they like to have it in a dark(ish) room.
>> >>
>> >> And in some cases 5% is likely not enough for the backlight to
>> >> actually turn on. So it will be wrong in one direction on some
>> >> devices and wrong in the other direction in other devices.
>> >>
>> >> Which means that to satisfy everyone here we will need a ton
>> >> of quirks, much too many to maintain in the kernel IMHO.
>> >>
>> >>
>> >> >> So we can only promise a best-effort to make brightness=0
>> >> >> mean minimum brightness, combined with documenting that it
>> >> >> may turn off the backlight and that userspace _must_ never
>> >> >> depend on it turning off the backlight.
>> >> >>
>> >> >> Also note that setting a direct PWM output to duty-cycle 0%
>> >> >> does not guarantee that the backlight goes off, this may be
>> >> >> an input for a special backlight LED driver IC like the
>> >> >> TI LP855x series which can have an internal lookup
>> >> >> table causing it to actually output a minimum brightness
>> >> >> when its PWM input is at 0% dutycycle.  So this is a case
>> >> >> where we just don't get enough info from the fw/hw to be able
>> >> >> to offer the guarantees which we would like to guarantee.
>> >> >
>> >> > So set it to a level we can guarantee can call it 0.  If we have the
>> >> > flag we are just punting on the problem in my opinion.
>> >>
>> >> Right this an impossible problem to solve so the intent is indeed
>> >> to punt this to userspace, which IMHO is the best thing we can do
>> >> here.  The idea behind the "bl_brightness_0_is_min_brightness:
>> >> ro, boolean" property is to provide a hint to userspace to help
>> >> userspace deal with this (and if userspace ends up using e.g.
>> >> systemd's hwdb for this to avoid unnecessary entries in hwdb).
>> >>
>> >> >  The kernel
>> >> > driver would seem to have a better idea what is a valid minimum than
>> >> > some arbitrary userspace application.
>> >>
>> >> If the kernel driver knows the valid minimum then it can make 0
>> >> actually be that valid minimum as you suggest and it can set the
>> >> hint flag to let userspace know this. OTOH there are many cases
>> >> where the kernel's guess is just as bad as userspace's guess and
>> >> there are too many laptops where this is the case to quirk
>> >> ourselves out of this situation.
>> >>
>> >> > Plus then if we need a
>> >> > workaround for what is the minimum valid brightness, we can fix it one
>> >> > place rather than letting every application try and fix it.
>> >>
>> >> I wish we could solve this in the kernel, but at least on
>> >> laptops with Intel integrated gfx many vendors don't bother
>> >> to put a non 0 value in the minimum duty-cycle field of the
>> >> VBT, so there really is no good way to solve this.
>> >
>> > We have similar issues with AMD platforms.  Some platforms don't
>> > populate the min value tables, but in the driver we set the minimum
>> > safe value as the default min value when that happens.  It may not
>> > always go as low as the platform may be capable of, but at least we
>> > have consistent behavior and it's all controlled in one place.
>> >
>> >>
>> >> If the userspace folks ever want to do a database for this,
>> >> I would expect them to do something with hwdb + udev which
>> >> can then be shared between the different desktop-environments.
>> >
>> > So why not do it in the kernel?  At least that way everyone will get
>> > it the fixes as they happen.  A big user database may or may not
>> > happen and behavior will be inconsistent across desktop environments
>> > until that does.  I don't really see any value in having the flag.
>> > There will be cases where the flag is wrong and will require kernel
>> > fixes anyway (e.g., OEM switches panel due to supply chain issues and
>> > forgets to update the vbios, etc.), so why not just define 0 as
>> > minimum safe backlight value?  If it's too low and flickers or turns
>> > the backlight off, we quirk it.  If a particular platform can go
>> > lower, we can quirk it.  If we add the flag then we need to not only
>> > add quirks for the minimum value, but we also have to deal with quirks
>> > for when the flag is set wrong.  So now we are maintaining two quirks
>> > instead of one.
>> 
>> Just chiming in, there are certainly plenty of panels and designs where
>> 0 PWM duty cycle is physically not possible, and thus 0 brightness
>> simply can't universally mean off.
>> 
>> Daniel referred to a case where 0 brightness was used as fast mini dpms
>> off, and I think it's fundamentally a broken use case. We can't
>> guarantee to be able to support that. I think the appeal was partly in
>> being able to do it without access to kms api, quick and dirty via
>> sysfs.
>> 
>> Please let's just make 0 the minimum but not off. If you want off, you
>> do modeset, and the driver can follow panel timings etc.
>> 
>> I think that's also something the kernel can actually guarantee, while
>> we can't guarantee 0 is off.
>
> Yes.
>
> The trouble is that we have platforms where it works like this, and so
> retroactively redefining what brightness 0 means would be a regression. I
> guess just another reason for why we should roll this out step by step,
> with latest platforms first.
>
> Or we shrug and decide to break things like that and redefine the
> backlight semantics a bit. Or well define them properly to begin with :-)

I say it's a new interface, and does not have to follow old interface
semantics. When userspace switches over, it has to adapt. Just shrug off
any "regression" reports where the comparison is against the old
interface.

BR,
Jani.


> -Daniel
>
>> 
>> 
>> BR,
>> Jani.
>> 
>> 
>> 
>> 
>> -- 
>> Jani Nikula, Intel Open Source Graphics Center

-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-27 14:23                       ` Jani Nikula
@ 2022-04-27 14:26                         ` Daniel Vetter
  2022-04-29  8:55                           ` Hans de Goede
  0 siblings, 1 reply; 44+ messages in thread
From: Daniel Vetter @ 2022-04-27 14:26 UTC (permalink / raw)
  To: Jani Nikula
  Cc: Sebastian Wick, Martin Roukala, dri-devel, wayland,
	Hans de Goede, Christoph Grenz, Yusuf Khan

On Wed, Apr 27, 2022 at 05:23:22PM +0300, Jani Nikula wrote:
> On Wed, 27 Apr 2022, Daniel Vetter <daniel@ffwll.ch> wrote:
> > On Thu, Apr 14, 2022 at 01:24:30PM +0300, Jani Nikula wrote:
> >> On Mon, 11 Apr 2022, Alex Deucher <alexdeucher@gmail.com> wrote:
> >> > On Mon, Apr 11, 2022 at 6:18 AM Hans de Goede <hdegoede@redhat.com> wrote:
> >> >>
> >> >> Hi,
> >> >>
> >> >> On 4/8/22 17:11, Alex Deucher wrote:
> >> >> > On Fri, Apr 8, 2022 at 10:56 AM Hans de Goede <hdegoede@redhat.com> wrote:
> >> >> >>
> >> >> >> Hi,
> >> >> >>
> >> >> >> On 4/8/22 16:08, Alex Deucher wrote:
> >> >> >>> On Fri, Apr 8, 2022 at 4:07 AM Daniel Vetter <daniel@ffwll.ch> wrote:
> >> >> >>>>
> >> >> >>>> On Thu, Apr 07, 2022 at 05:05:52PM -0400, Alex Deucher wrote:
> >> >> >>>>> On Thu, Apr 7, 2022 at 1:43 PM Hans de Goede <hdegoede@redhat.com> wrote:
> >> >> >>>>>>
> >> >> >>>>>> Hi Simon,
> >> >> >>>>>>
> >> >> >>>>>> On 4/7/22 18:51, Simon Ser wrote:
> >> >> >>>>>>> Very nice plan! Big +1 for the overall approach.
> >> >> >>>>>>
> >> >> >>>>>> Thanks.
> >> >> >>>>>>
> >> >> >>>>>>> On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
> >> >> >>>>>>>
> >> >> >>>>>>>> The drm_connector brightness properties
> >> >> >>>>>>>> =======================================
> >> >> >>>>>>>>
> >> >> >>>>>>>> bl_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 bl_brightness_max.
> >> >> >>>>>>>
> >> >> >>>>>>> Do we need to split this up into two props for sw/hw state? The privacy screen
> >> >> >>>>>>> stuff needed this, but you're pretty familiar with that. :)
> >> >> >>>>>>
> >> >> >>>>>> Luckily that won't be necessary, since the privacy-screen is a security
> >> >> >>>>>> feature the firmware/embedded-controller may refuse our requests
> >> >> >>>>>> (may temporarily lock-out changes) and/or may make changes without
> >> >> >>>>>> us requesting them itself. Neither is really the case with the
> >> >> >>>>>> brightness setting of displays.
> >> >> >>>>>>
> >> >> >>>>>>>> bl_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 (yet).
> >> >> >>>>>>>
> >> >> >>>>>>> I don't think we actually need that one. Integer KMS props all have a
> >> >> >>>>>>> range which can be fetched via drmModeGetProperty. The max can be
> >> >> >>>>>>> exposed via this range. Example with the existing alpha prop:
> >> >> >>>>>>>
> >> >> >>>>>>>     "alpha": range [0, UINT16_MAX] = 65535
> >> >> >>>>>>
> >> >> >>>>>> Right, I already knew that, which is why I explicitly added a range
> >> >> >>>>>> to the props already. The problem is that the range must be set
> >> >> >>>>>> before registering the connector and when the backlight driver
> >> >> >>>>>> only shows up (much) later during boot then we don't know the
> >> >> >>>>>> range when registering the connector. I guess we could "patch-up"
> >> >> >>>>>> the range later. But AFAIK that would be a bit of abuse of the
> >> >> >>>>>> property API as the range is intended to never change, not
> >> >> >>>>>> even after hotplug uevents. At least atm there is no infra
> >> >> >>>>>> in the kernel to change the range later.
> >> >> >>>>>>
> >> >> >>>>>> Which is why I added an explicit bl_brightness_max property
> >> >> >>>>>> of which the value gives the actual effective maximum of the
> >> >> >>>>>> brightness.
> >> >> >>>>
> >> >> >>>> Uh ... I'm not a huge fan tbh. The thing is, if we allow hotplugging
> >> >> >>>> brightness control later on then we just perpetuate the nonsense we have
> >> >> >>>> right now, forever.
> >> >> >>>>
> >> >> >>>> Imo we should support two kinds of drivers:
> >> >> >>>>
> >> >> >>>> - drivers which are non-crap, and make sure their backlight driver is
> >> >> >>>>   loaded before they register the drm_device (or at least the
> >> >> >>>>   drm_connector). For those we want the drm_connector->backlight pointer
> >> >> >>>>   to bit static over the lifetime of the connector, and then we can also
> >> >> >>>>   set up the brightness range correctly.
> >> >> >>>>
> >> >> >>>> - funny drivers which implement the glorious fallback dance which
> >> >> >>>>   libbacklight implements currently in userspace. Imo for these drivers we
> >> >> >>>>   should have a libbacklight_heuristics_backlight, which normalizes or
> >> >> >>>>   whatever, and is also ways there. And then internally handles the
> >> >> >>>>   fallback mess to the "right" backlight driver.
> >> >> >>>>
> >> >> >>>> We might have some gaps on acpi systems to make sure the drm driver can
> >> >> >>>> wait for the backlight driver to show up, but that's about it.
> >> >> >>>>
> >> >> >>>> Hotplugging random pieces later on is really not how drivers work nowadays
> >> >> >>>> with deferred probe and component framework and all that.
> >> >> >>>>
> >> >> >>>>>> I did consider using the range for this and updating it
> >> >> >>>>>> on the fly I think nothing is really preventing us from
> >> >> >>>>>> doing so, but it very much feels like abusing the generic
> >> >> >>>>>> properties API.
> >> >> >>>>>>
> >> >> >>>>>>>> bl_brightness_0_is_min_brightness: ro, boolean
> >> >> >>>>>>>> When this is set to true then it is safe to set brightness to 0
> >> >> >>>>>>>> without worrying that this completely turns the backlight off causing
> >> >> >>>>>>>> the screen to become unreadable. When this is false setting brightness
> >> >> >>>>>>>> to 0 may turn the backlight off, but this is not guaranteed.
> >> >> >>>>>>>> This will e.g. be true when directly driving a PWM and the video-BIOS
> >> >> >>>>>>>> has provided a minimum (non 0) duty-cycle below which the driver will
> >> >> >>>>>>>> never go.
> >> >> >>>>>>>
> >> >> >>>>>>> Hm. It's quite unfortunate that it's impossible to have strong guarantees
> >> >> >>>>>>> here.
> >> >> >>>>>>>
> >> >> >>>>>>> Is there any way we can avoid this prop?
> >> >> >>>>>>
> >> >> >>>>>> Not really, the problem is that we really don't know if 0 is off
> >> >> >>>>>> or min-brightness. In the given example where we actually never go
> >> >> >>>>>> down to a duty-cycle of 0% because the video BIOS tables tell us
> >> >> >>>>>> not to, we can be certain that setting the brightness prop to 0
> >> >> >>>>>> will not turn of the backlight, since we then set the duty-cycle
> >> >> >>>>>> to the VBT provided minimum. Note the intend here is to only set
> >> >> >>>>>> the boolean to true if the VBT provided minimum is _not_ 0, 0
> >> >> >>>>>> just means the vendor did not bother to provide a minimum.
> >> >> >>>>>>
> >> >> >>>>>> Currently e.g. GNOME never goes lower then something like 5%
> >> >> >>>>>> of brightness_max to avoid accidentally turning the screen off.
> >> >> >>>>>>
> >> >> >>>>>> Turning the screen off is quite bad to do on e.g. tablets where
> >> >> >>>>>> the GUI is the only way to undo the brightness change and now
> >> >> >>>>>> the user can no longer see the GUI.
> >> >> >>>>>>
> >> >> >>>>>> The idea behind this boolean is to give e.g. GNOME a way to
> >> >> >>>>>> know that it is safe to go down to 0% and for it to use
> >> >> >>>>>> the entire range.
> >> >> >>>>>
> >> >> >>>>> Why not just make it policy that 0 is defined as minimum brightness,
> >> >> >>>>> not off, and have all drivers conform to that?
> >> >> >>>>
> >> >> >>>> Because the backlight subsystem isn't as consistent on this, and it's been
> >> >> >>>> an epic source of confusion since forever.
> >> >> >>>>
> >> >> >>>> What's worse, there's both userspace out there which assumes brightness =
> >> >> >>>> 0 is a really fast dpms off _and_ userspace that assumes that brightness =
> >> >> >>>> 0 is the lowest setting. Of course on different sets of machines.
> >> >> >>>>
> >> >> >>>> So yeah we're screwed. I have no idea how to get out of this.
> >> >> >>>
> >> >> >>> Yes, but this is a new API.  So can't we do better?  Sure the old
> >> >> >>> backlight interface is broken, but why carry around clunky workarounds
> >> >> >>> for new interfaces?
> >> >> >>
> >> >> >> Right we certainly need to define the behavior of the new API
> >> >> >> clearly, so that userspace does not misuse / misinterpret it.
> >> >> >>
> >> >> >> The intend is for brightness=0 to mean minimum brightness
> >> >> >> to still be able to see what is on the screen. But the problem
> >> >> >> is that in many cases the GPU driver directly controls a PWM
> >> >> >> output, no minimum PWM value is given in the video BIOS tables
> >> >> >> and actually setting the PWM to 0% dutycycle turns off the
> >> >> >> screen.
> >> >> >
> >> >> > Sure.  So have the GPU driver map 0 to some valid minimum if that is
> >> >> > the case or might be the case.  If bugs come up, we can add quirks in
> >> >> > the GPU drivers.
> >> >>
> >> >> The problem is that when 0% duty-cycle is not off, but minimum
> >> >> brightness because there is some smart backlight-controller involved
> >> >> downstream of the pwm, then of we limit it to say min 5% then we
> >> >> have just limited the range of the brightness. GNOME already does
> >> >> this in userspace now and it is already receiving bug-reports
> >> >> from users that GNOME does not allow the brightness to go as low
> >> >> as they like to have it in a dark(ish) room.
> >> >>
> >> >> And in some cases 5% is likely not enough for the backlight to
> >> >> actually turn on. So it will be wrong in one direction on some
> >> >> devices and wrong in the other direction in other devices.
> >> >>
> >> >> Which means that to satisfy everyone here we will need a ton
> >> >> of quirks, much too many to maintain in the kernel IMHO.
> >> >>
> >> >>
> >> >> >> So we can only promise a best-effort to make brightness=0
> >> >> >> mean minimum brightness, combined with documenting that it
> >> >> >> may turn off the backlight and that userspace _must_ never
> >> >> >> depend on it turning off the backlight.
> >> >> >>
> >> >> >> Also note that setting a direct PWM output to duty-cycle 0%
> >> >> >> does not guarantee that the backlight goes off, this may be
> >> >> >> an input for a special backlight LED driver IC like the
> >> >> >> TI LP855x series which can have an internal lookup
> >> >> >> table causing it to actually output a minimum brightness
> >> >> >> when its PWM input is at 0% dutycycle.  So this is a case
> >> >> >> where we just don't get enough info from the fw/hw to be able
> >> >> >> to offer the guarantees which we would like to guarantee.
> >> >> >
> >> >> > So set it to a level we can guarantee can call it 0.  If we have the
> >> >> > flag we are just punting on the problem in my opinion.
> >> >>
> >> >> Right this an impossible problem to solve so the intent is indeed
> >> >> to punt this to userspace, which IMHO is the best thing we can do
> >> >> here.  The idea behind the "bl_brightness_0_is_min_brightness:
> >> >> ro, boolean" property is to provide a hint to userspace to help
> >> >> userspace deal with this (and if userspace ends up using e.g.
> >> >> systemd's hwdb for this to avoid unnecessary entries in hwdb).
> >> >>
> >> >> >  The kernel
> >> >> > driver would seem to have a better idea what is a valid minimum than
> >> >> > some arbitrary userspace application.
> >> >>
> >> >> If the kernel driver knows the valid minimum then it can make 0
> >> >> actually be that valid minimum as you suggest and it can set the
> >> >> hint flag to let userspace know this. OTOH there are many cases
> >> >> where the kernel's guess is just as bad as userspace's guess and
> >> >> there are too many laptops where this is the case to quirk
> >> >> ourselves out of this situation.
> >> >>
> >> >> > Plus then if we need a
> >> >> > workaround for what is the minimum valid brightness, we can fix it one
> >> >> > place rather than letting every application try and fix it.
> >> >>
> >> >> I wish we could solve this in the kernel, but at least on
> >> >> laptops with Intel integrated gfx many vendors don't bother
> >> >> to put a non 0 value in the minimum duty-cycle field of the
> >> >> VBT, so there really is no good way to solve this.
> >> >
> >> > We have similar issues with AMD platforms.  Some platforms don't
> >> > populate the min value tables, but in the driver we set the minimum
> >> > safe value as the default min value when that happens.  It may not
> >> > always go as low as the platform may be capable of, but at least we
> >> > have consistent behavior and it's all controlled in one place.
> >> >
> >> >>
> >> >> If the userspace folks ever want to do a database for this,
> >> >> I would expect them to do something with hwdb + udev which
> >> >> can then be shared between the different desktop-environments.
> >> >
> >> > So why not do it in the kernel?  At least that way everyone will get
> >> > it the fixes as they happen.  A big user database may or may not
> >> > happen and behavior will be inconsistent across desktop environments
> >> > until that does.  I don't really see any value in having the flag.
> >> > There will be cases where the flag is wrong and will require kernel
> >> > fixes anyway (e.g., OEM switches panel due to supply chain issues and
> >> > forgets to update the vbios, etc.), so why not just define 0 as
> >> > minimum safe backlight value?  If it's too low and flickers or turns
> >> > the backlight off, we quirk it.  If a particular platform can go
> >> > lower, we can quirk it.  If we add the flag then we need to not only
> >> > add quirks for the minimum value, but we also have to deal with quirks
> >> > for when the flag is set wrong.  So now we are maintaining two quirks
> >> > instead of one.
> >> 
> >> Just chiming in, there are certainly plenty of panels and designs where
> >> 0 PWM duty cycle is physically not possible, and thus 0 brightness
> >> simply can't universally mean off.
> >> 
> >> Daniel referred to a case where 0 brightness was used as fast mini dpms
> >> off, and I think it's fundamentally a broken use case. We can't
> >> guarantee to be able to support that. I think the appeal was partly in
> >> being able to do it without access to kms api, quick and dirty via
> >> sysfs.
> >> 
> >> Please let's just make 0 the minimum but not off. If you want off, you
> >> do modeset, and the driver can follow panel timings etc.
> >> 
> >> I think that's also something the kernel can actually guarantee, while
> >> we can't guarantee 0 is off.
> >
> > Yes.
> >
> > The trouble is that we have platforms where it works like this, and so
> > retroactively redefining what brightness 0 means would be a regression. I
> > guess just another reason for why we should roll this out step by step,
> > with latest platforms first.
> >
> > Or we shrug and decide to break things like that and redefine the
> > backlight semantics a bit. Or well define them properly to begin with :-)
> 
> I say it's a new interface, and does not have to follow old interface
> semantics. When userspace switches over, it has to adapt. Just shrug off
> any "regression" reports where the comparison is against the old
> interface.

Not sure we can fix the new interface without changing the old one. Like
when we specifiy that 0 means lowest setting, people will be annoyed when
it's actually off, and then fixing the backlight driver would break the
old stuff.

I'm leaning towards breaking the old stuff a bit and making this clean :-)
The regression is just power usage when you close the lid and stuff like
that, should be ok-ish for these older machines with funny userspace that
doesn't do a dpms off.
-Daniel

> 
> BR,
> Jani.
> 
> 
> > -Daniel
> >
> >> 
> >> 
> >> BR,
> >> Jani.
> >> 
> >> 
> >> 
> >> 
> >> -- 
> >> Jani Nikula, Intel Open Source Graphics Center
> 
> -- 
> Jani Nikula, Intel Open Source Graphics Center

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-27 14:26                         ` Daniel Vetter
@ 2022-04-29  8:55                           ` Hans de Goede
  2022-04-29  8:59                             ` Simon Ser
  0 siblings, 1 reply; 44+ messages in thread
From: Hans de Goede @ 2022-04-29  8:55 UTC (permalink / raw)
  To: Daniel Vetter, Jani Nikula
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

Hi,

On 4/27/22 16:26, Daniel Vetter wrote:
> On Wed, Apr 27, 2022 at 05:23:22PM +0300, Jani Nikula wrote:
>> On Wed, 27 Apr 2022, Daniel Vetter <daniel@ffwll.ch> wrote:
>>> On Thu, Apr 14, 2022 at 01:24:30PM +0300, Jani Nikula wrote:
>>>> On Mon, 11 Apr 2022, Alex Deucher <alexdeucher@gmail.com> wrote:
>>>>> On Mon, Apr 11, 2022 at 6:18 AM Hans de Goede <hdegoede@redhat.com> wrote:
>>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> On 4/8/22 17:11, Alex Deucher wrote:
>>>>>>> On Fri, Apr 8, 2022 at 10:56 AM Hans de Goede <hdegoede@redhat.com> wrote:
>>>>>>>>
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> On 4/8/22 16:08, Alex Deucher wrote:
>>>>>>>>> On Fri, Apr 8, 2022 at 4:07 AM Daniel Vetter <daniel@ffwll.ch> wrote:
>>>>>>>>>>
>>>>>>>>>> On Thu, Apr 07, 2022 at 05:05:52PM -0400, Alex Deucher wrote:
>>>>>>>>>>> On Thu, Apr 7, 2022 at 1:43 PM Hans de Goede <hdegoede@redhat.com> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>> Hi Simon,
>>>>>>>>>>>>
>>>>>>>>>>>> On 4/7/22 18:51, Simon Ser wrote:
>>>>>>>>>>>>> Very nice plan! Big +1 for the overall approach.
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks.
>>>>>>>>>>>>
>>>>>>>>>>>>> On Thursday, April 7th, 2022 at 17:38, Hans de Goede <hdegoede@redhat.com> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> The drm_connector brightness properties
>>>>>>>>>>>>>> =======================================
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> bl_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 bl_brightness_max.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Do we need to split this up into two props for sw/hw state? The privacy screen
>>>>>>>>>>>>> stuff needed this, but you're pretty familiar with that. :)
>>>>>>>>>>>>
>>>>>>>>>>>> Luckily that won't be necessary, since the privacy-screen is a security
>>>>>>>>>>>> feature the firmware/embedded-controller may refuse our requests
>>>>>>>>>>>> (may temporarily lock-out changes) and/or may make changes without
>>>>>>>>>>>> us requesting them itself. Neither is really the case with the
>>>>>>>>>>>> brightness setting of displays.
>>>>>>>>>>>>
>>>>>>>>>>>>>> bl_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 (yet).
>>>>>>>>>>>>>
>>>>>>>>>>>>> I don't think we actually need that one. Integer KMS props all have a
>>>>>>>>>>>>> range which can be fetched via drmModeGetProperty. The max can be
>>>>>>>>>>>>> exposed via this range. Example with the existing alpha prop:
>>>>>>>>>>>>>
>>>>>>>>>>>>>     "alpha": range [0, UINT16_MAX] = 65535
>>>>>>>>>>>>
>>>>>>>>>>>> Right, I already knew that, which is why I explicitly added a range
>>>>>>>>>>>> to the props already. The problem is that the range must be set
>>>>>>>>>>>> before registering the connector and when the backlight driver
>>>>>>>>>>>> only shows up (much) later during boot then we don't know the
>>>>>>>>>>>> range when registering the connector. I guess we could "patch-up"
>>>>>>>>>>>> the range later. But AFAIK that would be a bit of abuse of the
>>>>>>>>>>>> property API as the range is intended to never change, not
>>>>>>>>>>>> even after hotplug uevents. At least atm there is no infra
>>>>>>>>>>>> in the kernel to change the range later.
>>>>>>>>>>>>
>>>>>>>>>>>> Which is why I added an explicit bl_brightness_max property
>>>>>>>>>>>> of which the value gives the actual effective maximum of the
>>>>>>>>>>>> brightness.
>>>>>>>>>>
>>>>>>>>>> Uh ... I'm not a huge fan tbh. The thing is, if we allow hotplugging
>>>>>>>>>> brightness control later on then we just perpetuate the nonsense we have
>>>>>>>>>> right now, forever.
>>>>>>>>>>
>>>>>>>>>> Imo we should support two kinds of drivers:
>>>>>>>>>>
>>>>>>>>>> - drivers which are non-crap, and make sure their backlight driver is
>>>>>>>>>>   loaded before they register the drm_device (or at least the
>>>>>>>>>>   drm_connector). For those we want the drm_connector->backlight pointer
>>>>>>>>>>   to bit static over the lifetime of the connector, and then we can also
>>>>>>>>>>   set up the brightness range correctly.
>>>>>>>>>>
>>>>>>>>>> - funny drivers which implement the glorious fallback dance which
>>>>>>>>>>   libbacklight implements currently in userspace. Imo for these drivers we
>>>>>>>>>>   should have a libbacklight_heuristics_backlight, which normalizes or
>>>>>>>>>>   whatever, and is also ways there. And then internally handles the
>>>>>>>>>>   fallback mess to the "right" backlight driver.
>>>>>>>>>>
>>>>>>>>>> We might have some gaps on acpi systems to make sure the drm driver can
>>>>>>>>>> wait for the backlight driver to show up, but that's about it.
>>>>>>>>>>
>>>>>>>>>> Hotplugging random pieces later on is really not how drivers work nowadays
>>>>>>>>>> with deferred probe and component framework and all that.
>>>>>>>>>>
>>>>>>>>>>>> I did consider using the range for this and updating it
>>>>>>>>>>>> on the fly I think nothing is really preventing us from
>>>>>>>>>>>> doing so, but it very much feels like abusing the generic
>>>>>>>>>>>> properties API.
>>>>>>>>>>>>
>>>>>>>>>>>>>> bl_brightness_0_is_min_brightness: ro, boolean
>>>>>>>>>>>>>> When this is set to true then it is safe to set brightness to 0
>>>>>>>>>>>>>> without worrying that this completely turns the backlight off causing
>>>>>>>>>>>>>> the screen to become unreadable. When this is false setting brightness
>>>>>>>>>>>>>> to 0 may turn the backlight off, but this is not guaranteed.
>>>>>>>>>>>>>> This will e.g. be true when directly driving a PWM and the video-BIOS
>>>>>>>>>>>>>> has provided a minimum (non 0) duty-cycle below which the driver will
>>>>>>>>>>>>>> never go.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Hm. It's quite unfortunate that it's impossible to have strong guarantees
>>>>>>>>>>>>> here.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Is there any way we can avoid this prop?
>>>>>>>>>>>>
>>>>>>>>>>>> Not really, the problem is that we really don't know if 0 is off
>>>>>>>>>>>> or min-brightness. In the given example where we actually never go
>>>>>>>>>>>> down to a duty-cycle of 0% because the video BIOS tables tell us
>>>>>>>>>>>> not to, we can be certain that setting the brightness prop to 0
>>>>>>>>>>>> will not turn of the backlight, since we then set the duty-cycle
>>>>>>>>>>>> to the VBT provided minimum. Note the intend here is to only set
>>>>>>>>>>>> the boolean to true if the VBT provided minimum is _not_ 0, 0
>>>>>>>>>>>> just means the vendor did not bother to provide a minimum.
>>>>>>>>>>>>
>>>>>>>>>>>> Currently e.g. GNOME never goes lower then something like 5%
>>>>>>>>>>>> of brightness_max to avoid accidentally turning the screen off.
>>>>>>>>>>>>
>>>>>>>>>>>> Turning the screen off is quite bad to do on e.g. tablets where
>>>>>>>>>>>> the GUI is the only way to undo the brightness change and now
>>>>>>>>>>>> the user can no longer see the GUI.
>>>>>>>>>>>>
>>>>>>>>>>>> The idea behind this boolean is to give e.g. GNOME a way to
>>>>>>>>>>>> know that it is safe to go down to 0% and for it to use
>>>>>>>>>>>> the entire range.
>>>>>>>>>>>
>>>>>>>>>>> Why not just make it policy that 0 is defined as minimum brightness,
>>>>>>>>>>> not off, and have all drivers conform to that?
>>>>>>>>>>
>>>>>>>>>> Because the backlight subsystem isn't as consistent on this, and it's been
>>>>>>>>>> an epic source of confusion since forever.
>>>>>>>>>>
>>>>>>>>>> What's worse, there's both userspace out there which assumes brightness =
>>>>>>>>>> 0 is a really fast dpms off _and_ userspace that assumes that brightness =
>>>>>>>>>> 0 is the lowest setting. Of course on different sets of machines.
>>>>>>>>>>
>>>>>>>>>> So yeah we're screwed. I have no idea how to get out of this.
>>>>>>>>>
>>>>>>>>> Yes, but this is a new API.  So can't we do better?  Sure the old
>>>>>>>>> backlight interface is broken, but why carry around clunky workarounds
>>>>>>>>> for new interfaces?
>>>>>>>>
>>>>>>>> Right we certainly need to define the behavior of the new API
>>>>>>>> clearly, so that userspace does not misuse / misinterpret it.
>>>>>>>>
>>>>>>>> The intend is for brightness=0 to mean minimum brightness
>>>>>>>> to still be able to see what is on the screen. But the problem
>>>>>>>> is that in many cases the GPU driver directly controls a PWM
>>>>>>>> output, no minimum PWM value is given in the video BIOS tables
>>>>>>>> and actually setting the PWM to 0% dutycycle turns off the
>>>>>>>> screen.
>>>>>>>
>>>>>>> Sure.  So have the GPU driver map 0 to some valid minimum if that is
>>>>>>> the case or might be the case.  If bugs come up, we can add quirks in
>>>>>>> the GPU drivers.
>>>>>>
>>>>>> The problem is that when 0% duty-cycle is not off, but minimum
>>>>>> brightness because there is some smart backlight-controller involved
>>>>>> downstream of the pwm, then of we limit it to say min 5% then we
>>>>>> have just limited the range of the brightness. GNOME already does
>>>>>> this in userspace now and it is already receiving bug-reports
>>>>>> from users that GNOME does not allow the brightness to go as low
>>>>>> as they like to have it in a dark(ish) room.
>>>>>>
>>>>>> And in some cases 5% is likely not enough for the backlight to
>>>>>> actually turn on. So it will be wrong in one direction on some
>>>>>> devices and wrong in the other direction in other devices.
>>>>>>
>>>>>> Which means that to satisfy everyone here we will need a ton
>>>>>> of quirks, much too many to maintain in the kernel IMHO.
>>>>>>
>>>>>>
>>>>>>>> So we can only promise a best-effort to make brightness=0
>>>>>>>> mean minimum brightness, combined with documenting that it
>>>>>>>> may turn off the backlight and that userspace _must_ never
>>>>>>>> depend on it turning off the backlight.
>>>>>>>>
>>>>>>>> Also note that setting a direct PWM output to duty-cycle 0%
>>>>>>>> does not guarantee that the backlight goes off, this may be
>>>>>>>> an input for a special backlight LED driver IC like the
>>>>>>>> TI LP855x series which can have an internal lookup
>>>>>>>> table causing it to actually output a minimum brightness
>>>>>>>> when its PWM input is at 0% dutycycle.  So this is a case
>>>>>>>> where we just don't get enough info from the fw/hw to be able
>>>>>>>> to offer the guarantees which we would like to guarantee.
>>>>>>>
>>>>>>> So set it to a level we can guarantee can call it 0.  If we have the
>>>>>>> flag we are just punting on the problem in my opinion.
>>>>>>
>>>>>> Right this an impossible problem to solve so the intent is indeed
>>>>>> to punt this to userspace, which IMHO is the best thing we can do
>>>>>> here.  The idea behind the "bl_brightness_0_is_min_brightness:
>>>>>> ro, boolean" property is to provide a hint to userspace to help
>>>>>> userspace deal with this (and if userspace ends up using e.g.
>>>>>> systemd's hwdb for this to avoid unnecessary entries in hwdb).
>>>>>>
>>>>>>>  The kernel
>>>>>>> driver would seem to have a better idea what is a valid minimum than
>>>>>>> some arbitrary userspace application.
>>>>>>
>>>>>> If the kernel driver knows the valid minimum then it can make 0
>>>>>> actually be that valid minimum as you suggest and it can set the
>>>>>> hint flag to let userspace know this. OTOH there are many cases
>>>>>> where the kernel's guess is just as bad as userspace's guess and
>>>>>> there are too many laptops where this is the case to quirk
>>>>>> ourselves out of this situation.
>>>>>>
>>>>>>> Plus then if we need a
>>>>>>> workaround for what is the minimum valid brightness, we can fix it one
>>>>>>> place rather than letting every application try and fix it.
>>>>>>
>>>>>> I wish we could solve this in the kernel, but at least on
>>>>>> laptops with Intel integrated gfx many vendors don't bother
>>>>>> to put a non 0 value in the minimum duty-cycle field of the
>>>>>> VBT, so there really is no good way to solve this.
>>>>>
>>>>> We have similar issues with AMD platforms.  Some platforms don't
>>>>> populate the min value tables, but in the driver we set the minimum
>>>>> safe value as the default min value when that happens.  It may not
>>>>> always go as low as the platform may be capable of, but at least we
>>>>> have consistent behavior and it's all controlled in one place.
>>>>>
>>>>>>
>>>>>> If the userspace folks ever want to do a database for this,
>>>>>> I would expect them to do something with hwdb + udev which
>>>>>> can then be shared between the different desktop-environments.
>>>>>
>>>>> So why not do it in the kernel?  At least that way everyone will get
>>>>> it the fixes as they happen.  A big user database may or may not
>>>>> happen and behavior will be inconsistent across desktop environments
>>>>> until that does.  I don't really see any value in having the flag.
>>>>> There will be cases where the flag is wrong and will require kernel
>>>>> fixes anyway (e.g., OEM switches panel due to supply chain issues and
>>>>> forgets to update the vbios, etc.), so why not just define 0 as
>>>>> minimum safe backlight value?  If it's too low and flickers or turns
>>>>> the backlight off, we quirk it.  If a particular platform can go
>>>>> lower, we can quirk it.  If we add the flag then we need to not only
>>>>> add quirks for the minimum value, but we also have to deal with quirks
>>>>> for when the flag is set wrong.  So now we are maintaining two quirks
>>>>> instead of one.
>>>>
>>>> Just chiming in, there are certainly plenty of panels and designs where
>>>> 0 PWM duty cycle is physically not possible, and thus 0 brightness
>>>> simply can't universally mean off.
>>>>
>>>> Daniel referred to a case where 0 brightness was used as fast mini dpms
>>>> off, and I think it's fundamentally a broken use case. We can't
>>>> guarantee to be able to support that. I think the appeal was partly in
>>>> being able to do it without access to kms api, quick and dirty via
>>>> sysfs.
>>>>
>>>> Please let's just make 0 the minimum but not off. If you want off, you
>>>> do modeset, and the driver can follow panel timings etc.
>>>>
>>>> I think that's also something the kernel can actually guarantee, while
>>>> we can't guarantee 0 is off.
>>>
>>> Yes.
>>>
>>> The trouble is that we have platforms where it works like this, and so
>>> retroactively redefining what brightness 0 means would be a regression. I
>>> guess just another reason for why we should roll this out step by step,
>>> with latest platforms first.
>>>
>>> Or we shrug and decide to break things like that and redefine the
>>> backlight semantics a bit. Or well define them properly to begin with :-)
>>
>> I say it's a new interface, and does not have to follow old interface
>> semantics. When userspace switches over, it has to adapt. Just shrug off
>> any "regression" reports where the comparison is against the old
>> interface.
> 
> Not sure we can fix the new interface without changing the old one. Like
> when we specifiy that 0 means lowest setting, people will be annoyed when
> it's actually off, and then fixing the backlight driver would break the
> old stuff.

I believe that we can fix the new interface, the plan is for there
to be some helper code to proxy the new connector properties to what
is still a good old backlight-device internally in the kernel,.

This proxy-ing code could take a minimum value below which it should
not go when things are set through the properties and then if e.g.
the /sys/class/backlight interface offers range of 0-65535 and the
kms driver asks the proxying helper for a minimum of 500, show this
as 0-65035 on the property, simply adding 500 before sending the
value to the backlight-device on writes (and subtracting 500 on reads,
clamping to 0 as lowest value reported on reads).

This way apps using the new API can never go below 500 (in this
example) and for old API users nothing changes.

Given that Jani seems to be in favor of enforcing some minimal value
inside the i915 code going forward and also what Alex said that the
amdgpu code already enforces its own minimum if the video BIOS tables
don't provide one, it seems that there is consensus that we want 0
to mean minimum brightness at which the screen is still somewhat
readable and that we want to enforce this at the kernel level.

Which also means the weird hint property which I came up with won't
be necessary as we now have a clean definition of what brightness
0 is supposed to mean (in the new API) and any cases where this is not
the case are kernel bugs and should be fixed in the kernel.

Regards,

Hans


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-29  8:55                           ` Hans de Goede
@ 2022-04-29  8:59                             ` Simon Ser
  2022-04-29  9:06                               ` Pekka Paalanen
  0 siblings, 1 reply; 44+ messages in thread
From: Simon Ser @ 2022-04-29  8:59 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Sebastian Wick, dri-devel, Martin Roukala, Christoph Grenz,
	wayland, Yusuf Khan

On Friday, April 29th, 2022 at 10:55, Hans de Goede <hdegoede@redhat.com> wrote:

> I believe that we can fix the new interface, the plan is for there
> to be some helper code to proxy the new connector properties to what
> is still a good old backlight-device internally in the kernel,.
>
> This proxy-ing code could take a minimum value below which it should
> not go when things are set through the properties and then if e.g.
> the /sys/class/backlight interface offers range of 0-65535 and the
> kms driver asks the proxying helper for a minimum of 500, show this
> as 0-65035 on the property, simply adding 500 before sending the
> value to the backlight-device on writes (and subtracting 500 on reads,
> clamping to 0 as lowest value reported on reads).
>
> This way apps using the new API can never go below 500 (in this
> example) and for old API users nothing changes.
>
> Given that Jani seems to be in favor of enforcing some minimal value
> inside the i915 code going forward and also what Alex said that the
> amdgpu code already enforces its own minimum if the video BIOS tables
> don't provide one, it seems that there is consensus that we want 0
> to mean minimum brightness at which the screen is still somewhat
> readable and that we want to enforce this at the kernel level.
>
> Which also means the weird hint property which I came up with won't
> be necessary as we now have a clean definition of what brightness
> 0 is supposed to mean (in the new API) and any cases where this is not
> the case are kernel bugs and should be fixed in the kernel.

Looks like a good approach to me from user-space PoV!

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-29  8:59                             ` Simon Ser
@ 2022-04-29  9:06                               ` Pekka Paalanen
  2022-04-29  9:49                                 ` Lattannavar, Sameer
  0 siblings, 1 reply; 44+ messages in thread
From: Pekka Paalanen @ 2022-04-29  9:06 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

[-- Attachment #1: Type: text/plain, Size: 1822 bytes --]

On Fri, 29 Apr 2022 08:59:24 +0000
Simon Ser <contact@emersion.fr> wrote:

> On Friday, April 29th, 2022 at 10:55, Hans de Goede <hdegoede@redhat.com> wrote:
> 
> > I believe that we can fix the new interface, the plan is for there
> > to be some helper code to proxy the new connector properties to what
> > is still a good old backlight-device internally in the kernel,.
> >
> > This proxy-ing code could take a minimum value below which it should
> > not go when things are set through the properties and then if e.g.
> > the /sys/class/backlight interface offers range of 0-65535 and the
> > kms driver asks the proxying helper for a minimum of 500, show this
> > as 0-65035 on the property, simply adding 500 before sending the
> > value to the backlight-device on writes (and subtracting 500 on reads,
> > clamping to 0 as lowest value reported on reads).
> >
> > This way apps using the new API can never go below 500 (in this
> > example) and for old API users nothing changes.
> >
> > Given that Jani seems to be in favor of enforcing some minimal value
> > inside the i915 code going forward and also what Alex said that the
> > amdgpu code already enforces its own minimum if the video BIOS tables
> > don't provide one, it seems that there is consensus that we want 0
> > to mean minimum brightness at which the screen is still somewhat
> > readable and that we want to enforce this at the kernel level.
> >
> > Which also means the weird hint property which I came up with won't
> > be necessary as we now have a clean definition of what brightness
> > 0 is supposed to mean (in the new API) and any cases where this is not
> > the case are kernel bugs and should be fixed in the kernel.  
> 
> Looks like a good approach to me from user-space PoV!

Yes!


Thanks,
pq


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 44+ messages in thread

* RE: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-29  9:06                               ` Pekka Paalanen
@ 2022-04-29  9:49                                 ` Lattannavar, Sameer
  0 siblings, 0 replies; 44+ messages in thread
From: Lattannavar, Sameer @ 2022-04-29  9:49 UTC (permalink / raw)
  To: Pekka Paalanen, Hans de Goede
  Cc: Sebastian Wick, Martin Roukala, dri-devel, wayland,
	Christoph Grenz, Yusuf Khan

Yes  we would need this.
-Sameer

-----Original Message-----
From: wayland-devel <wayland-devel-bounces@lists.freedesktop.org> On Behalf Of Pekka Paalanen
Sent: Friday, April 29, 2022 2:37 PM
To: Hans de Goede <hdegoede@redhat.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>; Sebastian Wick <sebastian.wick@redhat.com>; Martin Roukala <martin.roukala@mupuf.org>; Christoph Grenz <christophg+lkml@grenz-bonn.de>; wayland <wayland-devel@lists.freedesktop.org>; dri-devel@lists.freedesktop.org; Daniel Vetter <daniel@ffwll.ch>; Alex Deucher <alexdeucher@gmail.com>; Yusuf Khan <yusisamerican@gmail.com>
Subject: Re: [RFC] drm/kms: control display brightness through drm_connector properties

On Fri, 29 Apr 2022 08:59:24 +0000
Simon Ser <contact@emersion.fr> wrote:

> On Friday, April 29th, 2022 at 10:55, Hans de Goede <hdegoede@redhat.com> wrote:
> 
> > I believe that we can fix the new interface, the plan is for there 
> > to be some helper code to proxy the new connector properties to what 
> > is still a good old backlight-device internally in the kernel,.
> >
> > This proxy-ing code could take a minimum value below which it should 
> > not go when things are set through the properties and then if e.g.
> > the /sys/class/backlight interface offers range of 0-65535 and the 
> > kms driver asks the proxying helper for a minimum of 500, show this 
> > as 0-65035 on the property, simply adding 500 before sending the 
> > value to the backlight-device on writes (and subtracting 500 on 
> > reads, clamping to 0 as lowest value reported on reads).
> >
> > This way apps using the new API can never go below 500 (in this
> > example) and for old API users nothing changes.
> >
> > Given that Jani seems to be in favor of enforcing some minimal value 
> > inside the i915 code going forward and also what Alex said that the 
> > amdgpu code already enforces its own minimum if the video BIOS 
> > tables don't provide one, it seems that there is consensus that we 
> > want 0 to mean minimum brightness at which the screen is still 
> > somewhat readable and that we want to enforce this at the kernel level.
> >
> > Which also means the weird hint property which I came up with won't 
> > be necessary as we now have a clean definition of what brightness
> > 0 is supposed to mean (in the new API) and any cases where this is 
> > not the case are kernel bugs and should be fixed in the kernel.
> 
> Looks like a good approach to me from user-space PoV!

Yes!


Thanks,
pq


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-14 13:10 ` Jani Nikula
@ 2022-05-18 12:59   ` Hans de Goede
  2022-05-18 14:23     ` Jani Nikula
  2022-05-18 14:40     ` Ville Syrjälä
  0 siblings, 2 replies; 44+ messages in thread
From: Hans de Goede @ 2022-05-18 12:59 UTC (permalink / raw)
  To: Jani Nikula, dri-devel, wayland
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, Yusuf Khan

Hi,

On 4/14/22 15:10, Jani Nikula wrote:
> On Thu, 07 Apr 2022, Hans de Goede <hdegoede@redhat.com> wrote:
>> 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.
>>
>> 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.
>>
>>
>> What scale to use for the drm_connector bl_brightness property?
>> ===============================================================
>>
>> The tricky part of this plan is phase 2 and then esp. defining what the
>> new brightness properties will look like and how they will work.
>>
>> The biggest challenge here is to decide on a fixed scale for the main
>> brightness property, say 0-65535, using scaling where the actual hw scale
>> is different, or if this should simply be a 1:1 mirror of the current
>> backlight interface, with the actual hw scale / brightness_max value
>> exposed as a drm_connector property.
>>
>> 1:1 advantages / 0-65535 disadvantages
>> - Userspace will likely move over to the connector-props quite slowly and
>>   we can expect various userspace bits, esp. also custom user scripts, to
>>   keep using the old uAPI for a long time. Using the 2 APIs are intermixed
>>   is fine when using a 1:1 brightness scale mapping. But if we end up doing
>>   a scaling round-trip all the time then eventually the brightness is going
>>   do drift. This can even happen if the user never changes the brightness
>>   when userspace saves it over suspend/resume or reboots.
>> - Almost all laptops have brightness up/down hotkeys. E.g GNOME decides
>>   on a step size for the hotkeys by doing min(brightness_max/20, 1).
>>   Some of the vendor specific backlight fw APIs (e.g. dell-laptop) have
>>   only 8 steps. When giving userspace the actual max_brightness value, then
>>   this will all work just fine. When hardcode brightness_max to 65535 OTOH
>>   then in this case GNOME will still give the user 20 steps where only 1
>>   in every 2-3 steps actually changes the brightness which IMHO is
>>   an unacceptably bad user experience.
>>
>> 0-65535 advantages / 1:1 disadvantages
>> - Without a fixed scale for the brightness property the brightness_max
>>   value may change after an userspace application's initial enumeration
>>   of the drm_connector. This can happen when neither the native GPU nor
>>   the acpi_video backlight devices are present/usable in this case
>>   acpi_video_get_backlight_type() will _assume_ a vendor specific fw API
>>   will be used for backlight control and the driver proving the "vendor"
>>   backlight device will show up much later and may even never show-up,
>>   so waiting for it is not an option. With a fixed 0-65535 scale userspace
>>   can just always assume this and the drm_connector backlight props helper
>>   code can even cache writes and send it to the actual backlight device
>>   when it shows up. With a 1:1 mapping userspace needs to listen for
>>   a uevent and then update the brightness range on such an event.
>>
>> I believe that the 1:1 mapping advantages out way the disadvantages
>> here. Also note that current userspace already blindly assumes that
>> all relevant drivers are loaded before the graphical-environment
>> starts and all the desktop environments as such already only do
>> a single scan of /sys/class/backlight when they start. So when
>> userspace forgets to add code to listen for the uevent when switching
>> to the new API nothing changes; and with the uevent userspace actually
>> gets a good mechanism to detect backlight drivers loading after
>> the graphical-environment has already started.
>>
>> So based on this here is my proposal for a set of new brightness
>> properties on the drm_connector object. Note these are all prefixed with
>> bl which stands for backlight, which is technically not correct for OLED.
>> But we need a prefix to avoid a name collision with the "brightness"
>> attribute which is part of the existing TV specific properties and IMHO
>> it is good to have a common prefix to make it clear that these all
>> belong together.
>>
>>
>> The drm_connector brightness properties
>> =======================================
>>
>> bl_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 bl_brightness_max.
>>
>> bl_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 (yet).
>>
>> bl_brightness_0_is_min_brightness: ro, boolean
>> When this is set to true then it is safe to set brightness to 0
>> without worrying that this completely turns the backlight off causing
>> the screen to become unreadable. When this is false setting brightness
>> to 0 may turn the backlight off, but this is _not_ guaranteed.
>> This will e.g. be true when directly driving a PWM and the video-BIOS
>> has provided a minimum (non 0) duty-cycle below which the driver will
>> never go.
>>
>> bl_brightness_control_method: ro, enum, possible values:
>> none:     The GPU driver expects brightness control to be provided by another
>>           driver and that driver has not loaded yet.
>> unknown:  The underlying control mechanism is unknown.
>> pwm:      The brightness property directly controls the duty-cycle of a PWM
>>           output.
>> firmware: The brightness is controlled through firmware calls.
>> DDC/CI:   The brightness is controlled through the DDC/CI protocol.
>> gmux:     The brightness is controlled by the GMUX.
>> Note this enum may be extended in the future, so other values may
>> be read, these should be treated as "unknown".
> 
> Some eDP panels support brightness control via DPCD, in complex
> ways. Some of them support mixed modes via both DPCD and PWM
> simultaneously. Some of them support luminance based control.
> 
> DSI command mode panels support brightness control via DCS commands.

Right the whole bl_brightness_control_method is a bad idea and
I'll drop for the actual implementation of this.

> 
>> When brightness control becomes available after being reported
>> as not available before (bl_brightness_control_method=="none")
>> a uevent with CONNECTOR=<connector-id> and
>> PROPERTY=<bl_brightness_control_method-id> will be generated
>> at this point all the properties must be re-read.
>>
>> When/once brightness control is available then all the read-only
>> properties are fixed and will never change.
>>
>> Besides the "none" value for no driver having loaded yet,
>> the different bl_brightness_control_method values are intended for
>> (userspace) heuristics for such things as the brightness setting
>> linearly controlling electrical power or setting perceived brightness.
> 
> I'm not sure if it's a good idea to expose this with the goal that it's
> to be used for heuristics. We usually don't even know if we're
> controlling actual backlight brightness or just the OLED
> brightness. Basically any of the methods could be used to control OLED,
> or some HDR display with luminance based controls, and the heuristics
> would be off.

Ack, as said I plan to drop both the bl_brightness_0_is_min_brightness
(discussed elsewhere in the thread) and bl_brightness_control_method
properties, leaving just bl_brightness + bl_brightness_max.

> There are some cases where we can actually get a rough PWM/luminance
> curve from i915 opregion. I think maybe 16 data points. We've never
> exposed that. My idea was that you'd have a property where you could add
> data points for the curve, it could get pre-populated by the kernel if
> the kernel knows how to do it, defaulting to linear, but it could also
> be set or adjusted by userspace. The point would be that the userspace
> adjusts brightness linearly, and the kernel would use the curve data
> points to adjust it non-linearly. The userspace could have completely
> separated brightness adjustment and curve adjustment, and the brightness
> adjustment would be dead simple.

Interesting, I guess this could be a future feature addition on top
of my work.

> Finally, I'd drop "backlight" as a term throughout. It's brightness
> we're setting, and backlight is just a panel implementation detail.

Right, I'm fine with dropping backlight, but we do need a prefix
for the brightness property because there already is a plain
"brightness" property which is part of the existing TV specific
properties.

So how about: display_brightness or panel_brightness ?

I'm not sure which one I like better myself...

Regards,

Hans


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-05-18 12:59   ` Hans de Goede
@ 2022-05-18 14:23     ` Jani Nikula
  2022-05-31 10:40       ` Hans de Goede
  2022-05-18 14:40     ` Ville Syrjälä
  1 sibling, 1 reply; 44+ messages in thread
From: Jani Nikula @ 2022-05-18 14:23 UTC (permalink / raw)
  To: Hans de Goede, dri-devel, wayland
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, Yusuf Khan

On Wed, 18 May 2022, Hans de Goede <hdegoede@redhat.com> wrote:
> So how about: display_brightness or panel_brightness ?

This is a prime opportunity to look at all the existing properties, and
come up with a new combination of capitalization, spacing, hyphens,
underscores, etc. to accompany the total lack of unification we
currently have. DisPLay_brIgh7ne55. :p

I think "display_brightness" is probably fine.


BR,
Jani.


-- 
Jani Nikula, Intel Open Source Graphics Center

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-05-18 12:59   ` Hans de Goede
  2022-05-18 14:23     ` Jani Nikula
@ 2022-05-18 14:40     ` Ville Syrjälä
  1 sibling, 0 replies; 44+ messages in thread
From: Ville Syrjälä @ 2022-05-18 14:40 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, wayland,
	dri-devel, Yusuf Khan

On Wed, May 18, 2022 at 02:59:58PM +0200, Hans de Goede wrote:
> Hi,
> 
> On 4/14/22 15:10, Jani Nikula wrote:
> > There are some cases where we can actually get a rough PWM/luminance
> > curve from i915 opregion. I think maybe 16 data points. We've never
> > exposed that. My idea was that you'd have a property where you could add
> > data points for the curve, it could get pre-populated by the kernel if
> > the kernel knows how to do it, defaulting to linear, but it could also
> > be set or adjusted by userspace. The point would be that the userspace
> > adjusts brightness linearly, and the kernel would use the curve data
> > points to adjust it non-linearly. The userspace could have completely
> > separated brightness adjustment and curve adjustment, and the brightness
> > adjustment would be dead simple.
> 
> Interesting, I guess this could be a future feature addition on top
> of my work.

Here's an outdated branch:
https://github.com/vsyrjala/linux/commits/blcm_backlight

Wrote that some years ago after getting fed up with the useless
non-linear respose of the brightness up/down buttons on my laptop.
Been running it ever since.

-- 
Ville Syrjälä
Intel

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-05-18 14:23     ` Jani Nikula
@ 2022-05-31 10:40       ` Hans de Goede
  0 siblings, 0 replies; 44+ messages in thread
From: Hans de Goede @ 2022-05-31 10:40 UTC (permalink / raw)
  To: Jani Nikula, dri-devel, wayland
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, Yusuf Khan

Hi,

On 5/18/22 16:23, Jani Nikula wrote:
> On Wed, 18 May 2022, Hans de Goede <hdegoede@redhat.com> wrote:
>> So how about: display_brightness or panel_brightness ?
> 
> This is a prime opportunity to look at all the existing properties, and
> come up with a new combination of capitalization, spacing, hyphens,
> underscores, etc. to accompany the total lack of unification we
> currently have. DisPLay_brIgh7ne55. :p
> 
> I think "display_brightness" is probably fine.

Interesting remark about the use of space/_/- I checked drm_connector.c
and most properties use all lower case with spaces so to try and be consistent,
I'll replace the _ with a space.

I guess it is time for me to create a v2 of this proposal.

Regards,

Hans


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-04-07 15:38 [RFC] drm/kms: control display brightness through drm_connector properties Hans de Goede
                   ` (2 preceding siblings ...)
  2022-04-14 13:10 ` Jani Nikula
@ 2022-08-24  2:18 ` Yusuf Khan
  2022-08-25  8:27   ` Hans de Goede
  3 siblings, 1 reply; 44+ messages in thread
From: Yusuf Khan @ 2022-08-24  2:18 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, dri-devel, wayland

[-- Attachment #1: Type: text/plain, Size: 11803 bytes --]

Sorry for the necro-bump, I hadnt seen this go by

My main concern with this proposal is the phasing out of
/sys/class/backlight/.
Currently on the user(user, not userland) level its easier for me to just
modify
the file and be done with it. xbacklight doesnt tell me when its failed,
brightnessctl doesnt make assumptions about what device is what, and
other brightness setting applications ive seen are much worse than them.
Someone needs to create a userland application thats less inconvenient
than `echo`ing into /sys/class/backlight with a name that human beings can
actually remember before I stop using the sysfs, perhaps "setbrightness"
could be the binary's name? Also I dont think its wise to disable or make it
read only though Kconfig as older apps may depend on it, maybe add a
kernel param that disables the old interface so bigger distros can pressure
app makers into changing the interface? As a big draw for DDC/CI is that
many displays support it as a way to change brightness(even if you arent
doing anything special that would break the old interface) perhaps it could
be an early adopter to that kernel parameter?

On Thu, Apr 7, 2022 at 10:39 AM Hans de Goede <hdegoede@redhat.com> wrote:

> 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.
>
> 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.
>
>
> What scale to use for the drm_connector bl_brightness property?
> ===============================================================
>
> The tricky part of this plan is phase 2 and then esp. defining what the
> new brightness properties will look like and how they will work.
>
> The biggest challenge here is to decide on a fixed scale for the main
> brightness property, say 0-65535, using scaling where the actual hw scale
> is different, or if this should simply be a 1:1 mirror of the current
> backlight interface, with the actual hw scale / brightness_max value
> exposed as a drm_connector property.
>
> 1:1 advantages / 0-65535 disadvantages
> - Userspace will likely move over to the connector-props quite slowly and
>   we can expect various userspace bits, esp. also custom user scripts, to
>   keep using the old uAPI for a long time. Using the 2 APIs are intermixed
>   is fine when using a 1:1 brightness scale mapping. But if we end up doing
>   a scaling round-trip all the time then eventually the brightness is going
>   do drift. This can even happen if the user never changes the brightness
>   when userspace saves it over suspend/resume or reboots.
> - Almost all laptops have brightness up/down hotkeys. E.g GNOME decides
>   on a step size for the hotkeys by doing min(brightness_max/20, 1).
>   Some of the vendor specific backlight fw APIs (e.g. dell-laptop) have
>   only 8 steps. When giving userspace the actual max_brightness value, then
>   this will all work just fine. When hardcode brightness_max to 65535 OTOH
>   then in this case GNOME will still give the user 20 steps where only 1
>   in every 2-3 steps actually changes the brightness which IMHO is
>   an unacceptably bad user experience.
>
> 0-65535 advantages / 1:1 disadvantages
> - Without a fixed scale for the brightness property the brightness_max
>   value may change after an userspace application's initial enumeration
>   of the drm_connector. This can happen when neither the native GPU nor
>   the acpi_video backlight devices are present/usable in this case
>   acpi_video_get_backlight_type() will _assume_ a vendor specific fw API
>   will be used for backlight control and the driver proving the "vendor"
>   backlight device will show up much later and may even never show-up,
>   so waiting for it is not an option. With a fixed 0-65535 scale userspace
>   can just always assume this and the drm_connector backlight props helper
>   code can even cache writes and send it to the actual backlight device
>   when it shows up. With a 1:1 mapping userspace needs to listen for
>   a uevent and then update the brightness range on such an event.
>
> I believe that the 1:1 mapping advantages out way the disadvantages
> here. Also note that current userspace already blindly assumes that
> all relevant drivers are loaded before the graphical-environment
> starts and all the desktop environments as such already only do
> a single scan of /sys/class/backlight when they start. So when
> userspace forgets to add code to listen for the uevent when switching
> to the new API nothing changes; and with the uevent userspace actually
> gets a good mechanism to detect backlight drivers loading after
> the graphical-environment has already started.
>
> So based on this here is my proposal for a set of new brightness
> properties on the drm_connector object. Note these are all prefixed with
> bl which stands for backlight, which is technically not correct for OLED.
> But we need a prefix to avoid a name collision with the "brightness"
> attribute which is part of the existing TV specific properties and IMHO
> it is good to have a common prefix to make it clear that these all
> belong together.
>
>
> The drm_connector brightness properties
> =======================================
>
> bl_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 bl_brightness_max.
>
> bl_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 (yet).
>
> bl_brightness_0_is_min_brightness: ro, boolean
> When this is set to true then it is safe to set brightness to 0
> without worrying that this completely turns the backlight off causing
> the screen to become unreadable. When this is false setting brightness
> to 0 may turn the backlight off, but this is _not_ guaranteed.
> This will e.g. be true when directly driving a PWM and the video-BIOS
> has provided a minimum (non 0) duty-cycle below which the driver will
> never go.
>
> bl_brightness_control_method: ro, enum, possible values:
> none:     The GPU driver expects brightness control to be provided by
> another
>           driver and that driver has not loaded yet.
> unknown:  The underlying control mechanism is unknown.
> pwm:      The brightness property directly controls the duty-cycle of a PWM
>           output.
> firmware: The brightness is controlled through firmware calls.
> DDC/CI:   The brightness is controlled through the DDC/CI protocol.
> gmux:     The brightness is controlled by the GMUX.
> Note this enum may be extended in the future, so other values may
> be read, these should be treated as "unknown".
>
> When brightness control becomes available after being reported
> as not available before (bl_brightness_control_method=="none")
> a uevent with CONNECTOR=<connector-id> and
> PROPERTY=<bl_brightness_control_method-id> will be generated
> at this point all the properties must be re-read.
>
> When/once brightness control is available then all the read-only
> properties are fixed and will never change.
>
> Besides the "none" value for no driver having loaded yet,
> the different bl_brightness_control_method values are intended for
> (userspace) heuristics for such things as the brightness setting
> linearly controlling electrical power or setting perceived brightness.
>
> 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
>
>

[-- Attachment #2: Type: text/html, Size: 13921 bytes --]

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-08-24  2:18 ` Yusuf Khan
@ 2022-08-25  8:27   ` Hans de Goede
  2022-08-25 21:40     ` Yusuf Khan
  0 siblings, 1 reply; 44+ messages in thread
From: Hans de Goede @ 2022-08-25  8:27 UTC (permalink / raw)
  To: Yusuf Khan
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, dri-devel, wayland

Hi Yusuf,

On 8/24/22 04:18, Yusuf Khan wrote:
> Sorry for the necro-bump, I hadnt seen this go by

No problem.

> My main concern with this proposal is the phasing out of /sys/class/backlight/.
> Currently on the user(user, not userland) level its easier for me to just modify
> the file and be done with it. xbacklight doesnt tell me when its failed,
> brightnessctl doesnt make assumptions about what device is what, and
> other brightness setting applications ive seen are much worse than them.
> Someone needs to create a userland application thats less inconvenient
> than `echo`ing into /sys/class/backlight with a name that human beings can
> actually remember before I stop using the sysfs, perhaps "setbrightness"
> could be the binary's name? Also I dont think its wise to disable or make it
> read only though Kconfig as older apps may depend on it, maybe add a
> kernel param that disables the old interface so bigger distros can pressure
> app makers into changing the interface? As a big draw for DDC/CI is that
> many displays support it as a way to change brightness(even if you arent
> doing anything special that would break the old interface) perhaps it could
> be an early adopter to that kernel parameter?

Right, so deprecating the /sys/class/backlight API definitely is the last
step and probably is years away. As you say hiding / making it read-only
should probably be a kernel-parameter at first, with maybe a Kconfig
option to set the default. So the depcration would go like this:

1. Add:
A kernel-parameter to allow hiding or read-only-ing the sysfs interface +
Kconfig to select the default +
dev_warn_once() when the old API is used

2. (much later) Drop the Kconfig option and default to hiding/read-only

3. (even later) Maybe completely remove the sysfs interface?

Note the hiding vs read-only thing is to be decided. ATM I'm rather more
focused on getting the new API in place then on deprecating the old one :)

Anyways I fully agree that we need to do the deprecation carefully and
slowly. This is likely going to take multiple years and then some ...

Regards,

Hans



> 
> On Thu, Apr 7, 2022 at 10:39 AM Hans de Goede <hdegoede@redhat.com <mailto:hdegoede@redhat.com>> wrote:
> 
>     As discussed already several times in the past:
>      https://www.x.org/wiki/Events/XDC2014/XDC2014GoedeBacklight/ <https://www.x.org/wiki/Events/XDC2014/XDC2014GoedeBacklight/>
>      https://lore.kernel.org/all/4b17ba08-39f3-57dd-5aad-d37d844b02c6@linux.intel.com/ <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.
> 
>     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 <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.
> 
> 
>     What scale to use for the drm_connector bl_brightness property?
>     ===============================================================
> 
>     The tricky part of this plan is phase 2 and then esp. defining what the
>     new brightness properties will look like and how they will work.
> 
>     The biggest challenge here is to decide on a fixed scale for the main
>     brightness property, say 0-65535, using scaling where the actual hw scale
>     is different, or if this should simply be a 1:1 mirror of the current
>     backlight interface, with the actual hw scale / brightness_max value
>     exposed as a drm_connector property.
> 
>     1:1 advantages / 0-65535 disadvantages
>     - Userspace will likely move over to the connector-props quite slowly and
>       we can expect various userspace bits, esp. also custom user scripts, to
>       keep using the old uAPI for a long time. Using the 2 APIs are intermixed
>       is fine when using a 1:1 brightness scale mapping. But if we end up doing
>       a scaling round-trip all the time then eventually the brightness is going
>       do drift. This can even happen if the user never changes the brightness
>       when userspace saves it over suspend/resume or reboots.
>     - Almost all laptops have brightness up/down hotkeys. E.g GNOME decides
>       on a step size for the hotkeys by doing min(brightness_max/20, 1).
>       Some of the vendor specific backlight fw APIs (e.g. dell-laptop) have
>       only 8 steps. When giving userspace the actual max_brightness value, then
>       this will all work just fine. When hardcode brightness_max to 65535 OTOH
>       then in this case GNOME will still give the user 20 steps where only 1
>       in every 2-3 steps actually changes the brightness which IMHO is
>       an unacceptably bad user experience.
> 
>     0-65535 advantages / 1:1 disadvantages
>     - Without a fixed scale for the brightness property the brightness_max
>       value may change after an userspace application's initial enumeration
>       of the drm_connector. This can happen when neither the native GPU nor
>       the acpi_video backlight devices are present/usable in this case
>       acpi_video_get_backlight_type() will _assume_ a vendor specific fw API
>       will be used for backlight control and the driver proving the "vendor"
>       backlight device will show up much later and may even never show-up,
>       so waiting for it is not an option. With a fixed 0-65535 scale userspace
>       can just always assume this and the drm_connector backlight props helper
>       code can even cache writes and send it to the actual backlight device
>       when it shows up. With a 1:1 mapping userspace needs to listen for
>       a uevent and then update the brightness range on such an event.
> 
>     I believe that the 1:1 mapping advantages out way the disadvantages
>     here. Also note that current userspace already blindly assumes that
>     all relevant drivers are loaded before the graphical-environment
>     starts and all the desktop environments as such already only do
>     a single scan of /sys/class/backlight when they start. So when
>     userspace forgets to add code to listen for the uevent when switching
>     to the new API nothing changes; and with the uevent userspace actually
>     gets a good mechanism to detect backlight drivers loading after
>     the graphical-environment has already started.
> 
>     So based on this here is my proposal for a set of new brightness
>     properties on the drm_connector object. Note these are all prefixed with
>     bl which stands for backlight, which is technically not correct for OLED.
>     But we need a prefix to avoid a name collision with the "brightness"
>     attribute which is part of the existing TV specific properties and IMHO
>     it is good to have a common prefix to make it clear that these all
>     belong together.
> 
> 
>     The drm_connector brightness properties
>     =======================================
> 
>     bl_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 bl_brightness_max.
> 
>     bl_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 (yet).
> 
>     bl_brightness_0_is_min_brightness: ro, boolean
>     When this is set to true then it is safe to set brightness to 0
>     without worrying that this completely turns the backlight off causing
>     the screen to become unreadable. When this is false setting brightness
>     to 0 may turn the backlight off, but this is _not_ guaranteed.
>     This will e.g. be true when directly driving a PWM and the video-BIOS
>     has provided a minimum (non 0) duty-cycle below which the driver will
>     never go.
> 
>     bl_brightness_control_method: ro, enum, possible values:
>     none:     The GPU driver expects brightness control to be provided by another
>               driver and that driver has not loaded yet.
>     unknown:  The underlying control mechanism is unknown.
>     pwm:      The brightness property directly controls the duty-cycle of a PWM
>               output.
>     firmware: The brightness is controlled through firmware calls.
>     DDC/CI:   The brightness is controlled through the DDC/CI protocol.
>     gmux:     The brightness is controlled by the GMUX.
>     Note this enum may be extended in the future, so other values may
>     be read, these should be treated as "unknown".
> 
>     When brightness control becomes available after being reported
>     as not available before (bl_brightness_control_method=="none")
>     a uevent with CONNECTOR=<connector-id> and
>     PROPERTY=<bl_brightness_control_method-id> will be generated
>     at this point all the properties must be re-read.
> 
>     When/once brightness control is available then all the read-only
>     properties are fixed and will never change.
> 
>     Besides the "none" value for no driver having loaded yet,
>     the different bl_brightness_control_method values are intended for
>     (userspace) heuristics for such things as the brightness setting
>     linearly controlling electrical power or setting perceived brightness.
> 
>     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/ <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/ <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 <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 <https://cgit.freedesktop.org/~mperes/linux/log/?h=backlight>
> 


^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-08-25  8:27   ` Hans de Goede
@ 2022-08-25 21:40     ` Yusuf Khan
  2022-08-28  8:08       ` Hans de Goede
  0 siblings, 1 reply; 44+ messages in thread
From: Yusuf Khan @ 2022-08-25 21:40 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, dri-devel, wayland

[-- Attachment #1: Type: text/plain, Size: 15243 bytes --]

Perhaps the Kconfig modifications could be postponed to stage 2
since for people running distros that suddenly decide to disable
/sys/class/backlight/ it may be impractical for them to recompile
their kernels and such. Also stage 2 should probably take ~2 decades
until it comes into being, for reference fbdev SPECIFIC drivers
were removed from fedora just recently and because of that there
were some issues with some user's systems. I understand it's much
easier to change from the /sys/class/backlight/ interface to the one
you have proposed than to change from fbdev to KMS though.

On Thu, Aug 25, 2022 at 3:27 AM Hans de Goede <hdegoede@redhat.com> wrote:

> Hi Yusuf,
>
> On 8/24/22 04:18, Yusuf Khan wrote:
> > Sorry for the necro-bump, I hadnt seen this go by
>
> No problem.
>
> > My main concern with this proposal is the phasing out of
> /sys/class/backlight/.
> > Currently on the user(user, not userland) level its easier for me to
> just modify
> > the file and be done with it. xbacklight doesnt tell me when its failed,
> > brightnessctl doesnt make assumptions about what device is what, and
> > other brightness setting applications ive seen are much worse than them.
> > Someone needs to create a userland application thats less inconvenient
> > than `echo`ing into /sys/class/backlight with a name that human beings
> can
> > actually remember before I stop using the sysfs, perhaps "setbrightness"
> > could be the binary's name? Also I dont think its wise to disable or
> make it
> > read only though Kconfig as older apps may depend on it, maybe add a
> > kernel param that disables the old interface so bigger distros can
> pressure
> > app makers into changing the interface? As a big draw for DDC/CI is that
> > many displays support it as a way to change brightness(even if you arent
> > doing anything special that would break the old interface) perhaps it
> could
> > be an early adopter to that kernel parameter?
>
> Right, so deprecating the /sys/class/backlight API definitely is the last
> step and probably is years away. As you say hiding / making it read-only
> should probably be a kernel-parameter at first, with maybe a Kconfig
> option to set the default. So the depcration would go like this:
>
> 1. Add:
> A kernel-parameter to allow hiding or read-only-ing the sysfs interface +
> Kconfig to select the default +
> dev_warn_once() when the old API is used
>
> 2. (much later) Drop the Kconfig option and default to hiding/read-only
>
> 3. (even later) Maybe completely remove the sysfs interface?
>
> Note the hiding vs read-only thing is to be decided. ATM I'm rather more
> focused on getting the new API in place then on deprecating the old one :)
>
> Anyways I fully agree that we need to do the deprecation carefully and
> slowly. This is likely going to take multiple years and then some ...
>
> Regards,
>
> Hans
>
>
>
> >
> > On Thu, Apr 7, 2022 at 10:39 AM Hans de Goede <hdegoede@redhat.com
> <mailto:hdegoede@redhat.com>> wrote:
> >
> >     As discussed already several times in the past:
> >      https://www.x.org/wiki/Events/XDC2014/XDC2014GoedeBacklight/ <
> https://www.x.org/wiki/Events/XDC2014/XDC2014GoedeBacklight/>
> >
> https://lore.kernel.org/all/4b17ba08-39f3-57dd-5aad-d37d844b02c6@linux.intel.com/
> <
> 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.
> >
> >     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 <
> 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.
> >
> >
> >     What scale to use for the drm_connector bl_brightness property?
> >     ===============================================================
> >
> >     The tricky part of this plan is phase 2 and then esp. defining what
> the
> >     new brightness properties will look like and how they will work.
> >
> >     The biggest challenge here is to decide on a fixed scale for the main
> >     brightness property, say 0-65535, using scaling where the actual hw
> scale
> >     is different, or if this should simply be a 1:1 mirror of the current
> >     backlight interface, with the actual hw scale / brightness_max value
> >     exposed as a drm_connector property.
> >
> >     1:1 advantages / 0-65535 disadvantages
> >     - Userspace will likely move over to the connector-props quite
> slowly and
> >       we can expect various userspace bits, esp. also custom user
> scripts, to
> >       keep using the old uAPI for a long time. Using the 2 APIs are
> intermixed
> >       is fine when using a 1:1 brightness scale mapping. But if we end
> up doing
> >       a scaling round-trip all the time then eventually the brightness
> is going
> >       do drift. This can even happen if the user never changes the
> brightness
> >       when userspace saves it over suspend/resume or reboots.
> >     - Almost all laptops have brightness up/down hotkeys. E.g GNOME
> decides
> >       on a step size for the hotkeys by doing min(brightness_max/20, 1).
> >       Some of the vendor specific backlight fw APIs (e.g. dell-laptop)
> have
> >       only 8 steps. When giving userspace the actual max_brightness
> value, then
> >       this will all work just fine. When hardcode brightness_max to
> 65535 OTOH
> >       then in this case GNOME will still give the user 20 steps where
> only 1
> >       in every 2-3 steps actually changes the brightness which IMHO is
> >       an unacceptably bad user experience.
> >
> >     0-65535 advantages / 1:1 disadvantages
> >     - Without a fixed scale for the brightness property the
> brightness_max
> >       value may change after an userspace application's initial
> enumeration
> >       of the drm_connector. This can happen when neither the native GPU
> nor
> >       the acpi_video backlight devices are present/usable in this case
> >       acpi_video_get_backlight_type() will _assume_ a vendor specific fw
> API
> >       will be used for backlight control and the driver proving the
> "vendor"
> >       backlight device will show up much later and may even never
> show-up,
> >       so waiting for it is not an option. With a fixed 0-65535 scale
> userspace
> >       can just always assume this and the drm_connector backlight props
> helper
> >       code can even cache writes and send it to the actual backlight
> device
> >       when it shows up. With a 1:1 mapping userspace needs to listen for
> >       a uevent and then update the brightness range on such an event.
> >
> >     I believe that the 1:1 mapping advantages out way the disadvantages
> >     here. Also note that current userspace already blindly assumes that
> >     all relevant drivers are loaded before the graphical-environment
> >     starts and all the desktop environments as such already only do
> >     a single scan of /sys/class/backlight when they start. So when
> >     userspace forgets to add code to listen for the uevent when switching
> >     to the new API nothing changes; and with the uevent userspace
> actually
> >     gets a good mechanism to detect backlight drivers loading after
> >     the graphical-environment has already started.
> >
> >     So based on this here is my proposal for a set of new brightness
> >     properties on the drm_connector object. Note these are all prefixed
> with
> >     bl which stands for backlight, which is technically not correct for
> OLED.
> >     But we need a prefix to avoid a name collision with the "brightness"
> >     attribute which is part of the existing TV specific properties and
> IMHO
> >     it is good to have a common prefix to make it clear that these all
> >     belong together.
> >
> >
> >     The drm_connector brightness properties
> >     =======================================
> >
> >     bl_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 bl_brightness_max.
> >
> >     bl_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 (yet).
> >
> >     bl_brightness_0_is_min_brightness: ro, boolean
> >     When this is set to true then it is safe to set brightness to 0
> >     without worrying that this completely turns the backlight off causing
> >     the screen to become unreadable. When this is false setting
> brightness
> >     to 0 may turn the backlight off, but this is _not_ guaranteed.
> >     This will e.g. be true when directly driving a PWM and the video-BIOS
> >     has provided a minimum (non 0) duty-cycle below which the driver will
> >     never go.
> >
> >     bl_brightness_control_method: ro, enum, possible values:
> >     none:     The GPU driver expects brightness control to be provided
> by another
> >               driver and that driver has not loaded yet.
> >     unknown:  The underlying control mechanism is unknown.
> >     pwm:      The brightness property directly controls the duty-cycle
> of a PWM
> >               output.
> >     firmware: The brightness is controlled through firmware calls.
> >     DDC/CI:   The brightness is controlled through the DDC/CI protocol.
> >     gmux:     The brightness is controlled by the GMUX.
> >     Note this enum may be extended in the future, so other values may
> >     be read, these should be treated as "unknown".
> >
> >     When brightness control becomes available after being reported
> >     as not available before (bl_brightness_control_method=="none")
> >     a uevent with CONNECTOR=<connector-id> and
> >     PROPERTY=<bl_brightness_control_method-id> will be generated
> >     at this point all the properties must be re-read.
> >
> >     When/once brightness control is available then all the read-only
> >     properties are fixed and will never change.
> >
> >     Besides the "none" value for no driver having loaded yet,
> >     the different bl_brightness_control_method values are intended for
> >     (userspace) heuristics for such things as the brightness setting
> >     linearly controlling electrical power or setting perceived
> brightness.
> >
> >     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/
> <
> 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/
> <
> 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 <
> 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 <
> https://cgit.freedesktop.org/~mperes/linux/log/?h=backlight>
> >
>
>

[-- Attachment #2: Type: text/html, Size: 19399 bytes --]

^ permalink raw reply	[flat|nested] 44+ messages in thread

* Re: [RFC] drm/kms: control display brightness through drm_connector properties
  2022-08-25 21:40     ` Yusuf Khan
@ 2022-08-28  8:08       ` Hans de Goede
  0 siblings, 0 replies; 44+ messages in thread
From: Hans de Goede @ 2022-08-28  8:08 UTC (permalink / raw)
  To: Yusuf Khan
  Cc: Sebastian Wick, Martin Roukala, Christoph Grenz, dri-devel, wayland

Hi,

On 8/25/22 23:40, Yusuf Khan wrote:
> Perhaps the Kconfig modifications could be postponed to stage 2
> since for people running distros that suddenly decide to disable
> /sys/class/backlight/ it may be impractical for them to recompile
> their kernels and such.

In step 1, the Kconfig option is just there to select the default
setting of the kernel commandline parameter. So when a distro
defaults that to disabling /sys/class/backlight (or making it
read-only) then the user can simple override it on the kernel
commandline. No re-compiling of kernels needed.

> Also stage 2 should probably take ~2 decades
> until it comes into being, for reference fbdev SPECIFIC drivers
> were removed from fedora just recently and because of that there
> were some issues with some user's systems. I understand it's much
> easier to change from the /sys/class/backlight/ interface to the one
> you have proposed than to change from fbdev to KMS though.

Yes chances are we will be stuck with the old sysfs API for a long
time to come. Note that since in some cases the backlight driver
is not part of the GPU driver, but rather part of e.g. dell-laptop
we will need the backlight-device abstraction in the kernel going
forward regardless of what happens with /sys/class/backlight.

So the cleanup resulting from removing it completely will not
be that big as the backlight-device abstraction will stay it
will only be the sysfs interface which disappears.

As such just having a kernel cmdline parameter to hide/unhide
it might be good enough.

Regards,

Hans



> 
> On Thu, Aug 25, 2022 at 3:27 AM Hans de Goede <hdegoede@redhat.com <mailto:hdegoede@redhat.com>> wrote:
> 
>     Hi Yusuf,
> 
>     On 8/24/22 04:18, Yusuf Khan wrote:
>     > Sorry for the necro-bump, I hadnt seen this go by
> 
>     No problem.
> 
>     > My main concern with this proposal is the phasing out of /sys/class/backlight/.
>     > Currently on the user(user, not userland) level its easier for me to just modify
>     > the file and be done with it. xbacklight doesnt tell me when its failed,
>     > brightnessctl doesnt make assumptions about what device is what, and
>     > other brightness setting applications ive seen are much worse than them.
>     > Someone needs to create a userland application thats less inconvenient
>     > than `echo`ing into /sys/class/backlight with a name that human beings can
>     > actually remember before I stop using the sysfs, perhaps "setbrightness"
>     > could be the binary's name? Also I dont think its wise to disable or make it
>     > read only though Kconfig as older apps may depend on it, maybe add a
>     > kernel param that disables the old interface so bigger distros can pressure
>     > app makers into changing the interface? As a big draw for DDC/CI is that
>     > many displays support it as a way to change brightness(even if you arent
>     > doing anything special that would break the old interface) perhaps it could
>     > be an early adopter to that kernel parameter?
> 
>     Right, so deprecating the /sys/class/backlight API definitely is the last
>     step and probably is years away. As you say hiding / making it read-only
>     should probably be a kernel-parameter at first, with maybe a Kconfig
>     option to set the default. So the depcration would go like this:
> 
>     1. Add:
>     A kernel-parameter to allow hiding or read-only-ing the sysfs interface +
>     Kconfig to select the default +
>     dev_warn_once() when the old API is used
> 
>     2. (much later) Drop the Kconfig option and default to hiding/read-only
> 
>     3. (even later) Maybe completely remove the sysfs interface?
> 
>     Note the hiding vs read-only thing is to be decided. ATM I'm rather more
>     focused on getting the new API in place then on deprecating the old one :)
> 
>     Anyways I fully agree that we need to do the deprecation carefully and
>     slowly. This is likely going to take multiple years and then some ...
> 
>     Regards,
> 
>     Hans
> 
> 
> 
>     >
>     > On Thu, Apr 7, 2022 at 10:39 AM Hans de Goede <hdegoede@redhat.com <mailto:hdegoede@redhat.com> <mailto:hdegoede@redhat.com <mailto:hdegoede@redhat.com>>> wrote:
>     >
>     >     As discussed already several times in the past:
>     >      https://www.x.org/wiki/Events/XDC2014/XDC2014GoedeBacklight/ <https://www.x.org/wiki/Events/XDC2014/XDC2014GoedeBacklight/> <https://www.x.org/wiki/Events/XDC2014/XDC2014GoedeBacklight/ <https://www.x.org/wiki/Events/XDC2014/XDC2014GoedeBacklight/>>
>     >      https://lore.kernel.org/all/4b17ba08-39f3-57dd-5aad-d37d844b02c6@linux.intel.com/ <https://lore.kernel.org/all/4b17ba08-39f3-57dd-5aad-d37d844b02c6@linux.intel.com/> <https://lore.kernel.org/all/4b17ba08-39f3-57dd-5aad-d37d844b02c6@linux.intel.com/ <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.
>     >
>     >     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 <https://bbs.archlinux.org/viewtopic.php?id=269920> <https://bbs.archlinux.org/viewtopic.php?id=269920 <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.
>     >
>     >
>     >     What scale to use for the drm_connector bl_brightness property?
>     >     ===============================================================
>     >
>     >     The tricky part of this plan is phase 2 and then esp. defining what the
>     >     new brightness properties will look like and how they will work.
>     >
>     >     The biggest challenge here is to decide on a fixed scale for the main
>     >     brightness property, say 0-65535, using scaling where the actual hw scale
>     >     is different, or if this should simply be a 1:1 mirror of the current
>     >     backlight interface, with the actual hw scale / brightness_max value
>     >     exposed as a drm_connector property.
>     >
>     >     1:1 advantages / 0-65535 disadvantages
>     >     - Userspace will likely move over to the connector-props quite slowly and
>     >       we can expect various userspace bits, esp. also custom user scripts, to
>     >       keep using the old uAPI for a long time. Using the 2 APIs are intermixed
>     >       is fine when using a 1:1 brightness scale mapping. But if we end up doing
>     >       a scaling round-trip all the time then eventually the brightness is going
>     >       do drift. This can even happen if the user never changes the brightness
>     >       when userspace saves it over suspend/resume or reboots.
>     >     - Almost all laptops have brightness up/down hotkeys. E.g GNOME decides
>     >       on a step size for the hotkeys by doing min(brightness_max/20, 1).
>     >       Some of the vendor specific backlight fw APIs (e.g. dell-laptop) have
>     >       only 8 steps. When giving userspace the actual max_brightness value, then
>     >       this will all work just fine. When hardcode brightness_max to 65535 OTOH
>     >       then in this case GNOME will still give the user 20 steps where only 1
>     >       in every 2-3 steps actually changes the brightness which IMHO is
>     >       an unacceptably bad user experience.
>     >
>     >     0-65535 advantages / 1:1 disadvantages
>     >     - Without a fixed scale for the brightness property the brightness_max
>     >       value may change after an userspace application's initial enumeration
>     >       of the drm_connector. This can happen when neither the native GPU nor
>     >       the acpi_video backlight devices are present/usable in this case
>     >       acpi_video_get_backlight_type() will _assume_ a vendor specific fw API
>     >       will be used for backlight control and the driver proving the "vendor"
>     >       backlight device will show up much later and may even never show-up,
>     >       so waiting for it is not an option. With a fixed 0-65535 scale userspace
>     >       can just always assume this and the drm_connector backlight props helper
>     >       code can even cache writes and send it to the actual backlight device
>     >       when it shows up. With a 1:1 mapping userspace needs to listen for
>     >       a uevent and then update the brightness range on such an event.
>     >
>     >     I believe that the 1:1 mapping advantages out way the disadvantages
>     >     here. Also note that current userspace already blindly assumes that
>     >     all relevant drivers are loaded before the graphical-environment
>     >     starts and all the desktop environments as such already only do
>     >     a single scan of /sys/class/backlight when they start. So when
>     >     userspace forgets to add code to listen for the uevent when switching
>     >     to the new API nothing changes; and with the uevent userspace actually
>     >     gets a good mechanism to detect backlight drivers loading after
>     >     the graphical-environment has already started.
>     >
>     >     So based on this here is my proposal for a set of new brightness
>     >     properties on the drm_connector object. Note these are all prefixed with
>     >     bl which stands for backlight, which is technically not correct for OLED.
>     >     But we need a prefix to avoid a name collision with the "brightness"
>     >     attribute which is part of the existing TV specific properties and IMHO
>     >     it is good to have a common prefix to make it clear that these all
>     >     belong together.
>     >
>     >
>     >     The drm_connector brightness properties
>     >     =======================================
>     >
>     >     bl_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 bl_brightness_max.
>     >
>     >     bl_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 (yet).
>     >
>     >     bl_brightness_0_is_min_brightness: ro, boolean
>     >     When this is set to true then it is safe to set brightness to 0
>     >     without worrying that this completely turns the backlight off causing
>     >     the screen to become unreadable. When this is false setting brightness
>     >     to 0 may turn the backlight off, but this is _not_ guaranteed.
>     >     This will e.g. be true when directly driving a PWM and the video-BIOS
>     >     has provided a minimum (non 0) duty-cycle below which the driver will
>     >     never go.
>     >
>     >     bl_brightness_control_method: ro, enum, possible values:
>     >     none:     The GPU driver expects brightness control to be provided by another
>     >               driver and that driver has not loaded yet.
>     >     unknown:  The underlying control mechanism is unknown.
>     >     pwm:      The brightness property directly controls the duty-cycle of a PWM
>     >               output.
>     >     firmware: The brightness is controlled through firmware calls.
>     >     DDC/CI:   The brightness is controlled through the DDC/CI protocol.
>     >     gmux:     The brightness is controlled by the GMUX.
>     >     Note this enum may be extended in the future, so other values may
>     >     be read, these should be treated as "unknown".
>     >
>     >     When brightness control becomes available after being reported
>     >     as not available before (bl_brightness_control_method=="none")
>     >     a uevent with CONNECTOR=<connector-id> and
>     >     PROPERTY=<bl_brightness_control_method-id> will be generated
>     >     at this point all the properties must be re-read.
>     >
>     >     When/once brightness control is available then all the read-only
>     >     properties are fixed and will never change.
>     >
>     >     Besides the "none" value for no driver having loaded yet,
>     >     the different bl_brightness_control_method values are intended for
>     >     (userspace) heuristics for such things as the brightness setting
>     >     linearly controlling electrical power or setting perceived brightness.
>     >
>     >     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/ <https://lore.kernel.org/lkml/20220403230850.2986-1-yusisamerican@gmail.com/> <https://lore.kernel.org/lkml/20220403230850.2986-1-yusisamerican@gmail.com/ <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/ <https://lore.kernel.org/all/4b17ba08-39f3-57dd-5aad-d37d844b02c6@linux.intel.com/> <https://lore.kernel.org/all/4b17ba08-39f3-57dd-5aad-d37d844b02c6@linux.intel.com/ <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 <https://www.spinics.net/lists/linux-acpi/msg50526.html> <https://www.spinics.net/lists/linux-acpi/msg50526.html <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 <https://cgit.freedesktop.org/~mperes/linux/log/?h=backlight> <https://cgit.freedesktop.org/~mperes/linux/log/?h=backlight <https://cgit.freedesktop.org/~mperes/linux/log/?h=backlight>>
>     >
> 


^ permalink raw reply	[flat|nested] 44+ messages in thread

end of thread, other threads:[~2022-08-28  8:08 UTC | newest]

Thread overview: 44+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-07 15:38 [RFC] drm/kms: control display brightness through drm_connector properties Hans de Goede
2022-04-07 16:51 ` Simon Ser
2022-04-07 17:43   ` Hans de Goede
2022-04-07 21:05     ` Alex Deucher
2022-04-08  8:07       ` Daniel Vetter
2022-04-08  9:58         ` Hans de Goede
2022-04-08 10:09           ` Hans de Goede
2022-04-08 10:16             ` Simon Ser
2022-04-08 10:26               ` Hans de Goede
2022-04-13  8:32                 ` Daniel Vetter
2022-04-13  8:38                   ` Simon Ser
2022-04-13  9:44                   ` Hans de Goede
2022-04-08 10:23           ` Hans de Goede
2022-04-08 14:08         ` Alex Deucher
2022-04-08 14:55           ` Hans de Goede
2022-04-08 15:11             ` Alex Deucher
2022-04-11 10:18               ` Hans de Goede
2022-04-11 11:34                 ` Pekka Paalanen
2022-04-11 11:50                   ` Hans de Goede
2022-04-11 13:11                     ` Mikhail Gusarov
2022-04-11 14:11                 ` Alex Deucher
2022-04-14 10:24                   ` Jani Nikula
2022-04-27 14:03                     ` Daniel Vetter
2022-04-27 14:23                       ` Jani Nikula
2022-04-27 14:26                         ` Daniel Vetter
2022-04-29  8:55                           ` Hans de Goede
2022-04-29  8:59                             ` Simon Ser
2022-04-29  9:06                               ` Pekka Paalanen
2022-04-29  9:49                                 ` Lattannavar, Sameer
2022-04-08  8:22     ` Simon Ser
2022-04-08 15:00       ` Hans de Goede
2022-04-11 10:35       ` Hans de Goede
2022-04-07 18:58 ` Carsten Haitzler
2022-04-11 10:27   ` Hans de Goede
2022-04-11 11:14     ` Carsten Haitzler
2022-04-14 13:10 ` Jani Nikula
2022-05-18 12:59   ` Hans de Goede
2022-05-18 14:23     ` Jani Nikula
2022-05-31 10:40       ` Hans de Goede
2022-05-18 14:40     ` Ville Syrjälä
2022-08-24  2:18 ` Yusuf Khan
2022-08-25  8:27   ` Hans de Goede
2022-08-25 21:40     ` Yusuf Khan
2022-08-28  8:08       ` Hans de Goede

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).