Re: [PATCH v2 0/3] drm: backlight quirk infrastructure and lower minimum for Framework AMD 13

2024-06-25 Thread Hans de Goede
Hi Thomas,

On 6/23/24 10:51 AM, Thomas Weißschuh wrote:
> The value of "min_input_signal" returned from ATIF on a Framework AMD 13
> is "12". This leads to a fairly bright minimum display backlight.
> 
> Add a generic quirk infrastructure for backlight configuration to
> override the settings provided by the firmware.
> Also add amdgpu as a user of that infrastructure and a quirk for the
> Framework 13 matte panel.
> Most likely this will also work for the glossy panel, but I can't test
> that.
> 
> One solution would be a fixed firmware version, but given that the
> problem exists since the release of the hardware, it has been known for
> a month that the hardware can go lower and there was no acknowledgment
> from Framework in any way, I'd like to explore this alternative
> way forward.

There are many panels where the brightness can go lower then the advertised
minimum brightness by the firmware (e.g. VBT for i915). For most users
the minimum brightness is fine, especially since going lower often may lead
to an unreadable screen when indoors (not in the full sun) during daylight
hours. And some users get confused by the unreadable screen and find it
hard to recover things from this state.

So IMHO we should not be overriding the minimum brightness from the firmware
using quirks because:

a) This is going to be an endless game of whack-a-mole
b) The new value may be too low for certain users / use-cases

With that said I realize that there are also many users who want to have
a lower minimum brightness value for use in the evening, since they find
the available minimum value still too bright. I know some people want this
for e.g. various ThinkPad models too.

So rather then quirking this, with the above mentioned disadvantages I believe
that it would be better to extend the existing video=eDP-1: kernel
commandline parsing to allow overriding the minimum brightness in a driver
agnostic way.

The minimum brightness override set this way will still need hooking up
in each driver separately but by using the video=eDP-1:... mechanism
we can document how to do this in driver independent manner. since
I know there have been multiple requests for something like this in
the past I believe that having a single uniform way for users to do this
will be good.

Alternatively we could have each driver have a driver specific module-
parameter for this. Either way I think we need some way for users to
override this as a config/setting tweak rather then use quirks for this.

Regards,

Hans






> 
> Notes:
> 
> * Should the quirk infrastructure be part of drm_edid.c?
> * The current allocation of struct drm_edid in amdgpu is bad.
>   But it is done the same way in other parts of amdgpu.
>   I do have patches migrating amdgpu to proper usage of struct drm_edid [0]
> 
> Mario:
> 
> I intentionally left out the consideration of the firmware version.
> The quirk will stay correct even if the firmware starts reporting
> correct values.
> If there are strong opinions it would be easy to add, though.
> 
> Based on amdgpu/drm-next.
> 
> [0] 
> https://lore.kernel.org/lkml/20240616-amdgpu-edid-bios-v1-1-2874f212b...@weissschuh.net/
> 
> ---
> Changes in v2:
> - Introduce proper drm backlight quirk infrastructure
> - Quirk by EDID and DMI instead of only DMI
> - Limit quirk to only single Framework 13 matte panel
> - Link to v1: 
> https://lore.kernel.org/r/20240610-amdgpu-min-backlight-quirk-v1-1-8459895a5...@weissschuh.net
> 
> ---
> Thomas Weißschuh (3):
>   drm: Add panel backlight quirks
>   drm: panel-backlight-quirks: Add Framework 13 matte panel
>   drm/amd/display: Add support backlight quirks
> 
>  Documentation/gpu/drm-kms-helpers.rst |  3 +
>  drivers/gpu/drm/Kconfig   |  4 ++
>  drivers/gpu/drm/Makefile  |  1 +
>  drivers/gpu/drm/amd/amdgpu/Kconfig|  1 +
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 +
>  drivers/gpu/drm/drm_panel_backlight_quirks.c  | 76 
> +++
>  include/drm/drm_utils.h   | 11 
>  7 files changed, 124 insertions(+)
> ---
> base-commit: 1ecef5589320fd56af599b624d59c355d162ac7b
> change-id: 20240610-amdgpu-min-backlight-quirk-8402fd8e736a
> 
> Best regards,



Re: [PATCH v2 1/3] drm: Add panel backlight quirks

2024-06-25 Thread Hans de Goede
Hi Thomas,

On 6/23/24 10:51 AM, Thomas Weißschuh wrote:
> Panels using a PWM-controlled backlight source without an do not have a
> standard way to communicate their valid PWM ranges.
> On x86 the ranges are read from ACPI through driver-specific tables.
> The built-in ranges are not necessarily correct, or may grow stale if an
> older device can be retrofitted with newer panels.
> 
> Add a quirk infrastructure with which the valid backlight ranges can be
> maintained as part of the kernel.
> 
> Signed-off-by: Thomas Weißschuh 
> ---
>  Documentation/gpu/drm-kms-helpers.rst|  3 ++
>  drivers/gpu/drm/Kconfig  |  4 ++
>  drivers/gpu/drm/Makefile |  1 +
>  drivers/gpu/drm/drm_panel_backlight_quirks.c | 67 
> 
>  include/drm/drm_utils.h  | 11 +
>  5 files changed, 86 insertions(+)
> 
> diff --git a/Documentation/gpu/drm-kms-helpers.rst 
> b/Documentation/gpu/drm-kms-helpers.rst
> index 59cfe8a7a8ba..1998a2675210 100644
> --- a/Documentation/gpu/drm-kms-helpers.rst
> +++ b/Documentation/gpu/drm-kms-helpers.rst
> @@ -224,6 +224,9 @@ Panel Helper Reference
>  .. kernel-doc:: drivers/gpu/drm/drm_panel_orientation_quirks.c
> :export:
>  
> +.. kernel-doc:: drivers/gpu/drm/drm_panel_backlight_quirks.c
> +   :export:
> +
>  Panel Self Refresh Helper Reference
>  ===
>  
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index 959b19a04101..50ccb43315bf 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -443,6 +443,10 @@ config DRM_EXPORT_FOR_TESTS
>  config DRM_PANEL_ORIENTATION_QUIRKS
>   tristate
>  
> +# Separate option as not all DRM drivers use it
> +config DRM_PANEL_BACKLIGHT_QUIRKS
> + tristate
> +
>  config DRM_LIB_RANDOM
>   bool
>   default n
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index f9ca4f8fa6c5..6669913b907e 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -92,6 +92,7 @@ drm-$(CONFIG_DRM_PANIC) += drm_panic.o
>  obj-$(CONFIG_DRM)+= drm.o
>  
>  obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o
> +obj-$(CONFIG_DRM_PANEL_BACKLIGHT_QUIRKS) += drm_panel_backlight_quirks.o
>  
>  #
>  # Memory-management helpers
> diff --git a/drivers/gpu/drm/drm_panel_backlight_quirks.c 
> b/drivers/gpu/drm/drm_panel_backlight_quirks.c
> new file mode 100644
> index ..a89b5fd1940e
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_panel_backlight_quirks.c
> @@ -0,0 +1,67 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +struct drm_panel_backlight_entry {
> + struct {
> + enum dmi_field field;
> + const char * const value;
> + } dmi_match;

Matching on a single DMI string is not always enough to uniquely identify
a machine. I would change this to a dmi_system_id struct and then add
an array with 2 dmi_system_id structs in drm_panel_backlight_entry_matches()
and copy the struct to the first array entry + zero out the second entry
(terminator) and then use dmi_check_system().

> + struct drm_edid_ident ident;

Hmm, what about DSI panels? These do not (always) have EDID info AFAIK.

drivers/gpu/drm/drm_panel_orientation_quirks.c is using a resolution match
so as to hopefully not match external screens, but that is also so that it can
be used from efifb / simpledrm and here you really do want to differentiate
between different panels by panel model.

So I guess that the EDId match is fine and if we ever need to match DSI panels
without EDID we figure something out then.

Thinking more about this I have a question about the approach as a whole though,
I'll reply to the cover-letter with this.

Regards,

Hans



> + struct drm_panel_backlight_quirk quirk;
> +};
> +
> +static const struct drm_panel_backlight_entry drm_panel_backlight_entries[] 
> = {
> +};
> +
> +static bool drm_panel_backlight_entry_matches(const struct 
> drm_panel_backlight_entry *entry,
> +   const struct drm_edid *edid)
> +{
> + if (!dmi_match(entry->dmi_match.field, entry->dmi_match.value))
> + return false;
> +
> + if (!drm_edid_match(edid, >ident))
> + return false;
> +
> + return true;
> +}
> +
> +/**
> + * drm_get_panel_panel_quirk - Check for panel backlight quirks
> + * @edid: EDID of the panel to check
> + *
> + * This function checks for platform specific (e.g. DMI based) quirks
> + * providing info on backlight control for systems where this cannot be
> + * probed from the hard-/firm-ware.
> + *
> + * Returns:
> + * A struct drm_panel_backlight_quirk if a quirk is found or NULL otherwise.
> + */
> +const struct drm_panel_backlight_quirk *drm_get_panel_backlight_quirk(const 
> struct drm_edid *edid)
> +{
> + const struct drm_panel_backlight_entry *entry;
> + size_t 

Re: [PATCH v2 1/3] drm: Add panel backlight quirks

2024-06-24 Thread Hans de Goede
Hi,

On 6/23/24 10:20 PM, Mario Limonciello wrote:
> On 6/23/2024 03:51, Thomas Weißschuh wrote:
>> Panels using a PWM-controlled backlight source without an do not have a
>> standard way to communicate their valid PWM ranges.
>> On x86 the ranges are read from ACPI through driver-specific tables.
>> The built-in ranges are not necessarily correct, or may grow stale if an
>> older device can be retrofitted with newer panels.
>>
>> Add a quirk infrastructure with which the valid backlight ranges can be
>> maintained as part of the kernel.
>>
> 
> So I was just talking to some folks in the Linux handheld gaming community 
> (added to CC) about an issue they have where they need to know the correct 
> panel orientation.  Due to reuse of panels across vendors the orientation on 
> one might not be appropriate on another.  The trick is then to detect the 
> combo of both the panel and the DMI data.
> 
> It's the same "kind" of problem where something advertised in the firmware 
> should be ignored but only on a panel + SMBIOS combination.
> 
> So I am wondering if what you're proposing here could be more generalized.  
> IE "drm_panel_quirks.c" instead?
> 
> Thoughts?

Note we already have a quirk mechanism for non upright mounted lcd-panels:

drivers/gpu/drm/drm_panel_orientation_quirks.c

note that the info here is shared with the simpledrm and
efifb drivers, so if the chose is made to extend this then
that needs to be taken into account.

Regards,

Hans





>> Signed-off-by: Thomas Weißschuh 
>> ---
>>   Documentation/gpu/drm-kms-helpers.rst    |  3 ++
>>   drivers/gpu/drm/Kconfig  |  4 ++
>>   drivers/gpu/drm/Makefile |  1 +
>>   drivers/gpu/drm/drm_panel_backlight_quirks.c | 67 
>> 
>>   include/drm/drm_utils.h  | 11 +
>>   5 files changed, 86 insertions(+)
>>
>> diff --git a/Documentation/gpu/drm-kms-helpers.rst 
>> b/Documentation/gpu/drm-kms-helpers.rst
>> index 59cfe8a7a8ba..1998a2675210 100644
>> --- a/Documentation/gpu/drm-kms-helpers.rst
>> +++ b/Documentation/gpu/drm-kms-helpers.rst
>> @@ -224,6 +224,9 @@ Panel Helper Reference
>>   .. kernel-doc:: drivers/gpu/drm/drm_panel_orientation_quirks.c
>>  :export:
>>   +.. kernel-doc:: drivers/gpu/drm/drm_panel_backlight_quirks.c
>> +   :export:
>> +
>>   Panel Self Refresh Helper Reference
>>   ===
>>   diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
>> index 959b19a04101..50ccb43315bf 100644
>> --- a/drivers/gpu/drm/Kconfig
>> +++ b/drivers/gpu/drm/Kconfig
>> @@ -443,6 +443,10 @@ config DRM_EXPORT_FOR_TESTS
>>   config DRM_PANEL_ORIENTATION_QUIRKS
>>   tristate
>>   +# Separate option as not all DRM drivers use it
>> +config DRM_PANEL_BACKLIGHT_QUIRKS
>> +    tristate
>> +
>>   config DRM_LIB_RANDOM
>>   bool
>>   default n
>> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
>> index f9ca4f8fa6c5..6669913b907e 100644
>> --- a/drivers/gpu/drm/Makefile
>> +++ b/drivers/gpu/drm/Makefile
>> @@ -92,6 +92,7 @@ drm-$(CONFIG_DRM_PANIC) += drm_panic.o
>>   obj-$(CONFIG_DRM)    += drm.o
>>     obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += 
>> drm_panel_orientation_quirks.o
>> +obj-$(CONFIG_DRM_PANEL_BACKLIGHT_QUIRKS) += drm_panel_backlight_quirks.o
>>     #
>>   # Memory-management helpers
>> diff --git a/drivers/gpu/drm/drm_panel_backlight_quirks.c 
>> b/drivers/gpu/drm/drm_panel_backlight_quirks.c
>> new file mode 100644
>> index ..a89b5fd1940e
>> --- /dev/null
>> +++ b/drivers/gpu/drm/drm_panel_backlight_quirks.c
>> @@ -0,0 +1,67 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +#include 
>> +
>> +struct drm_panel_backlight_entry {
>> +    struct {
>> +    enum dmi_field field;
>> +    const char * const value;
>> +    } dmi_match;
>> +    struct drm_edid_ident ident;
>> +    struct drm_panel_backlight_quirk quirk;
>> +};
>> +
>> +static const struct drm_panel_backlight_entry drm_panel_backlight_entries[] 
>> = {
>> +};
>> +
>> +static bool drm_panel_backlight_entry_matches(const struct 
>> drm_panel_backlight_entry *entry,
>> +  const struct drm_edid *edid)
>> +{
>> +    if (!dmi_match(entry->dmi_match.field, entry->dmi_match.value))
>> +    return false;
>> +
>> +    if (!drm_edid_match(edid, >ident))
>> +    return false;
>> +
>> +    return true;
>> +}
>> +
>> +/**
>> + * drm_get_panel_panel_quirk - Check for panel backlight quirks
>> + * @edid: EDID of the panel to check
>> + *
>> + * This function checks for platform specific (e.g. DMI based) quirks
>> + * providing info on backlight control for systems where this cannot be
>> + * probed from the hard-/firm-ware.
>> + *
>> + * Returns:
>> + * A struct drm_panel_backlight_quirk if a quirk is found or NULL otherwise.
>> + */
>> +const struct drm_panel_backlight_quirk *drm_get_panel_backlight_quirk(const 
>> 

Re: [PATCH 07/28] platform: intel_ips: Use PCI_IRQ_INTX

2024-03-25 Thread Hans de Goede
Hi,

On 3/25/24 8:09 AM, Damien Le Moal wrote:
> Use the macro PCI_IRQ_INTX instead of the deprecated PCI_IRQ_LEGACY
> macro.
> 
> Signed-off-by: Damien Le Moal 

Thanks, patch looks good to me, feel free to merge
this through whatever tree is convenient (or let me
know if you want me to pick up just this one patch
from the series).

Acked-by: Hans de Goede 

Regards,

Hans




> ---
>  drivers/platform/x86/intel_ips.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/platform/x86/intel_ips.c 
> b/drivers/platform/x86/intel_ips.c
> index ba38649cc142..73ec4460a151 100644
> --- a/drivers/platform/x86/intel_ips.c
> +++ b/drivers/platform/x86/intel_ips.c
> @@ -1505,7 +1505,7 @@ static int ips_probe(struct pci_dev *dev, const struct 
> pci_device_id *id)
>* IRQ handler for ME interaction
>* Note: don't use MSI here as the PCH has bugs.
>*/
> - ret = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_LEGACY);
> + ret = pci_alloc_irq_vectors(dev, 1, 1, PCI_IRQ_INTX);
>   if (ret < 0)
>   return ret;
>  



Re: Kernel 6.7+ broke under-powering of my RX 6700XT. (Archlinux, mesa/amdgpu)

2024-02-21 Thread Hans de Goede
Hi,

On 2/20/24 16:15, Alex Deucher wrote:
> On Tue, Feb 20, 2024 at 10:03 AM Linux regression tracking (Thorsten
> Leemhuis)  wrote:
>>
>> On 20.02.24 15:45, Alex Deucher wrote:
>>> On Mon, Feb 19, 2024 at 9:47 AM Linux regression tracking (Thorsten
>>> Leemhuis)  wrote:

 On 17.02.24 14:30, Greg KH wrote:
> On Sat, Feb 17, 2024 at 02:01:54PM +0100, Roman Benes wrote:
>> Minimum power limit on latest(6.7+) kernels is 190W for my GPU (RX 
>> 6700XT,
>> mesa, archlinux) and I cannot get power cap as low as before(to 115W),
>> neither with Corectrl, LACT or TuxClocker and /sys have a variable 
>> read-only
>> even for root. This is not of above apps issue but of the kernel, I read
>> similar issues from other bug reports of above apps. I downgraded to 
>> v6.6.10
>> kernel and my 115W(under power)cap work again as before.
>
 For the record and everyone that lands here: the cause is known now
 (it's 1958946858a62b ("drm/amd/pm: Support for getting power1_cap_min
 value") [v6.7-rc1]) and the issue afaics tracked here:

 https://gitlab.freedesktop.org/drm/amd/-/issues/3183

 Other mentions:
 https://gitlab.freedesktop.org/drm/amd/-/issues/3137
 https://gitlab.freedesktop.org/drm/amd/-/issues/2992

 Haven't seen any statement from the amdgpu developers (now CCed) yet on
 this there (but might have missed something!). From what I can see I
 assume this will likely be somewhat tricky to handle, as a revert
 overall might be a bad idea here. We'll see I guess.
>>>
>>> The change aligns the driver what has been validated on each board
>>> design.  Windows uses the same limits.  Using values lower than the
>>> validated range can lead to undefined behavior and could potentially
>>> damage your hardware.
>>
>> Thx for the reply! Yeah, I was expecting something along those lines.
>>
>> Nevertheless it afaics still is a regression in the eyes of many users.
>> I'm not sure how Linus feels about this, but I wonder if we can find
>> some solution here so that users that really want to, can continue to do
>> what was possible out-of-the box before. Is that possible to realize or
>> even supported already?
>>
>> And sure, those users would be running their hardware outside of its
>> specifications. But is that different from overclocking (which the
>> driver allows, doesn't it? If not by all means please correct me!)?
> 
> Sure.  The driver has always had upper bound limits for overclocking,
> this change adds lower bounds checking for underclocking as well.
> When the silicon validation teams set the bounding box for a device,
> they set a range of values where it's reasonable to operate based on
> the characteristics of the design.
> 
> If we did want to allow extended underclocking, we need a big warning
> in the logs at the very least.

Requiring a module-option to be set to allow this, as well as a big
warning in the logs sounds like a good solution to me.

Regards,

Hans





 Roman posted something that apparently was meant to go to the list, so
 let me put it here:

 """
 UPDATE: User fililip already posted patch, but it need to be merged,
 discussion is on gitlab link below.

 (PS: I hope I am replying correctly to "all" now? - using original addr.)


> it seems that commit was already found(see user's 'fililip' comment):
>
> https://gitlab.freedesktop.org/drm/amd/-/issues/3183
> commit 1958946858a62b6b5392ed075aa219d199bcae39
> Author: Ma Jun 
> Date:   Thu Oct 12 09:33:45 2023 +0800
>
> drm/amd/pm: Support for getting power1_cap_min value
>
> Support for getting power1_cap_min value on smu13 and smu11.
> For other Asics, we still use 0 as the default value.
>
> Signed-off-by: Ma Jun 
> Reviewed-by: Kenneth Feng 
> Signed-off-by: Alex Deucher 
>
> However, this is not good as it remove under-powering range too far. I
 was getting only about 7% less performance but 90W(!) less consumption
 when set to my 115W before. Also I wonder if we as a OS of options and
 freedom have to stick to such very high reference for min values without
 ability to override them through some sys ctrls. Commit was done by amd
 guy and I wonder if because of maybe this post that I made few months
 ago(business strategy?):
>
>
 https://www.reddit.com/r/Amd/comments/183gye7/rx_6700xt_from_230w_to_capped_115w_at_only_10/
>
> This is not a dangerous OC upwards where I can understand desire to
 protect HW, it is downward, having min cap at 190W when card pull on
 115W almost same speed is IMO crazy to deny. We don't talk about default
 or reference values here either, just a move to lower the range of
 options for whatever reason.
>
> I don't know how much power you guys have over them, but please
 consider either reverting this change, 

[GIT PULL] mmutable branch between pdx86 amd wbrf branch and wifi / amdgpu due for the v6.8 merge window

2023-12-11 Thread Hans de Goede
Hi Wifi and AMDGPU maintainers,

Here is a pull-request for the platform-drivers-x86 parts of:

https://lore.kernel.org/platform-driver-x86/20231211100630.2170152-1-jun@amd.com/

>From my pov the pdx86 bits are ready and the 
>platform-drivers-x86-amd-wbrf-v6.8-1 tag can be merged by you to merge the 
>wifi-subsys resp. the amdgpu driver changes on top.

This only adds kernel internal API, so if in the future the API needs work that 
can be done.

I've not merged this branch into pdx86/for-next yet, since I see little use in 
merging it without any users. I'll merge it once either the wifi or amdgpu 
changes are also merged
(and if some blocking issues get identified before either are merged I can 
prepare a new pull-request fixing the issues).

Regards,

Hans



The following changes since commit b85ea95d086471afb4ad062012a4d73cd328fa86:

  Linux 6.7-rc1 (2023-11-12 16:19:07 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git 
tags/platform-drivers-x86-amd-wbrf-v6.8-1

for you to fetch changes up to 58e82a62669da52e688f4a8b89922c1839bf1001:

  platform/x86/amd: Add support for AMD ACPI based Wifi band RFI mitigation 
feature (2023-12-11 11:33:44 +0100)


Immutable branch between pdx86 amd wbrf branch and wifi / amdgpu due for the 
v6.8 merge window

platform-drivers-x86-amd-wbrf-v6.8-1: v6.7-rc1 + AMD WBRF support
for merging into the wifi subsys and amdgpu driver for 6.8.


Ma Jun (2):
  Documentation/driver-api: Add document about WBRF mechanism
  platform/x86/amd: Add support for AMD ACPI based Wifi band RFI mitigation 
feature

 Documentation/driver-api/index.rst |   1 +
 Documentation/driver-api/wbrf.rst  |  78 +
 drivers/platform/x86/amd/Kconfig   |  14 ++
 drivers/platform/x86/amd/Makefile  |   1 +
 drivers/platform/x86/amd/wbrf.c| 317 +
 include/linux/acpi_amd_wbrf.h  |  91 +++
 6 files changed, 502 insertions(+)
 create mode 100644 Documentation/driver-api/wbrf.rst
 create mode 100644 drivers/platform/x86/amd/wbrf.c
 create mode 100644 include/linux/acpi_amd_wbrf.h



Re: [GIT PULL] mmutable branch between pdx86 amd wbrf branch and wifi / amdgpu due for the v6.8 merge window

2023-12-11 Thread Hans de Goede
Hi Johannes,

On 12/11/23 12:41, Johannes Berg wrote:
> Hi,
> 
>> Here is a pull-request for the platform-drivers-x86 parts of:
>>
>> https://lore.kernel.org/platform-driver-x86/20231211100630.2170152-1-jun@amd.com/
>>
>> From my pov the pdx86 bits are ready and the 
>> platform-drivers-x86-amd-wbrf-v6.8-1 tag can be merged by you to merge the 
>> wifi-subsys resp. the amdgpu driver changes on top.
>>
>> This only adds kernel internal API, so if in the future the API needs work 
>> that can be done.
> 
> I've been fine with the wifi bits since around v3 of the patchset ;-)
> 
> So the idea is that I'll pull this into wireless-next and then apply the
> two wireless patches on top, right?

Right.

> AFAICT, since the other patches don't depend on wireless for
> compilation, this is the only thing I need to do, i.e. no need to have
> another separate branch to send it further on, right?

Right / correct.

Regards,

Hans






Re: [PATCH v14 2/9] platform/x86/amd: Add support for AMD ACPI based Wifi band RFI mitigation feature

2023-12-04 Thread Hans de Goede
Hi,

On 11/29/23 10:13, Ma Jun wrote:
> Due to electrical and mechanical constraints in certain platform designs
> there may be likely interference of relatively high-powered harmonics of
> the (G-)DDR memory clocks with local radio module frequency bands used
> by Wifi 6/6e/7.
> 
> To mitigate this, AMD has introduced a mechanism that devices can use to
> notify active use of particular frequencies so that other devices can make
> relative internal adjustments as necessary to avoid this resonance.
> 
> Co-developed-by: Evan Quan 
> Signed-off-by: Evan Quan 
> Signed-off-by: Ma Jun 
> 
> --
> v11:
>  - fix typo(Simon)
> v12:
>  - Fix the code logic (Rafael)
>  - Move amd_wbrf.c to drivers/platform/x86/amd/wbrf.c
>  - Updated Evan's email because he's no longer at AMD.Thanks
> for his work in earlier versions.
> v13:
>  - Fix the format issue (IIpo Jarvinen)
>  - Add comment for some functions
> v14:
>  - Use the apci_check_dsm and acpi_evaluate_dsm (Hans de Goede)

Thank you this is much better.

I notice that the #define ACPI_AMD_WBRF_METHOD  "\\WBRF"
still exists though and that this is still used in
static bool acpi_amd_wbrf_supported_system(void).

I think it might be better to just remove
these 2 all together.

Checking if a DSM with the expected GUID is present
and if that has the correct bits set in its supported
mask should be enough.

And on future systems the implementer may decide to
not have a WBRF helper function at all and instead
handle everything in the _DSM method.

So the "\\WBRF" check seems to be checking for
what really is an implementation detail.

2 other very small remarks:

> +/**
> + * acpi_amd_wbrf_supported_producer - determine if the WBRF can be enabled
> + *for the device as a producer
> + *
> + * @dev: device pointer
> + *
> + * Check if the platform equipped with necessary implementations to
> + * support WBRF for the device as a producer.
> + *
> + * Return:
> + * true if WBRF is supported, otherwise returns false
> + */
> +bool acpi_amd_wbrf_supported_producer(struct device *dev)
> +{
> + struct acpi_device *adev;
> +
> + adev = ACPI_COMPANION(dev);
> + if (!adev)
> + return false;
> +
> + if (!acpi_amd_wbrf_supported_system())
> + return false;
> +
> +
> + return acpi_check_dsm(adev->handle, _acpi_dsm_guid,
> +   WBRF_REVISION, BIT(WBRF_RECORD));
> +}
> +EXPORT_SYMBOL_GPL(acpi_amd_wbrf_supported_producer);

Please don't use double empty lines, one empty line to separate things
is enough.

> +
> +/**
> + * acpi_amd_wbrf_supported_consumer - determine if the WBRF can be enabled
> + *for the device as a consumer
> + *
> + * @dev: device pointer
> + *
> + * Determine if the platform equipped with necessary implementations to
> + * support WBRF for the device as a consumer.
> + *
> + * Return:
> + * true if WBRF is supported, otherwise returns false.
> + */
> +bool acpi_amd_wbrf_supported_consumer(struct device *dev)
> +{
> + struct acpi_device *adev;
> +
> + adev = ACPI_COMPANION(dev);
> + if (!adev)
> + return false;
> +
> + if (!acpi_amd_wbrf_supported_system())
> + return false;
> +
> + return acpi_check_dsm(adev->handle, _acpi_dsm_guid,
> +   WBRF_REVISION, BIT(WBRF_RETRIEVE));
> +}
> +EXPORT_SYMBOL_GPL(acpi_amd_wbrf_supported_consumer);
> +
> +/**
> + * amd_wbrf_retrieve_freq_band - retrieve current active frequency
> + * bands

You may go a bit over the 80 chars limit, please just make this
a single line:

 * amd_wbrf_retrieve_freq_band - retrieve current active frequency bands

> + *
> + * @dev: device pointer
> + * @out: output structure containing all the active frequency bands
> + *
> + * Retrieve the current active frequency bands which were broadcasted
> + * by other producers. The consumer who calls this API should take
> + * proper actions if any of the frequency band may cause RFI with its
> + * own frequency band used.
> + *
> + * Return:
> + * 0 for getting wifi freq band successfully.
> + * Returns a negative error code for failure.
> + */

Regards,

Hans



Re: [PATCH v12 1/9] Documentation/driver-api: Add document about WBRF mechanism

2023-11-20 Thread Hans de Goede
Hi,

On 10/17/23 04:53, Ma Jun wrote:
> Add documentation about AMD's Wifi band RFI mitigation (WBRF) mechanism
> explaining the theory and how it is used.
> 
> Signed-off-by: Ma Jun 
> ---
>  Documentation/driver-api/wbrf.rst | 73 +++
>  1 file changed, 73 insertions(+)
>  create mode 100644 Documentation/driver-api/wbrf.rst
> 
> diff --git a/Documentation/driver-api/wbrf.rst 
> b/Documentation/driver-api/wbrf.rst
> new file mode 100644
> index ..8561840263b3
> --- /dev/null
> +++ b/Documentation/driver-api/wbrf.rst
> @@ -0,0 +1,73 @@
> +.. SPDX-License-Identifier: GPL-2.0-or-later
> +
> +=
> +WBRF - Wifi Band RFI Mitigations
> +=
> +Due to electrical and mechanical constraints in certain platform designs
> +there may be likely interference of relatively high-powered harmonics of
> +the GPU memory clocks with local radio module frequency bands used by
> +certain Wifi bands.
> +
> +To mitigate possible RFI interference producers can advertise the
> +frequencies in use and consumers can use this information to avoid using
> +these frequencies for sensitive features.
> +
> +When a platform is known to have this issue with any contained devices,
> +the platform designer will advertise the availability of this feature via
> +ACPI devices with a device specific method (_DSM).
> +* Producers with this _DSM will be able to advertise the frequencies in use.
> +* Consumers with this _DSM will be able to register for notifications of
> +frequencies in use.
> +
> +Some general terms
> +==
> +Producer: such component who can produce high-powered radio frequency
> +Consumer: such component who can adjust its in-use frequency in
> +   response to the radio frequencies of other components to
> +   mitigate the possible RFI.
> +
> +To make the mechanism function, those producers should notify active use
> +of their particular frequencies so that other consumers can make relative
> +internal adjustments as necessary to avoid this resonance.
> +
> +ACPI interface
> +==
> +Although initially used by for wifi + dGPU use cases, the ACPI interface
> +can be scaled to any type of device that a platform designer discovers
> +can cause interference.
> +
> +The GUID used for the _DSM is 7B7656CF-DC3D-4C1C-83E9-66E721DE3070.
> +
> +3 functions are available in this _DSM:
> +
> +* 0: discover # of functions available
> +* 1: record RF bands in use
> +* 2: retrieve RF bands in use
> +
> +Driver programming interface
> +
> +.. kernel-doc:: drivers/platform/x86/amd/wbrf.c
> +
> +Sample Usage
> +=
> +The expected flow for the producers:
> +1) During probe, call `acpi_amd_wbrf_supported_producer` to check if WBRF
> +can be enabled for the device.
> +2) On using some frequency band, call `acpi_amd_wbrf_add_remove` with 'add'
> +param to get other consumers properly notified.
> +3) Or on stopping using some frequency band, call
> +`acpi_amd_wbrf_add_remove` with 'remove' param to get other consumers 
> notified.
> +
> +The expected flow for the consumers:
> +1) During probe, call `acpi_amd_wbrf_supported_consumer` to check if WBRF
> +can be enabled for the device.
> +2) Call `amd_wbrf_register_notifier` to register for notification
> +of frequency band change(add or remove) from other producers.

> +3) Call the `amd_wbrf_retrieve_freq_band` intentionally to retrieve
> +current active frequency bands considering some producers may broadcast
> +such information before the consumer is up.

"intentionally" in this sentence should be "initially" (I presume).

With that fixed and Ilpo's review comments addressed you may add my:

Reviewed-by: Hans de Goede 

to this patch.

Regards,

Hans




> +4) On receiving a notification for frequency band change, run
> +`amd_wbrf_retrieve_freq_band` again to retrieve the latest
> +active frequency bands.
> +5) During driver cleanup, call `amd_wbrf_unregister_notifier` to
> +unregister the notifier.



Re: [PATCH v12 0/9] Enable Wifi RFI interference mitigation feature support

2023-11-20 Thread Hans de Goede
Hi,

On 10/19/23 08:17, Ma, Jun wrote:
> ping...
> Any other comments?

Patches 1/9 and 2/9 look reasonable, once the questions about
use of the _DSM vs directly calling the WBRF ACPI method are
resolved I can merge patches 1/9 and 2/9 and create an immutable
feature branch based on 6.7-rc1 + these 2 patches.

I'll then also send a pull-request to the wifi /resp amdgpu
maintainers from this branch.

I see no acks / reviews from the wifi folks yet,
so once that immutable feature branch is ready the first
thing to do is try to get the wifi folks to review + merge WBRF
support.

Note I plan to not actually merge the feature branch
into for-next until the wifi folks are happy with the code.

This way if changes are necessary I can do a v2 feature branch
and the wifi folks can merge that instead.

Regards,

Hans




> On 10/17/2023 10:53 AM, Ma Jun wrote:
>> Due to electrical and mechanical constraints in certain platform designs 
>> there
>> may be likely interference of relatively high-powered harmonics of the 
>> (G-)DDR
>> memory clocks with local radio module frequency bands used by Wifi 6/6e/7. To
>> mitigate possible RFI interference we introuduced WBRF(Wifi Band RFI 
>> mitigation Feature).
>> Producers can advertise the frequencies in use and consumers can use this 
>> information
>> to avoid using these frequencies for sensitive features.
>>
>> The whole patch set is based on Linux 6.5.0. With some brief introductions
>> as below:
>> Patch1:  Document about WBRF
>> Patch2:  Core functionality setup for WBRF feature support
>> Patch3 - 4:  Bring WBRF support to wifi subsystem.
>> Patch5 - 9:  Bring WBRF support to AMD graphics driver.
>>
>> Evan Quan (7):
>>   cfg80211: expose nl80211_chan_width_to_mhz for wide sharing
>>   wifi: mac80211: Add support for WBRF features
>>   drm/amd/pm: update driver_if and ppsmc headers for coming wbrf feature
>>   drm/amd/pm: setup the framework to support Wifi RFI mitigation feature
>>   drm/amd/pm: add flood detection for wbrf events
>>   drm/amd/pm: enable Wifi RFI mitigation feature support for SMU13.0.0
>>   drm/amd/pm: enable Wifi RFI mitigation feature support for SMU13.0.7
>>
>> Ma Jun (2):
>>   Documentation/driver-api: Add document about WBRF mechanism
>>   platform/x86/amd: Add support for AMD ACPI based Wifi band RFI
>> mitigation feature
>>
>>  Documentation/driver-api/wbrf.rst |  71 +++
>>  drivers/gpu/drm/amd/amdgpu/amdgpu.h   |   2 +
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   |  17 +
>>  drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 214 +
>>  drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h |  33 ++
>>  .../inc/pmfw_if/smu13_driver_if_v13_0_0.h |  14 +-
>>  .../inc/pmfw_if/smu13_driver_if_v13_0_7.h |  14 +-
>>  .../pm/swsmu/inc/pmfw_if/smu_v13_0_0_ppsmc.h  |   3 +-
>>  .../pm/swsmu/inc/pmfw_if/smu_v13_0_7_ppsmc.h  |   3 +-
>>  drivers/gpu/drm/amd/pm/swsmu/inc/smu_types.h  |   3 +-
>>  drivers/gpu/drm/amd/pm/swsmu/inc/smu_v13_0.h  |   3 +
>>  .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c|   9 +
>>  .../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c  |  60 +++
>>  .../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c  |  59 +++
>>  drivers/gpu/drm/amd/pm/swsmu/smu_internal.h   |   3 +
>>  drivers/platform/x86/amd/Kconfig  |  15 +
>>  drivers/platform/x86/amd/Makefile |   1 +
>>  drivers/platform/x86/amd/wbrf.c   | 422 ++
>>  include/linux/acpi_amd_wbrf.h | 101 +
>>  include/linux/ieee80211.h |   1 +
>>  include/net/cfg80211.h|   8 +
>>  net/mac80211/Makefile |   2 +
>>  net/mac80211/chan.c   |   9 +
>>  net/mac80211/ieee80211_i.h|   9 +
>>  net/mac80211/main.c   |   2 +
>>  net/mac80211/wbrf.c   | 105 +
>>  net/wireless/chan.c   |   3 +-
>>  27 files changed, 1180 insertions(+), 6 deletions(-)
>>  create mode 100644 Documentation/driver-api/wbrf.rst
>>  create mode 100644 drivers/platform/x86/amd/wbrf.c
>>  create mode 100644 include/linux/acpi_amd_wbrf.h
>>  create mode 100644 net/mac80211/wbrf.c
>>
> 



Re: [PATCH v12 2/9] platform/x86/amd: Add support for AMD ACPI based Wifi band RFI mitigation feature

2023-11-20 Thread Hans de Goede
Hi,

On 10/17/23 04:53, Ma Jun wrote:
> Due to electrical and mechanical constraints in certain platform designs
> there may be likely interference of relatively high-powered harmonics of
> the (G-)DDR memory clocks with local radio module frequency bands used
> by Wifi 6/6e/7.
> 
> To mitigate this, AMD has introduced a mechanism that devices can use to
> notify active use of particular frequencies so that other devices can make
> relative internal adjustments as necessary to avoid this resonance.
> 
> Co-Developed-by: Evan Quan 
> Signed-off-by: Evan Quan 
> Signed-off-by: Ma Jun 



> +bool acpi_amd_wbrf_supported_producer(struct device *dev)
> +{
> + struct acpi_device *adev = ACPI_COMPANION(dev);
> +
> + if (!adev)
> + return false;
> +
> + if (!acpi_amd_wbrf_supported_system())
> + return false;
> +
> +
> + return acpi_check_dsm(adev->handle, _acpi_dsm_guid,
> +   WBRF_REVISION,
> +   BIT(WBRF_RECORD));
> +}
> +EXPORT_SYMBOL_GPL(acpi_amd_wbrf_supported_producer);

So until here you use acpi_dsm methods (1), which matches
with patch 1/9 which says that both producers and consumers
use a _DSM for WBRF.

1) With the exception of the weird acpi_amd_wbrf_supported_system()
helper.

> +static union acpi_object *
> +acpi_evaluate_wbrf(acpi_handle handle, u64 rev, u64 func)
> +{
> + acpi_status ret;
> + struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
> + union acpi_object params[4];
> + struct acpi_object_list input = {
> + .count = 4,
> + .pointer = params,
> + };
> +
> + params[0].type = ACPI_TYPE_INTEGER;
> + params[0].integer.value = rev;
> + params[1].type = ACPI_TYPE_INTEGER;
> + params[1].integer.value = func;
> + params[2].type = ACPI_TYPE_PACKAGE;
> + params[2].package.count = 0;
> + params[2].package.elements = NULL;
> + params[3].type = ACPI_TYPE_STRING;
> + params[3].string.length = 0;
> + params[3].string.pointer = NULL;
> +
> + ret = acpi_evaluate_object(handle, "WBRF", , );
> + if (ACPI_FAILURE(ret))
> + return NULL;
> +
> + return buf.pointer;
> +}

But now all of a sudden you start calling a WBRF method
directly instead of calling a _DSM by GUID, which seems
to be intended for consumers.

This contradicts with the documentation which says that
consumers also use the _DSM.

And this looks a lot like acpi_evaluate_dsm and
... (continued below)

> +
> +static bool check_acpi_wbrf(acpi_handle handle, u64 rev, u64 funcs)
> +{
> + int i;
> + u64 mask = 0;
> + union acpi_object *obj;
> +
> + if (funcs == 0)
> + return false;
> +
> + obj = acpi_evaluate_wbrf(handle, rev, 0);
> + if (!obj)
> + return false;
> +
> + if (obj->type != ACPI_TYPE_BUFFER)
> + return false;
> +
> + /*
> +  * Bit vector providing supported functions information.
> +  * Each bit marks support for one specific function of the WBRF method.
> +  */
> + for (i = 0; i < obj->buffer.length && i < 8; i++)
> + mask |= (u64)obj->buffer.pointer[i] << i * 8;
> +
> + ACPI_FREE(obj);
> +
> + if ((mask & BIT(WBRF_ENABLED)) && (mask & funcs) == funcs)
> + return true;
> +
> + return false;
> +}

This looks exactly like acpi_check_dsm().

> +
> +/**
> + * acpi_amd_wbrf_supported_consumer - determine if the WBRF can be enabled
> + *for the device as a consumer
> + *
> + * @dev: device pointer
> + *
> + * Determine if the platform equipped with necessary implementations to
> + * support WBRF for the device as a consumer.
> + *
> + * Return:
> + * true if WBRF is supported, otherwise returns false.
> + */
> +bool acpi_amd_wbrf_supported_consumer(struct device *dev)
> +{
> + struct acpi_device *adev = ACPI_COMPANION(dev);
> +
> + if (!adev)
> + return false;
> +
> + if (!acpi_amd_wbrf_supported_system())
> + return false;
> +
> + return check_acpi_wbrf(adev->handle,
> +WBRF_REVISION,
> +BIT(WBRF_RETRIEVE));
> +}
> +EXPORT_SYMBOL_GPL(acpi_amd_wbrf_supported_consumer);

So I would expect this to just use acpi_check_dsm like
is done for the producers.

> +
> +/**
> + * amd_wbrf_retrieve_freq_band - retrieve current active frequency
> + * bands
> + *
> + * @dev: device pointer
> + * @out: output structure containing all the active frequency bands
> + *
> + * Retrieve the current active frequency bands which were broadcasted
> + * by other producers. The consumer who calls this API should take
> + * proper actions if any of the frequency band may cause RFI with its
> + * own frequency band used.
> + *
> + * Return:
> + * 0 for getting wifi freq band successfully.
> + * Returns a negative error code for failure.
> + */
> +int amd_wbrf_retrieve_freq_band(struct device 

Re: [PATCH v2 6/9] PCI: Rename is_thunderbolt to is_tunneled

2023-11-03 Thread Hans de Goede
Hi,

On 11/3/23 20:07, Mario Limonciello wrote:
> The `is_thunderbolt` bit has been used to indicate that a PCIe device
> contained the Intel VSEC which is used by various parts of the kernel
> to change behavior. To later allow usage with USB4 controllers as well,
> rename this to `is_tunneled`.
> 
> Signed-off-by: Mario Limonciello 

Here is my ack for the trivial drivers/platform/x86/apple-gmux.c change:

Acked-by: Hans de Goede 

Bjorn, feel free to route this through the PCI tree.

Regards,

Hans




> ---
>  drivers/pci/pci.c | 2 +-
>  drivers/pci/probe.c   | 2 +-
>  drivers/platform/x86/apple-gmux.c | 2 +-
>  include/linux/pci.h   | 2 +-
>  4 files changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 59c01d68c6d5..d9aa5a39f585 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -3032,7 +3032,7 @@ bool pci_bridge_d3_possible(struct pci_dev *bridge)
>   return true;
>  
>   /* Even the oldest 2010 Thunderbolt controller supports D3. */
> - if (bridge->is_thunderbolt)
> + if (bridge->is_tunneled)
>   return true;
>  
>   /* Platform might know better if the bridge supports D3 */
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 795534589b98..518413d15402 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -1597,7 +1597,7 @@ static void set_pcie_thunderbolt(struct pci_dev *dev)
>   /* Is the device part of a Thunderbolt controller? */
>   vsec = pci_find_vsec_capability(dev, PCI_VENDOR_ID_INTEL, 
> PCI_VSEC_ID_INTEL_TBT);
>   if (vsec)
> - dev->is_thunderbolt = 1;
> + dev->is_tunneled = 1;
>  }
>  
>  static void set_pcie_untrusted(struct pci_dev *dev)
> diff --git a/drivers/platform/x86/apple-gmux.c 
> b/drivers/platform/x86/apple-gmux.c
> index 1417e230edbd..20315aa4463a 100644
> --- a/drivers/platform/x86/apple-gmux.c
> +++ b/drivers/platform/x86/apple-gmux.c
> @@ -774,7 +774,7 @@ static int gmux_resume(struct device *dev)
>  
>  static int is_thunderbolt(struct device *dev, void *data)
>  {
> - return to_pci_dev(dev)->is_thunderbolt;
> + return to_pci_dev(dev)->is_tunneled;
>  }
>  
>  static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 439c2dac8a3e..b1724f25fb02 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -440,7 +440,7 @@ struct pci_dev {
>   unsigned intis_virtfn:1;
>   unsigned intis_hotplug_bridge:1;
>   unsigned intshpc_managed:1; /* SHPC owned by shpchp */
> - unsigned intis_thunderbolt:1;   /* Thunderbolt controller */
> + unsigned intis_tunneled:1;  /* Tunneled TBT or USB4 link */
>   unsigned intno_command_complete:1;  /* No command completion */
>   /*
>* Devices marked being untrusted are the ones that can potentially



Re: [PATCH v4 13/17] platform/x86/amd/pmf: Add PMF-AMDGPU get interface

2023-10-18 Thread Hans de Goede
Hi,

I was not following this at first, so my apologies for
jumping in in the middle of the thread:




> +static int amd_pmf_gpu_get_cur_state(struct thermal_cooling_device 
> *cooling_dev,
> + unsigned long *state)
> +{
> +    struct backlight_device *bd;
> +
> +    if (!acpi_video_backlight_use_native())
> +    return -ENODEV;
> +
> +    bd = backlight_device_get_by_type(BACKLIGHT_RAW);
> +    if (!bd)
> +    return -ENODEV;
> +
> +    *state = backlight_get_brightness(bd);
> +
> +    return 0;
> +}
> +
> +static int amd_pmf_gpu_get_max_state(struct thermal_cooling_device 
> *cooling_dev,
> + unsigned long *state)
> +{
> +    struct backlight_device *bd;
> +
> +    if (!acpi_video_backlight_use_native())
> +    return -ENODEV;
> +
> +    bd = backlight_device_get_by_type(BACKLIGHT_RAW);
> +    if (!bd)
> +    return -ENODEV;
> +
> +    if (backlight_is_blank(bd))
> +    *state = 0;
> +    else
> +    *state = bd->props.max_brightness;
> +
> +    return 0;
> +}
> +
> +static const struct thermal_cooling_device_ops bd_cooling_ops = {
> +    .get_max_state = amd_pmf_gpu_get_max_state,
> +    .get_cur_state = amd_pmf_gpu_get_cur_state,
> +};

So first of all, good to see that this is using the
thermal_cooling_device APIs now, that is great thank you.

But the whole idea behind using the thermal_cooling_device APIs
is that amdgpu exports the cooling_device itself, rather then have
the AMD PMF code export it. Now the AMD PMF code is still poking
at the backlight_device itself, while the idea was to delegate
this to the GPU driver.

Actually seeing all the acpi_video_backlight_use_native()
checks here, I wonder why only have this work with native backlight
control. One step better would be to add thermal_cooling_device
support to the backlight core in:
drivers/video/backlight/backlight.c

Then it will work with any backlight control provider!



Last but not least this code MUST not call
acpi_video_backlight_use_native()

No code other then native GPU drivers must ever call
acpi_video_backlight_use_native(). This special function
not only checks if the native backlight control is the
one which the detection code in drivers/acpi/video_detect.c
has selected, it also signals to video_detect.c that
native GPU backlight control is available.

So by calling this in the AMD PMF code you are now
telling video_detect.c that native GPU backlight control
is available on all systems where AMD PMF runs.

As I already said I really believe the whole cooling
device should be registered somewhere else. But if you
do end up sticking with this then you MUST replace
the acpi_video_backlight_use_native() calls with:

if (acpi_video_get_backlight_type() == acpi_backlight_native) {...}

Regards,

Hans





Re: [PATCH 13/15] platform/x86/amd/pmf: Add PMF-AMDGPU set interface

2023-09-27 Thread Hans de Goede
HI,

On 9/26/23 15:17, Christian König wrote:
> Am 26.09.23 um 14:56 schrieb Hans de Goede:
>> Hi,
>>
>> On 9/26/23 13:24, Shyam Sundar S K wrote:
>>> Hi Hans,
>>>
>>> On 9/26/2023 4:05 PM, Hans de Goede wrote:
>>>> Hi,
>>>>
>>>> On 9/22/23 19:50, Shyam Sundar S K wrote:
>>>>> For the Smart PC Solution to fully work, it has to enact to the actions
>>>>> coming from TA. Add the initial code path for set interface to AMDGPU.
>>>>>
>>>>> Co-developed-by: Mario Limonciello 
>>>>> Signed-off-by: Mario Limonciello 
>>>>> Signed-off-by: Shyam Sundar S K 
>>>>> ---
>>>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c | 21 +
>>>>>   drivers/platform/x86/amd/pmf/pmf.h  |  2 ++
>>>>>   drivers/platform/x86/amd/pmf/tee-if.c   | 19 +--
>>>>>   include/linux/amd-pmf-io.h  |  1 +
>>>>>   4 files changed, 41 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c 
>>>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
>>>>> index 232d11833ddc..5c567bff0548 100644
>>>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
>>>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
>>>>> @@ -68,3 +68,24 @@ int amd_pmf_get_gfx_data(struct amd_gpu_pmf_data *pmf)
>>>>>   return 0;
>>>>>   }
>>>>>   EXPORT_SYMBOL_GPL(amd_pmf_get_gfx_data);
>>>>> +
>>>>> +int amd_pmf_set_gfx_data(struct amd_gpu_pmf_data *pmf)
>>>>> +{
>>>>> +    struct drm_device *drm_dev = pci_get_drvdata(pmf->gpu_dev);
>>>>> +    struct amdgpu_device *adev = drm_to_adev(drm_dev);
>>>>> +    struct backlight_device *bd;
>>>>> +
>>>>> +    if (!(adev->flags & AMD_IS_APU)) {
>>>>> +    DRM_ERROR("PMF-AMDGPU interface not supported\n");
>>>>> +    return -ENODEV;
>>>>> +    }
>>>>> +
>>>>> +    bd = backlight_device_get_by_type(BACKLIGHT_RAW);
>>>>> +    if (!bd)
>>>>> +    return -ENODEV;
>>>> This assumes that the backlight is always controller by the amdgpu's
>>>> native backlight driver, but it might e.g. also be handled by
>>>> eacpi-video or by nvidia_wmi_ec_backlight (when using an AMD APU +
>>>> nvidia dgpu).
>>> PMF is meant for AMD APUs(atleast for now) and the _HID will only be
>>> made visible if its AMD laptop. So using amdgpu's native BACKLIGHT_RAW
>>> should be safe, right?
>> Users can pass say acpi_backlight=video and use the acpi_video
>> driver for backlight control instead of the native GPU backlight
>> control.
>>
>>>> For now what should be done here is to call acpi_video_get_backlight_type()
>>>> and then translate the return value from this into a backlight-type:
>>>>
>>>>  acpi_backlight_video    -> BACKLIGHT_FIRMWARE
>>>>  acpi_backlight_vendor,    -> BACKLIGHT_PLATFORM
>>>>  acpi_backlight_native,    -> BACKLIGHT_RAW
>>>>  acpi_backlight_nvidia_wmi_ec,    -> BACKLIGHT_FIRMWARE
>>>>  acpi_backlight_apple_gmux,    -> BACKLIGHT_PLATFORM
>>>>
>>> I can add this change in the v2, do you insist on this?
>> Insist is a strong word, but I think that it is a good idea to have
>> this. Evenutally it looks like this code will need to either integrate with
>> the drm drivers lot more; or the drm core needs to export some special
>> hooks for this which the PMF code can then call.
>>
>> Actually thinking more about this, I think that the right thing to do
>> here is make some code register brightness control as a cooling device
>> (which I think is already done in some cases) and then have the PMF
>> code use the cooling-device APIs for this.
>>
>> IMHO that would be a much cleaner solution then this hack.
> 
> Yeah, fully agree with Hans. This looks like a rather extreme hack to me.

Shyam, the cooling device interface is defined in:

include/linux/thermal.h

And then look for cooling_device .

An example of code registering a cooling_device for backlight control is:

drivers/acpi/acpi_video.c

and then specifically the code starting around line 257 with:

video_get_max_state()

until

static const struct thermal_cooling_device_ops video_cooling_ops = {
...

And the code

Re: [PATCH 13/15] platform/x86/amd/pmf: Add PMF-AMDGPU set interface

2023-09-26 Thread Hans de Goede
Hi,

On 9/26/23 13:24, Shyam Sundar S K wrote:
> Hi Hans,
> 
> On 9/26/2023 4:05 PM, Hans de Goede wrote:
>> Hi,
>>
>> On 9/22/23 19:50, Shyam Sundar S K wrote:
>>> For the Smart PC Solution to fully work, it has to enact to the actions
>>> coming from TA. Add the initial code path for set interface to AMDGPU.
>>>
>>> Co-developed-by: Mario Limonciello 
>>> Signed-off-by: Mario Limonciello 
>>> Signed-off-by: Shyam Sundar S K 
>>> ---
>>>  drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c | 21 +
>>>  drivers/platform/x86/amd/pmf/pmf.h  |  2 ++
>>>  drivers/platform/x86/amd/pmf/tee-if.c   | 19 +--
>>>  include/linux/amd-pmf-io.h  |  1 +
>>>  4 files changed, 41 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c 
>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
>>> index 232d11833ddc..5c567bff0548 100644
>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
>>> @@ -68,3 +68,24 @@ int amd_pmf_get_gfx_data(struct amd_gpu_pmf_data *pmf)
>>> return 0;
>>>  }
>>>  EXPORT_SYMBOL_GPL(amd_pmf_get_gfx_data);
>>> +
>>> +int amd_pmf_set_gfx_data(struct amd_gpu_pmf_data *pmf)
>>> +{
>>> +   struct drm_device *drm_dev = pci_get_drvdata(pmf->gpu_dev);
>>> +   struct amdgpu_device *adev = drm_to_adev(drm_dev);
>>> +   struct backlight_device *bd;
>>> +
>>> +   if (!(adev->flags & AMD_IS_APU)) {
>>> +   DRM_ERROR("PMF-AMDGPU interface not supported\n");
>>> +   return -ENODEV;
>>> +   }
>>> +
>>> +   bd = backlight_device_get_by_type(BACKLIGHT_RAW);
>>> +   if (!bd)
>>> +   return -ENODEV;
>>
>> This assumes that the backlight is always controller by the amdgpu's
>> native backlight driver, but it might e.g. also be handled by
>> eacpi-video or by nvidia_wmi_ec_backlight (when using an AMD APU +
>> nvidia dgpu).
> 
> PMF is meant for AMD APUs(atleast for now) and the _HID will only be
> made visible if its AMD laptop. So using amdgpu's native BACKLIGHT_RAW
> should be safe, right?

Users can pass say acpi_backlight=video and use the acpi_video
driver for backlight control instead of the native GPU backlight
control.

> 
>>
>> For now what should be done here is to call acpi_video_get_backlight_type()
>> and then translate the return value from this into a backlight-type:
>>
>> acpi_backlight_video -> BACKLIGHT_FIRMWARE
>> acpi_backlight_vendor,   -> BACKLIGHT_PLATFORM
>> acpi_backlight_native,   -> BACKLIGHT_RAW
>> acpi_backlight_nvidia_wmi_ec,-> BACKLIGHT_FIRMWARE
>> acpi_backlight_apple_gmux,   -> BACKLIGHT_PLATFORM
>>
> 
> I can add this change in the v2, do you insist on this?

Insist is a strong word, but I think that it is a good idea to have
this. Evenutally it looks like this code will need to either integrate with
the drm drivers lot more; or the drm core needs to export some special
hooks for this which the PMF code can then call.

Actually thinking more about this, I think that the right thing to do
here is make some code register brightness control as a cooling device
(which I think is already done in some cases) and then have the PMF
code use the cooling-device APIs for this.

IMHO that would be a much cleaner solution then this hack.

Regards,

Hans



> 
> Thanks,
> Shyam
> 
>> Also I'm worried about probe order here, this code currently assumes
>> that the GPU or other backlight driver has loaded before this runs,
>> which is not necessarily the case.
>>
>> I think that if the backlight_device_get_by_type() fails this
>> should be retried say every 10 seconds from some delayed workqueue
>> for at least a couple of minutes after boot.
>>
>> Regards,
>>
>> Hans
>>
>>
>>
>>
>>> +
>>> +   backlight_device_set_brightness(bd, pmf->brightness);
>>> +
>>> +   return 0;
>>> +}
>>> +EXPORT_SYMBOL_GPL(amd_pmf_set_gfx_data);
>>> diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
>>> b/drivers/platform/x86/amd/pmf/pmf.h
>>> index 9032df4ba48a..ce89cc0daa5a 100644
>>> --- a/drivers/platform/x86/amd/pmf/pmf.h
>>> +++ b/drivers/platform/x86/amd/pmf/pmf.h
>>> @@ -73,6 +73,7 @@
>>>  #define PMF_POLICY_STT_SKINTEMP_APU7
>>>  #define PMF_POLICY_S

Re: [PATCH 13/15] platform/x86/amd/pmf: Add PMF-AMDGPU set interface

2023-09-26 Thread Hans de Goede
Hi,

On 9/22/23 19:50, Shyam Sundar S K wrote:
> For the Smart PC Solution to fully work, it has to enact to the actions
> coming from TA. Add the initial code path for set interface to AMDGPU.
> 
> Co-developed-by: Mario Limonciello 
> Signed-off-by: Mario Limonciello 
> Signed-off-by: Shyam Sundar S K 
> ---
>  drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c | 21 +
>  drivers/platform/x86/amd/pmf/pmf.h  |  2 ++
>  drivers/platform/x86/amd/pmf/tee-if.c   | 19 +--
>  include/linux/amd-pmf-io.h  |  1 +
>  4 files changed, 41 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c 
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
> index 232d11833ddc..5c567bff0548 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pmf.c
> @@ -68,3 +68,24 @@ int amd_pmf_get_gfx_data(struct amd_gpu_pmf_data *pmf)
>   return 0;
>  }
>  EXPORT_SYMBOL_GPL(amd_pmf_get_gfx_data);
> +
> +int amd_pmf_set_gfx_data(struct amd_gpu_pmf_data *pmf)
> +{
> + struct drm_device *drm_dev = pci_get_drvdata(pmf->gpu_dev);
> + struct amdgpu_device *adev = drm_to_adev(drm_dev);
> + struct backlight_device *bd;
> +
> + if (!(adev->flags & AMD_IS_APU)) {
> + DRM_ERROR("PMF-AMDGPU interface not supported\n");
> + return -ENODEV;
> + }
> +
> + bd = backlight_device_get_by_type(BACKLIGHT_RAW);
> + if (!bd)
> + return -ENODEV;

This assumes that the backlight is always controller by the amdgpu's
native backlight driver, but it might e.g. also be handled by
eacpi-video or by nvidia_wmi_ec_backlight (when using an AMD APU +
nvidia dgpu).

For now what should be done here is to call acpi_video_get_backlight_type()
and then translate the return value from this into a backlight-type:

acpi_backlight_video-> BACKLIGHT_FIRMWARE
acpi_backlight_vendor,  -> BACKLIGHT_PLATFORM
acpi_backlight_native,  -> BACKLIGHT_RAW
acpi_backlight_nvidia_wmi_ec,   -> BACKLIGHT_FIRMWARE
acpi_backlight_apple_gmux,  -> BACKLIGHT_PLATFORM

Also I'm worried about probe order here, this code currently assumes
that the GPU or other backlight driver has loaded before this runs,
which is not necessarily the case.

I think that if the backlight_device_get_by_type() fails this
should be retried say every 10 seconds from some delayed workqueue
for at least a couple of minutes after boot.

Regards,

Hans




> +
> + backlight_device_set_brightness(bd, pmf->brightness);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(amd_pmf_set_gfx_data);
> diff --git a/drivers/platform/x86/amd/pmf/pmf.h 
> b/drivers/platform/x86/amd/pmf/pmf.h
> index 9032df4ba48a..ce89cc0daa5a 100644
> --- a/drivers/platform/x86/amd/pmf/pmf.h
> +++ b/drivers/platform/x86/amd/pmf/pmf.h
> @@ -73,6 +73,7 @@
>  #define PMF_POLICY_STT_SKINTEMP_APU  7
>  #define PMF_POLICY_STT_SKINTEMP_HS2  8
>  #define PMF_POLICY_SYSTEM_STATE  9
> +#define PMF_POLICY_DISPLAY_BRIGHTNESS12
>  #define PMF_POLICY_P3T   38
>  
>  /* TA macros */
> @@ -480,6 +481,7 @@ enum ta_pmf_error_type {
>  };
>  
>  struct pmf_action_table {
> + unsigned long display_brightness;
>   enum system_state system_state;
>   unsigned long spl; /* in mW */
>   unsigned long sppt; /* in mW */
> diff --git a/drivers/platform/x86/amd/pmf/tee-if.c 
> b/drivers/platform/x86/amd/pmf/tee-if.c
> index 1608996654e8..eef83a4c 100644
> --- a/drivers/platform/x86/amd/pmf/tee-if.c
> +++ b/drivers/platform/x86/amd/pmf/tee-if.c
> @@ -79,10 +79,10 @@ static int amd_pmf_update_uevents(struct amd_pmf_dev 
> *dev, u16 event)
>   return 0;
>  }
>  
> -static void amd_pmf_apply_policies(struct amd_pmf_dev *dev, struct 
> ta_pmf_enact_result *out)
> +static int amd_pmf_apply_policies(struct amd_pmf_dev *dev, struct 
> ta_pmf_enact_result *out)
>  {
>   u32 val, event = 0;
> - int idx;
> + int idx, ret;
>  
>   for (idx = 0; idx < out->actions_count; idx++) {
>   val = out->actions_list[idx].value;
> @@ -160,8 +160,23 @@ static void amd_pmf_apply_policies(struct amd_pmf_dev 
> *dev, struct ta_pmf_enact_
>   dev->prev_data->system_state = 0;
>   }
>   break;
> +
> + case PMF_POLICY_DISPLAY_BRIGHTNESS:
> + ret = amd_pmf_get_gfx_data(>gfx_data);
> + if (ret)
> + return ret;
> +
> + dev->prev_data->display_brightness = 
> dev->gfx_data.brightness;
> + if (dev->prev_data->display_brightness != val) {
> + dev->gfx_data.brightness = val;
> + amd_pmf_set_gfx_data(>gfx_data);
> +

Re: [PATCH v3 0/6] drm/amd/display: Pass proper parent for DM backlight device v3

2023-03-16 Thread Hans de Goede
Hi,

On 3/16/23 15:57, Rodrigo Siqueira Jordao wrote:
> 
> 
> On 3/12/23 13:17, Hans de Goede wrote:
>> Hi All,
>>
>> Here is version 3 of my patch series to pass the proper parent device
>> to backlight_device_register().
>>
>> Changes in v3:
>> - Make amdgpu_dm_register_backlight_device() check bl_idx != 1 before
>>    registering the backlight since amdgpu_dm_connector_late_register()
>>    now calls it for _all_ connectors.
>>
>> Changes in v2:
>> - Patches 1 - 5 are new, reworking the code a bit to allow delaying
>>    the registering, so this has turned from a single patch into
>>    a 6 patch set.
>> - Patch 6 now delays the registering of the backlight_dev till
>>    after the drm_connector is registered by doing it from
>>    drm_connector_funcs.late_register.
>>
>> Note this no longer is RFC since this has been successfully
>> tested on 3 laptops which hit the affected code path.
>>
>> Version 3 has also been tested on my personal AMD Ryzen 7 5700G APU
>> desktop machine and now no longer tries to register a backlight
>> device for each connector there.
>>
>> Regards,
>>
>> Hans
>>
>>
>> Hans de Goede (6):
>>    drm/amd/display/amdgpu_dm: Fix backlight_device_register() error
>>  handling
>>    drm/amd/display/amdgpu_dm: Refactor register_backlight_device()
>>    drm/amd/display/amdgpu_dm: Add a bl_idx to amdgpu_dm_connector
>>    drm/amd/display/amdgpu_dm: Move most backlight setup into
>>  setup_backlight_device()
>>    drm/amd/display/amdgpu_dm: Make amdgpu_dm_register_backlight_device()
>>  take an amdgpu_dm_connector
>>    drm/amd/display/amdgpu_dm: Pass proper parent for backlight device
>>  registration v3
>>
>>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 100 --
>>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   1 +
>>   2 files changed, 46 insertions(+), 55 deletions(-)
>>
> 
> Hi,
> 
> First of all, thanks a lot for this patchset.
> 
> I run your series in our CI (IGT-based), and I also conducted some manual 
> tests in my ASICs. Everything looks fine.
> 
> I also reviewed this series, and it LGTM:
> 
> Reviewed-by: Rodrigo Siqueira 
> 
> Finally, I pushed it to amd-staging-drm-next.

Great, thank you.

Regards,

Hans




[PATCH v3 4/6] drm/amd/display/amdgpu_dm: Move most backlight setup into setup_backlight_device()

2023-03-13 Thread Hans de Goede
Rename register_backlight_device() to setup_backlight_device()
and move all backlight setup related calls from
amdgpu_dm_register_backlight_device() and from
amdgpu_dm_initialize_drm_device() there.

This leaves amdgpu_dm_register_backlight_device() dealing purely
with registering the actual backlight class device.

This is a preparation patch for moving the actual backlight class device
registering to drm_connector_funcs.late_register.

Signed-off-by: Hans de Goede 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c   | 17 -
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index eb1f2073b0cf..757202af2eec 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4145,9 +4145,6 @@ amdgpu_dm_register_backlight_device(struct 
amdgpu_display_manager *dm)
char bl_name[16];
struct backlight_properties props = { 0 };
 
-   amdgpu_dm_update_backlight_caps(dm, dm->num_of_edps);
-   dm->brightness[dm->num_of_edps] = AMDGPU_MAX_BL_LEVEL;
-
if (!acpi_video_backlight_use_native()) {
drm_info(adev_to_drm(dm->adev), "Skipping amdgpu DM backlight 
registration\n");
/* Try registering an ACPI video backlight device instead. */
@@ -4216,8 +4213,8 @@ static int initialize_plane(struct amdgpu_display_manager 
*dm,
 }
 
 
-static void register_backlight_device(struct amdgpu_display_manager *dm,
- struct amdgpu_dm_connector *aconnector)
+static void setup_backlight_device(struct amdgpu_display_manager *dm,
+  struct amdgpu_dm_connector *aconnector)
 {
struct dc_link *link = aconnector->dc_link;
int bl_idx = dm->num_of_edps;
@@ -4233,6 +4230,9 @@ static void register_backlight_device(struct 
amdgpu_display_manager *dm,
 
aconnector->bl_idx = bl_idx;
 
+   amdgpu_dm_update_backlight_caps(dm, bl_idx);
+   dm->brightness[bl_idx] = AMDGPU_MAX_BL_LEVEL;
+
amdgpu_dm_register_backlight_device(dm);
if (!dm->backlight_dev[bl_idx]) {
aconnector->bl_idx = -1;
@@ -4241,6 +4241,8 @@ static void register_backlight_device(struct 
amdgpu_display_manager *dm,
 
dm->backlight_link[bl_idx] = link;
dm->num_of_edps++;
+
+   update_connector_ext_caps(aconnector);
 }
 
 static void amdgpu_set_panel_orientation(struct drm_connector *connector);
@@ -4423,10 +4425,7 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
 
if (ret) {

amdgpu_dm_update_connector_after_detect(aconnector);
-   register_backlight_device(dm, aconnector);
-
-   if (dm->num_of_edps)
-   update_connector_ext_caps(aconnector);
+   setup_backlight_device(dm, aconnector);
 
if (psr_feature_enabled)
amdgpu_dm_set_psr_caps(link);
-- 
2.39.1



[PATCH v3 0/6] drm/amd/display: Pass proper parent for DM backlight device v3

2023-03-13 Thread Hans de Goede
Hi All,

Here is version 3 of my patch series to pass the proper parent device
to backlight_device_register().

Changes in v3:
- Make amdgpu_dm_register_backlight_device() check bl_idx != 1 before
  registering the backlight since amdgpu_dm_connector_late_register()
  now calls it for _all_ connectors.

Changes in v2:
- Patches 1 - 5 are new, reworking the code a bit to allow delaying
  the registering, so this has turned from a single patch into
  a 6 patch set.
- Patch 6 now delays the registering of the backlight_dev till
  after the drm_connector is registered by doing it from
  drm_connector_funcs.late_register.

Note this no longer is RFC since this has been successfully
tested on 3 laptops which hit the affected code path.

Version 3 has also been tested on my personal AMD Ryzen 7 5700G APU
desktop machine and now no longer tries to register a backlight
device for each connector there.

Regards,

Hans


Hans de Goede (6):
  drm/amd/display/amdgpu_dm: Fix backlight_device_register() error
handling
  drm/amd/display/amdgpu_dm: Refactor register_backlight_device()
  drm/amd/display/amdgpu_dm: Add a bl_idx to amdgpu_dm_connector
  drm/amd/display/amdgpu_dm: Move most backlight setup into
setup_backlight_device()
  drm/amd/display/amdgpu_dm: Make amdgpu_dm_register_backlight_device()
take an amdgpu_dm_connector
  drm/amd/display/amdgpu_dm: Pass proper parent for backlight device
registration v3

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 100 --
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |   1 +
 2 files changed, 46 insertions(+), 55 deletions(-)

-- 
2.39.1



[PATCH v3 5/6] drm/amd/display/amdgpu_dm: Make amdgpu_dm_register_backlight_device() take an amdgpu_dm_connector

2023-03-13 Thread Hans de Goede
Make amdgpu_dm_register_backlight_device() take an amdgpu_dm_connector
pointer to the connector for which it should register the backlight
as its only argument.

This is a preparation patch for moving the actual backlight class device
registering to drm_connector_funcs.late_register.

Signed-off-by: Hans de Goede 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 24 +--
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 757202af2eec..038bf897cc28 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4140,13 +4140,15 @@ static const struct backlight_ops 
amdgpu_dm_backlight_ops = {
 };
 
 static void
-amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm)
+amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector)
 {
-   char bl_name[16];
+   struct drm_device *drm = aconnector->base.dev;
+   struct amdgpu_display_manager *dm = _to_adev(drm)->dm;
struct backlight_properties props = { 0 };
+   char bl_name[16];
 
if (!acpi_video_backlight_use_native()) {
-   drm_info(adev_to_drm(dm->adev), "Skipping amdgpu DM backlight 
registration\n");
+   drm_info(drm, "Skipping amdgpu DM backlight registration\n");
/* Try registering an ACPI video backlight device instead. */
acpi_video_register_backlight();
return;
@@ -4157,17 +4159,15 @@ amdgpu_dm_register_backlight_device(struct 
amdgpu_display_manager *dm)
props.type = BACKLIGHT_RAW;
 
snprintf(bl_name, sizeof(bl_name), "amdgpu_bl%d",
-adev_to_drm(dm->adev)->primary->index + dm->num_of_edps);
+drm->primary->index + aconnector->bl_idx);
 
-   dm->backlight_dev[dm->num_of_edps] = backlight_device_register(bl_name,
-  
adev_to_drm(dm->adev)->dev,
-  dm,
-  
_dm_backlight_ops,
-  );
+   dm->backlight_dev[aconnector->bl_idx] =
+   backlight_device_register(bl_name, drm->dev, dm,
+ _dm_backlight_ops, );
 
-   if (IS_ERR(dm->backlight_dev[dm->num_of_edps])) {
+   if (IS_ERR(dm->backlight_dev[aconnector->bl_idx])) {
DRM_ERROR("DM: Backlight registration failed!\n");
-   dm->backlight_dev[dm->num_of_edps] = NULL;
+   dm->backlight_dev[aconnector->bl_idx] = NULL;
} else
DRM_DEBUG_DRIVER("DM: Registered Backlight device: %s\n", 
bl_name);
 }
@@ -4233,7 +4233,7 @@ static void setup_backlight_device(struct 
amdgpu_display_manager *dm,
amdgpu_dm_update_backlight_caps(dm, bl_idx);
dm->brightness[bl_idx] = AMDGPU_MAX_BL_LEVEL;
 
-   amdgpu_dm_register_backlight_device(dm);
+   amdgpu_dm_register_backlight_device(aconnector);
if (!dm->backlight_dev[bl_idx]) {
aconnector->bl_idx = -1;
return;
-- 
2.39.1



[PATCH v3 6/6] drm/amd/display/amdgpu_dm: Pass proper parent for backlight device registration v3

2023-03-13 Thread Hans de Goede
The parent for the backlight device should be the drm-connector object,
not the PCI device.

Userspace relies on this to be able to detect which backlight class device
to use on hybrid gfx devices where there may be multiple native (raw)
backlight devices registered.

Specifically gnome-settings-daemon expects the parent device to have
an "enabled" sysfs attribute (as drm_connector devices do) and tests
that this returns "enabled" when read.

This aligns the parent of the backlight device with i915, nouveau, radeon.
Note that drivers/gpu/drm/amd/amdgpu/atombios_encoders.c also already
uses the drm_connector as parent, only amdgpu_dm.c used the PCI device
as parent before this change.

Changes in v3:
Make amdgpu_dm_register_backlight_device() check bl_idx != 1 before
registering the backlight since amdgpu_dm_connector_late_register()
now calls it for _all_ connectors.

Changes in v2:
Together with changing the parent, also move the registration to
drm_connector_funcs.late_register() this is necessary because the parent
device (which now is the drm_connector) must be registered before
the backlight class device is, otherwise the backlight class device ends
up without any parent set at all.

This brings the backlight class device registration timing inline with
nouveau and i915 which also use drm_connector_funcs.late_register()
for this.

Note this slightly changes backlight_device_register() error handling,
instead of not increasing dm->num_of_edps and re-using the current
bl_idx for a potential other backlight device, dm->backlight_dev[bl_idx]
is now simply left NULL on failure. This is ok because all code
looking at dm->backlight_dev[i] also checks it is not NULL.

Link: https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/730
Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 ++
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 038bf897cc28..169b307888c1 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4147,6 +4147,9 @@ amdgpu_dm_register_backlight_device(struct 
amdgpu_dm_connector *aconnector)
struct backlight_properties props = { 0 };
char bl_name[16];
 
+   if (aconnector->bl_idx == -1)
+   return;
+
if (!acpi_video_backlight_use_native()) {
drm_info(drm, "Skipping amdgpu DM backlight registration\n");
/* Try registering an ACPI video backlight device instead. */
@@ -4162,7 +4165,7 @@ amdgpu_dm_register_backlight_device(struct 
amdgpu_dm_connector *aconnector)
 drm->primary->index + aconnector->bl_idx);
 
dm->backlight_dev[aconnector->bl_idx] =
-   backlight_device_register(bl_name, drm->dev, dm,
+   backlight_device_register(bl_name, aconnector->base.kdev, dm,
  _dm_backlight_ops, );
 
if (IS_ERR(dm->backlight_dev[aconnector->bl_idx])) {
@@ -4232,13 +4235,6 @@ static void setup_backlight_device(struct 
amdgpu_display_manager *dm,
 
amdgpu_dm_update_backlight_caps(dm, bl_idx);
dm->brightness[bl_idx] = AMDGPU_MAX_BL_LEVEL;
-
-   amdgpu_dm_register_backlight_device(aconnector);
-   if (!dm->backlight_dev[bl_idx]) {
-   aconnector->bl_idx = -1;
-   return;
-   }
-
dm->backlight_link[bl_idx] = link;
dm->num_of_edps++;
 
@@ -6297,6 +6293,8 @@ amdgpu_dm_connector_late_register(struct drm_connector 
*connector)
to_amdgpu_dm_connector(connector);
int r;
 
+   amdgpu_dm_register_backlight_device(amdgpu_dm_connector);
+
if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
(connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
amdgpu_dm_connector->dm_dp_aux.aux.dev = connector->kdev;
-- 
2.39.1



[PATCH v3 2/6] drm/amd/display/amdgpu_dm: Refactor register_backlight_device()

2023-03-13 Thread Hans de Goede
Refactor register_backlight_device():

1) Turn the connector-type + signal check into an early exit
condition to avoid the indentation level of the rest of the code

2) Add an array bounds check for the arrays indexed by dm->num_of_edps

3) register_backlight_device() always increases dm->num_of_edps if
amdgpu_dm_register_backlight_device() has assigned a backlight_dev to
the current dm->backlight_link[dm->num_of_edps] slot.

So on its next call dm->backlight_dev[dm->num_of_edps] always point to
the next empty slot and the "if (!dm->backlight_dev[dm->num_of_edps])"
check will thus always succeed and can be removed.

4) Add a bl_idx local variable to use as array index, rather then
using dm->num_of_edps to improve the code readability.

Signed-off-by: Hans de Goede 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 ++-
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 42b88ab5552d..1b5efa56ec15 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4231,21 +4231,23 @@ static int initialize_plane(struct 
amdgpu_display_manager *dm,
 static void register_backlight_device(struct amdgpu_display_manager *dm,
  struct dc_link *link)
 {
-   if ((link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) &&
-   link->type != dc_connection_none) {
-   /*
-* Event if registration failed, we should continue with
-* DM initialization because not having a backlight control
-* is better then a black screen.
-*/
-   if (!dm->backlight_dev[dm->num_of_edps])
-   amdgpu_dm_register_backlight_device(dm);
+   int bl_idx = dm->num_of_edps;
 
-   if (dm->backlight_dev[dm->num_of_edps]) {
-   dm->backlight_link[dm->num_of_edps] = link;
-   dm->num_of_edps++;
-   }
+   if (!(link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) ||
+   link->type == dc_connection_none)
+   return;
+
+   if (dm->num_of_edps >= AMDGPU_DM_MAX_NUM_EDP) {
+   drm_warn(adev_to_drm(dm->adev), "Too much eDP connections, 
skipping backlight setup for additional eDPs\n");
+   return;
}
+
+   amdgpu_dm_register_backlight_device(dm);
+   if (!dm->backlight_dev[bl_idx])
+   return;
+
+   dm->backlight_link[bl_idx] = link;
+   dm->num_of_edps++;
 }
 
 static void amdgpu_set_panel_orientation(struct drm_connector *connector);
-- 
2.39.1



Re: [RFC v2 6/6] drm/amd/display: Pass proper parent for DM backlight device registration v2

2023-03-13 Thread Hans de Goede
Hi,

On 3/8/23 22:58, Hans de Goede wrote:
> The parent for the backlight device should be the drm-connector object,
> not the PCI device.
> 
> Userspace relies on this to be able to detect which backlight class device
> to use on hybrid gfx devices where there may be multiple native (raw)
> backlight devices registered.
> 
> Specifically gnome-settings-daemon expects the parent device to have
> an "enabled" sysfs attribute (as drm_connector devices do) and tests
> that this returns "enabled" when read.
> 
> This aligns the parent of the backlight device with i915, nouveau, radeon.
> Note that drivers/gpu/drm/amd/amdgpu/atombios_encoders.c also already
> uses the drm_connector as parent, only amdgpu_dm.c used the PCI device
> as parent before this change.
> 
> Changes in v2:
> Together with changing the parent, also move the registration to
> drm_connector_funcs.late_register() this is necessary because the parent
> device (which now is the drm_connector) must be registered before
> the backlight class device is, otherwise the backlight class device ends
> up without any parent set at all.
> 
> This brings the backlight class device registration timing inline with
> nouveau and i915 which also use drm_connector_funcs.late_register()
> for this.
> 
> Note this slightly changes backlight_device_register() error handling,
> instead of not increasing dm->num_of_edps and re-using the current
> bl_idx for a potential other backlight device, dm->backlight_dev[bl_idx]
> is now simply left NULL on failure. This is ok because all code
> looking at dm->backlight_dev[i] also checks it is not NULL.
> 
> Link: https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/730
> Signed-off-by: Hans de Goede 

Self nack, the amdgpu_dm_register_backlight_device() call in
amdgpu_dm_connector_late_register() leads to the driver now
trying to register a backlight class device for each connector
(I hit this on my AMD APU based desktop machine).

I'll prepare a non RFC version with this fixed.

Regards,

Hans



> ---
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 11 +++
>  1 file changed, 3 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 038bf897cc28..051074d5812f 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -4162,7 +4162,7 @@ amdgpu_dm_register_backlight_device(struct 
> amdgpu_dm_connector *aconnector)
>drm->primary->index + aconnector->bl_idx);
>  
>   dm->backlight_dev[aconnector->bl_idx] =
> - backlight_device_register(bl_name, drm->dev, dm,
> + backlight_device_register(bl_name, aconnector->base.kdev, dm,
> _dm_backlight_ops, );
>  
>   if (IS_ERR(dm->backlight_dev[aconnector->bl_idx])) {
> @@ -4232,13 +4232,6 @@ static void setup_backlight_device(struct 
> amdgpu_display_manager *dm,
>  
>   amdgpu_dm_update_backlight_caps(dm, bl_idx);
>   dm->brightness[bl_idx] = AMDGPU_MAX_BL_LEVEL;
> -
> - amdgpu_dm_register_backlight_device(aconnector);
> - if (!dm->backlight_dev[bl_idx]) {
> - aconnector->bl_idx = -1;
> - return;
> - }
> -
>   dm->backlight_link[bl_idx] = link;
>   dm->num_of_edps++;
>  
> @@ -6297,6 +6290,8 @@ amdgpu_dm_connector_late_register(struct drm_connector 
> *connector)
>   to_amdgpu_dm_connector(connector);
>   int r;
>  
> + amdgpu_dm_register_backlight_device(amdgpu_dm_connector);
> +
>   if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
>   (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
>   amdgpu_dm_connector->dm_dp_aux.aux.dev = connector->kdev;



[PATCH v3 3/6] drm/amd/display/amdgpu_dm: Add a bl_idx to amdgpu_dm_connector

2023-03-13 Thread Hans de Goede
Currently functions like update_connector_ext_caps() and
amdgpu_dm_connector_destroy() are iterating over dm->backlight_link[i]
to find the index of the (optional) backlight_dev associated with
the connector.

Instead make register_backlight_device() store the dm->backlight_dev[]
index used for the connector inside the amdgpu_dm_connector struct.

This removes the need to iterate over the dm->backlight_link[]
array and this is necessary as a preparation patch for moving
the actual backlight_device_register()
call to drm_connector_funcs.late_register.

While reworking update_connector_ext_caps() also remove the aconnector
and aconnector->dc_link NULL checks in this function. These are both
never NULL and are unconditionally derefed in its callers.

Signed-off-by: Hans de Goede 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 42 +++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  1 +
 2 files changed, 17 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 1b5efa56ec15..eb1f2073b0cf 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2936,30 +2936,18 @@ static struct drm_mode_config_helper_funcs 
amdgpu_dm_mode_config_helperfuncs = {
 static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
 {
struct amdgpu_dm_backlight_caps *caps;
-   struct amdgpu_display_manager *dm;
struct drm_connector *conn_base;
struct amdgpu_device *adev;
-   struct dc_link *link = NULL;
struct drm_luminance_range_info *luminance_range;
-   int i;
-
-   if (!aconnector || !aconnector->dc_link)
-   return;
 
-   link = aconnector->dc_link;
-   if (link->connector_signal != SIGNAL_TYPE_EDP)
+   if (aconnector->bl_idx == -1 ||
+   aconnector->dc_link->connector_signal != SIGNAL_TYPE_EDP)
return;
 
conn_base = >base;
adev = drm_to_adev(conn_base->dev);
-   dm = >dm;
-   for (i = 0; i < dm->num_of_edps; i++) {
-   if (link == dm->backlight_link[i])
-   break;
-   }
-   if (i >= dm->num_of_edps)
-   return;
-   caps = >backlight_caps[i];
+
+   caps = >dm.backlight_caps[aconnector->bl_idx];
caps->ext_caps = >dc_link->dpcd_sink_ext_caps;
caps->aux_support = false;
 
@@ -4229,8 +4217,9 @@ static int initialize_plane(struct amdgpu_display_manager 
*dm,
 
 
 static void register_backlight_device(struct amdgpu_display_manager *dm,
- struct dc_link *link)
+ struct amdgpu_dm_connector *aconnector)
 {
+   struct dc_link *link = aconnector->dc_link;
int bl_idx = dm->num_of_edps;
 
if (!(link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) ||
@@ -4242,9 +4231,13 @@ static void register_backlight_device(struct 
amdgpu_display_manager *dm,
return;
}
 
+   aconnector->bl_idx = bl_idx;
+
amdgpu_dm_register_backlight_device(dm);
-   if (!dm->backlight_dev[bl_idx])
+   if (!dm->backlight_dev[bl_idx]) {
+   aconnector->bl_idx = -1;
return;
+   }
 
dm->backlight_link[bl_idx] = link;
dm->num_of_edps++;
@@ -4430,7 +4423,7 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
 
if (ret) {

amdgpu_dm_update_connector_after_detect(aconnector);
-   register_backlight_device(dm, link);
+   register_backlight_device(dm, aconnector);
 
if (dm->num_of_edps)
update_connector_ext_caps(aconnector);
@@ -6211,10 +6204,8 @@ static void amdgpu_dm_connector_unregister(struct 
drm_connector *connector)
 static void amdgpu_dm_connector_destroy(struct drm_connector *connector)
 {
struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
-   const struct dc_link *link = aconnector->dc_link;
struct amdgpu_device *adev = drm_to_adev(connector->dev);
struct amdgpu_display_manager *dm = >dm;
-   int i;
 
/*
 * Call only if mst_mgr was initialized before since it's not done
@@ -6223,11 +6214,9 @@ static void amdgpu_dm_connector_destroy(struct 
drm_connector *connector)
if (aconnector->mst_mgr.dev)
drm_dp_mst_topology_mgr_destroy(>mst_mgr);
 
-   for (i = 0; i < dm->num_of_edps; i++) {
-   if ((link == dm->backlight_link[i]) && dm->backlight_dev[i]) {
-   backlight_device_unregister(dm->backlight_dev[i]);
-  

[PATCH v3 1/6] drm/amd/display/amdgpu_dm: Fix backlight_device_register() error handling

2023-03-13 Thread Hans de Goede
backlight_device_register() returns an ERR_PTR on error, but other code
such as amdgpu_dm_connector_destroy() assumes dm->backlight_dev[i] is NULL
if no backlight is registered.

Clear dm->backlight_dev[i] on registration failure, to avoid other code
trying to deref an ERR_PTR pointer.

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 009ef917dad4..42b88ab5552d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4180,9 +4180,10 @@ amdgpu_dm_register_backlight_device(struct 
amdgpu_display_manager *dm)
   
_dm_backlight_ops,
   );
 
-   if (IS_ERR(dm->backlight_dev[dm->num_of_edps]))
+   if (IS_ERR(dm->backlight_dev[dm->num_of_edps])) {
DRM_ERROR("DM: Backlight registration failed!\n");
-   else
+   dm->backlight_dev[dm->num_of_edps] = NULL;
+   } else
DRM_DEBUG_DRIVER("DM: Registered Backlight device: %s\n", 
bl_name);
 }
 
-- 
2.39.1



Re: [RFC v2 0/6] drm/amd/display: Pass proper parent for DM backlight device v2

2023-03-11 Thread Hans de Goede
Hi Rodrigo,

On 3/10/23 23:12, Rodrigo Siqueira Jordao wrote:
> Hi Hans,
> 
> Which AMD device do you have available for testing this series?

As mentioned in a reply to the cover-letter (should have been
in the cover-letter itself but I forgot, sorry. I don't have
any hw to test this which is why this was marked as a RFC.

In the mean time 2 reporters of:

https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/730

who have affected hw hitting the changed code paths have
confirmed that this series works and that the correct
parent now gets set.

So as I also already mentioned in a reply to the cover-letter (1):

this series no longer is RFC, but is ready for merging (from my pov) now.

> P.s.: If you have a new version of this series, could you also Cc me?

Sure, although atm I see no need to do a new version, please consider
this a non RFC submission now and review it. If the review leads to
changes being requested then I'll prepare a new version and Cc you.

Regards,

Hans



1) Next time mayvw read the entire thread before replying ?








> On 3/8/23 14:58, Hans de Goede wrote:
>> Hi All,
>>
>> Here is version 2 of my patch series to pass the proper parent device
>> to backlight_device_register().
>>
>> New in version 2 is delaying the registering of the backlight_dev till
>> after the drm_connector is registered by doing it from
>> drm_connector_funcs.late_register.
>>
>> This involves first reworking the code a bit to allow delaying
>> the registering, so this has turned from a single patch into
>> a 6 patch set.
>>
>> Regards,
>>
>> Hans
>>
>>
>> Hans de Goede (6):
>>    drm/amd/display/amdgpu_dm: Fix backlight_device_register() error
>>  handling
>>    drm/amd/display/amdgpu_dm: Refactor register_backlight_device()
>>    drm/amd/display/amdgpu_dm: Add a bl_idx to amdgpu_dm_connector
>>    drm/amd/display/amdgpu_dm: Move most backlight setup into
>>  setup_backlight_device()
>>    drm/amd/display/amdgpu_dm: Make amdgpu_dm_register_backlight_device()
>>  take an amdgpu_dm_connector
>>    drm/amd/display: Pass proper parent for DM backlight device
>>  registration v2
>>
>>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 99 ---
>>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  1 +
>>   2 files changed, 44 insertions(+), 56 deletions(-)
>>
> 



Re: [RFC v2 0/6] drm/amd/display: Pass proper parent for DM backlight device v2

2023-03-09 Thread Hans de Goede
Hi all,

On 3/8/23 23:10, Hans de Goede wrote:
> Hi,
> 
> On 3/8/23 22:58, Hans de Goede wrote:
>> Hi All,
>>
>> Here is version 2 of my patch series to pass the proper parent device
>> to backlight_device_register().
>>
>> New in version 2 is delaying the registering of the backlight_dev till
>> after the drm_connector is registered by doing it from
>> drm_connector_funcs.late_register.
>>
>> This involves first reworking the code a bit to allow delaying
>> the registering, so this has turned from a single patch into
>> a 6 patch set.
>>
>> Regards,
>>
>> Hans
> 
> p.s.
> 
> Like last time this series is marked as RFC because I don't have hw
> to test the fix myself. The previous version was tested by 2 reporters
> of: https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/730
> 
> I hope to get test results from them for this new version soon.

I just heard back from one of the reporters that this fixes 
gnome-settings-daemon
picking the wrong backlight device on a hybrid gfx laptop where both GPU-s
register a native backlight control.

So this series no longer is RFC, but is ready for merging (from my pov) now.

Regards,

Hans





>> Hans de Goede (6):
>>   drm/amd/display/amdgpu_dm: Fix backlight_device_register() error
>> handling
>>   drm/amd/display/amdgpu_dm: Refactor register_backlight_device()
>>   drm/amd/display/amdgpu_dm: Add a bl_idx to amdgpu_dm_connector
>>   drm/amd/display/amdgpu_dm: Move most backlight setup into
>> setup_backlight_device()
>>   drm/amd/display/amdgpu_dm: Make amdgpu_dm_register_backlight_device()
>> take an amdgpu_dm_connector
>>   drm/amd/display: Pass proper parent for DM backlight device
>> registration v2
>>
>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 99 ---
>>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  1 +
>>  2 files changed, 44 insertions(+), 56 deletions(-)
>>
> 



Re: [RFC v2 0/6] drm/amd/display: Pass proper parent for DM backlight device v2

2023-03-08 Thread Hans de Goede
Hi,

On 3/8/23 22:58, Hans de Goede wrote:
> Hi All,
> 
> Here is version 2 of my patch series to pass the proper parent device
> to backlight_device_register().
> 
> New in version 2 is delaying the registering of the backlight_dev till
> after the drm_connector is registered by doing it from
> drm_connector_funcs.late_register.
> 
> This involves first reworking the code a bit to allow delaying
> the registering, so this has turned from a single patch into
> a 6 patch set.
> 
> Regards,
> 
> Hans

p.s.

Like last time this series is marked as RFC because I don't have hw
to test the fix myself. The previous version was tested by 2 reporters
of: https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/730

I hope to get test results from them for this new version soon.


> 
> 
> Hans de Goede (6):
>   drm/amd/display/amdgpu_dm: Fix backlight_device_register() error
> handling
>   drm/amd/display/amdgpu_dm: Refactor register_backlight_device()
>   drm/amd/display/amdgpu_dm: Add a bl_idx to amdgpu_dm_connector
>   drm/amd/display/amdgpu_dm: Move most backlight setup into
> setup_backlight_device()
>   drm/amd/display/amdgpu_dm: Make amdgpu_dm_register_backlight_device()
> take an amdgpu_dm_connector
>   drm/amd/display: Pass proper parent for DM backlight device
> registration v2
> 
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 99 ---
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  1 +
>  2 files changed, 44 insertions(+), 56 deletions(-)
> 



[RFC v2 2/6] drm/amd/display/amdgpu_dm: Refactor register_backlight_device()

2023-03-08 Thread Hans de Goede
Refactor register_backlight_device():

1) Turn the connector-type + signal check into an early exit
condition to avoid the indentation level of the rest of the code

2) Add an array bounds check for the arrays indexed by dm->num_of_edps

3) register_backlight_device() always increases dm->num_of_edps if
amdgpu_dm_register_backlight_device() has assigned a backlight_dev to
the current dm->backlight_link[dm->num_of_edps] slot.

So on its next call dm->backlight_dev[dm->num_of_edps] always point to
the next empty slot and the "if (!dm->backlight_dev[dm->num_of_edps])"
check will thus always succeed and can be removed.

4) Add a bl_idx local variable to use as array index, rather then
using dm->num_of_edps to improve the code readability.

Signed-off-by: Hans de Goede 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 28 ++-
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 42b88ab5552d..1b5efa56ec15 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4231,21 +4231,23 @@ static int initialize_plane(struct 
amdgpu_display_manager *dm,
 static void register_backlight_device(struct amdgpu_display_manager *dm,
  struct dc_link *link)
 {
-   if ((link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) &&
-   link->type != dc_connection_none) {
-   /*
-* Event if registration failed, we should continue with
-* DM initialization because not having a backlight control
-* is better then a black screen.
-*/
-   if (!dm->backlight_dev[dm->num_of_edps])
-   amdgpu_dm_register_backlight_device(dm);
+   int bl_idx = dm->num_of_edps;
 
-   if (dm->backlight_dev[dm->num_of_edps]) {
-   dm->backlight_link[dm->num_of_edps] = link;
-   dm->num_of_edps++;
-   }
+   if (!(link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) ||
+   link->type == dc_connection_none)
+   return;
+
+   if (dm->num_of_edps >= AMDGPU_DM_MAX_NUM_EDP) {
+   drm_warn(adev_to_drm(dm->adev), "Too much eDP connections, 
skipping backlight setup for additional eDPs\n");
+   return;
}
+
+   amdgpu_dm_register_backlight_device(dm);
+   if (!dm->backlight_dev[bl_idx])
+   return;
+
+   dm->backlight_link[bl_idx] = link;
+   dm->num_of_edps++;
 }
 
 static void amdgpu_set_panel_orientation(struct drm_connector *connector);
-- 
2.39.1



[RFC v2 1/6] drm/amd/display/amdgpu_dm: Fix backlight_device_register() error handling

2023-03-08 Thread Hans de Goede
backlight_device_register() returns an ERR_PTR on error, but other code
such as amdgpu_dm_connector_destroy() assumes dm->backlight_dev[i] is NULL
if no backlight is registered.

Clear dm->backlight_dev[i] on registration failure, to avoid other code
trying to deref an ERR_PTR pointer.

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 009ef917dad4..42b88ab5552d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4180,9 +4180,10 @@ amdgpu_dm_register_backlight_device(struct 
amdgpu_display_manager *dm)
   
_dm_backlight_ops,
   );
 
-   if (IS_ERR(dm->backlight_dev[dm->num_of_edps]))
+   if (IS_ERR(dm->backlight_dev[dm->num_of_edps])) {
DRM_ERROR("DM: Backlight registration failed!\n");
-   else
+   dm->backlight_dev[dm->num_of_edps] = NULL;
+   } else
DRM_DEBUG_DRIVER("DM: Registered Backlight device: %s\n", 
bl_name);
 }
 
-- 
2.39.1



[RFC v2 5/6] drm/amd/display/amdgpu_dm: Make amdgpu_dm_register_backlight_device() take an amdgpu_dm_connector

2023-03-08 Thread Hans de Goede
Make amdgpu_dm_register_backlight_device() take an amdgpu_dm_connector
pointer to the connector for which it should register the backlight
as its only argument.

This is a preparation patch for moving the actual backlight class device
registering to drm_connector_funcs.late_register.

Signed-off-by: Hans de Goede 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 24 +--
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 757202af2eec..038bf897cc28 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4140,13 +4140,15 @@ static const struct backlight_ops 
amdgpu_dm_backlight_ops = {
 };
 
 static void
-amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm)
+amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector)
 {
-   char bl_name[16];
+   struct drm_device *drm = aconnector->base.dev;
+   struct amdgpu_display_manager *dm = _to_adev(drm)->dm;
struct backlight_properties props = { 0 };
+   char bl_name[16];
 
if (!acpi_video_backlight_use_native()) {
-   drm_info(adev_to_drm(dm->adev), "Skipping amdgpu DM backlight 
registration\n");
+   drm_info(drm, "Skipping amdgpu DM backlight registration\n");
/* Try registering an ACPI video backlight device instead. */
acpi_video_register_backlight();
return;
@@ -4157,17 +4159,15 @@ amdgpu_dm_register_backlight_device(struct 
amdgpu_display_manager *dm)
props.type = BACKLIGHT_RAW;
 
snprintf(bl_name, sizeof(bl_name), "amdgpu_bl%d",
-adev_to_drm(dm->adev)->primary->index + dm->num_of_edps);
+drm->primary->index + aconnector->bl_idx);
 
-   dm->backlight_dev[dm->num_of_edps] = backlight_device_register(bl_name,
-  
adev_to_drm(dm->adev)->dev,
-  dm,
-  
_dm_backlight_ops,
-  );
+   dm->backlight_dev[aconnector->bl_idx] =
+   backlight_device_register(bl_name, drm->dev, dm,
+ _dm_backlight_ops, );
 
-   if (IS_ERR(dm->backlight_dev[dm->num_of_edps])) {
+   if (IS_ERR(dm->backlight_dev[aconnector->bl_idx])) {
DRM_ERROR("DM: Backlight registration failed!\n");
-   dm->backlight_dev[dm->num_of_edps] = NULL;
+   dm->backlight_dev[aconnector->bl_idx] = NULL;
} else
DRM_DEBUG_DRIVER("DM: Registered Backlight device: %s\n", 
bl_name);
 }
@@ -4233,7 +4233,7 @@ static void setup_backlight_device(struct 
amdgpu_display_manager *dm,
amdgpu_dm_update_backlight_caps(dm, bl_idx);
dm->brightness[bl_idx] = AMDGPU_MAX_BL_LEVEL;
 
-   amdgpu_dm_register_backlight_device(dm);
+   amdgpu_dm_register_backlight_device(aconnector);
if (!dm->backlight_dev[bl_idx]) {
aconnector->bl_idx = -1;
return;
-- 
2.39.1



[RFC v2 4/6] drm/amd/display/amdgpu_dm: Move most backlight setup into setup_backlight_device()

2023-03-08 Thread Hans de Goede
Rename register_backlight_device() to setup_backlight_device()
and move all backlight setup related calls from
amdgpu_dm_register_backlight_device() and from
amdgpu_dm_initialize_drm_device() there.

This leaves amdgpu_dm_register_backlight_device() dealing purely
with registering the actual backlight class device.

This is a preparation patch for moving the actual backlight class device
registering to drm_connector_funcs.late_register.

Signed-off-by: Hans de Goede 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c   | 17 -
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index eb1f2073b0cf..757202af2eec 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4145,9 +4145,6 @@ amdgpu_dm_register_backlight_device(struct 
amdgpu_display_manager *dm)
char bl_name[16];
struct backlight_properties props = { 0 };
 
-   amdgpu_dm_update_backlight_caps(dm, dm->num_of_edps);
-   dm->brightness[dm->num_of_edps] = AMDGPU_MAX_BL_LEVEL;
-
if (!acpi_video_backlight_use_native()) {
drm_info(adev_to_drm(dm->adev), "Skipping amdgpu DM backlight 
registration\n");
/* Try registering an ACPI video backlight device instead. */
@@ -4216,8 +4213,8 @@ static int initialize_plane(struct amdgpu_display_manager 
*dm,
 }
 
 
-static void register_backlight_device(struct amdgpu_display_manager *dm,
- struct amdgpu_dm_connector *aconnector)
+static void setup_backlight_device(struct amdgpu_display_manager *dm,
+  struct amdgpu_dm_connector *aconnector)
 {
struct dc_link *link = aconnector->dc_link;
int bl_idx = dm->num_of_edps;
@@ -4233,6 +4230,9 @@ static void register_backlight_device(struct 
amdgpu_display_manager *dm,
 
aconnector->bl_idx = bl_idx;
 
+   amdgpu_dm_update_backlight_caps(dm, bl_idx);
+   dm->brightness[bl_idx] = AMDGPU_MAX_BL_LEVEL;
+
amdgpu_dm_register_backlight_device(dm);
if (!dm->backlight_dev[bl_idx]) {
aconnector->bl_idx = -1;
@@ -4241,6 +4241,8 @@ static void register_backlight_device(struct 
amdgpu_display_manager *dm,
 
dm->backlight_link[bl_idx] = link;
dm->num_of_edps++;
+
+   update_connector_ext_caps(aconnector);
 }
 
 static void amdgpu_set_panel_orientation(struct drm_connector *connector);
@@ -4423,10 +4425,7 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
 
if (ret) {

amdgpu_dm_update_connector_after_detect(aconnector);
-   register_backlight_device(dm, aconnector);
-
-   if (dm->num_of_edps)
-   update_connector_ext_caps(aconnector);
+   setup_backlight_device(dm, aconnector);
 
if (psr_feature_enabled)
amdgpu_dm_set_psr_caps(link);
-- 
2.39.1



[RFC v2 0/6] drm/amd/display: Pass proper parent for DM backlight device v2

2023-03-08 Thread Hans de Goede
Hi All,

Here is version 2 of my patch series to pass the proper parent device
to backlight_device_register().

New in version 2 is delaying the registering of the backlight_dev till
after the drm_connector is registered by doing it from
drm_connector_funcs.late_register.

This involves first reworking the code a bit to allow delaying
the registering, so this has turned from a single patch into
a 6 patch set.

Regards,

Hans


Hans de Goede (6):
  drm/amd/display/amdgpu_dm: Fix backlight_device_register() error
handling
  drm/amd/display/amdgpu_dm: Refactor register_backlight_device()
  drm/amd/display/amdgpu_dm: Add a bl_idx to amdgpu_dm_connector
  drm/amd/display/amdgpu_dm: Move most backlight setup into
setup_backlight_device()
  drm/amd/display/amdgpu_dm: Make amdgpu_dm_register_backlight_device()
take an amdgpu_dm_connector
  drm/amd/display: Pass proper parent for DM backlight device
registration v2

 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 99 ---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  1 +
 2 files changed, 44 insertions(+), 56 deletions(-)

-- 
2.39.1



[RFC v2 3/6] drm/amd/display/amdgpu_dm: Add a bl_idx to amdgpu_dm_connector

2023-03-08 Thread Hans de Goede
Currently functions like update_connector_ext_caps() and
amdgpu_dm_connector_destroy() are iterating over dm->backlight_link[i]
to find the index of the (optional) backlight_dev associated with
the connector.

Instead make register_backlight_device() store the dm->backlight_dev[]
index used for the connector inside the amdgpu_dm_connector struct.

This removes the need to iterate over the dm->backlight_link[]
array and this is necessary as a preparation patch for moving
the actual backlight_device_register()
call to drm_connector_funcs.late_register.

While reworking update_connector_ext_caps() also remove the aconnector
and aconnector->dc_link NULL checks in this function. These are both
never NULL and are unconditionally derefed in its callers.

Signed-off-by: Hans de Goede 
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 42 +++
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h |  1 +
 2 files changed, 17 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 1b5efa56ec15..eb1f2073b0cf 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2936,30 +2936,18 @@ static struct drm_mode_config_helper_funcs 
amdgpu_dm_mode_config_helperfuncs = {
 static void update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
 {
struct amdgpu_dm_backlight_caps *caps;
-   struct amdgpu_display_manager *dm;
struct drm_connector *conn_base;
struct amdgpu_device *adev;
-   struct dc_link *link = NULL;
struct drm_luminance_range_info *luminance_range;
-   int i;
-
-   if (!aconnector || !aconnector->dc_link)
-   return;
 
-   link = aconnector->dc_link;
-   if (link->connector_signal != SIGNAL_TYPE_EDP)
+   if (aconnector->bl_idx == -1 ||
+   aconnector->dc_link->connector_signal != SIGNAL_TYPE_EDP)
return;
 
conn_base = >base;
adev = drm_to_adev(conn_base->dev);
-   dm = >dm;
-   for (i = 0; i < dm->num_of_edps; i++) {
-   if (link == dm->backlight_link[i])
-   break;
-   }
-   if (i >= dm->num_of_edps)
-   return;
-   caps = >backlight_caps[i];
+
+   caps = >dm.backlight_caps[aconnector->bl_idx];
caps->ext_caps = >dc_link->dpcd_sink_ext_caps;
caps->aux_support = false;
 
@@ -4229,8 +4217,9 @@ static int initialize_plane(struct amdgpu_display_manager 
*dm,
 
 
 static void register_backlight_device(struct amdgpu_display_manager *dm,
- struct dc_link *link)
+ struct amdgpu_dm_connector *aconnector)
 {
+   struct dc_link *link = aconnector->dc_link;
int bl_idx = dm->num_of_edps;
 
if (!(link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) ||
@@ -4242,9 +4231,13 @@ static void register_backlight_device(struct 
amdgpu_display_manager *dm,
return;
}
 
+   aconnector->bl_idx = bl_idx;
+
amdgpu_dm_register_backlight_device(dm);
-   if (!dm->backlight_dev[bl_idx])
+   if (!dm->backlight_dev[bl_idx]) {
+   aconnector->bl_idx = -1;
return;
+   }
 
dm->backlight_link[bl_idx] = link;
dm->num_of_edps++;
@@ -4430,7 +4423,7 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
 
if (ret) {

amdgpu_dm_update_connector_after_detect(aconnector);
-   register_backlight_device(dm, link);
+   register_backlight_device(dm, aconnector);
 
if (dm->num_of_edps)
update_connector_ext_caps(aconnector);
@@ -6211,10 +6204,8 @@ static void amdgpu_dm_connector_unregister(struct 
drm_connector *connector)
 static void amdgpu_dm_connector_destroy(struct drm_connector *connector)
 {
struct amdgpu_dm_connector *aconnector = 
to_amdgpu_dm_connector(connector);
-   const struct dc_link *link = aconnector->dc_link;
struct amdgpu_device *adev = drm_to_adev(connector->dev);
struct amdgpu_display_manager *dm = >dm;
-   int i;
 
/*
 * Call only if mst_mgr was initialized before since it's not done
@@ -6223,11 +6214,9 @@ static void amdgpu_dm_connector_destroy(struct 
drm_connector *connector)
if (aconnector->mst_mgr.dev)
drm_dp_mst_topology_mgr_destroy(>mst_mgr);
 
-   for (i = 0; i < dm->num_of_edps; i++) {
-   if ((link == dm->backlight_link[i]) && dm->backlight_dev[i]) {
-   backlight_device_unregister(dm->backlight_dev[i]);
-  

[RFC v2 6/6] drm/amd/display: Pass proper parent for DM backlight device registration v2

2023-03-08 Thread Hans de Goede
The parent for the backlight device should be the drm-connector object,
not the PCI device.

Userspace relies on this to be able to detect which backlight class device
to use on hybrid gfx devices where there may be multiple native (raw)
backlight devices registered.

Specifically gnome-settings-daemon expects the parent device to have
an "enabled" sysfs attribute (as drm_connector devices do) and tests
that this returns "enabled" when read.

This aligns the parent of the backlight device with i915, nouveau, radeon.
Note that drivers/gpu/drm/amd/amdgpu/atombios_encoders.c also already
uses the drm_connector as parent, only amdgpu_dm.c used the PCI device
as parent before this change.

Changes in v2:
Together with changing the parent, also move the registration to
drm_connector_funcs.late_register() this is necessary because the parent
device (which now is the drm_connector) must be registered before
the backlight class device is, otherwise the backlight class device ends
up without any parent set at all.

This brings the backlight class device registration timing inline with
nouveau and i915 which also use drm_connector_funcs.late_register()
for this.

Note this slightly changes backlight_device_register() error handling,
instead of not increasing dm->num_of_edps and re-using the current
bl_idx for a potential other backlight device, dm->backlight_dev[bl_idx]
is now simply left NULL on failure. This is ok because all code
looking at dm->backlight_dev[i] also checks it is not NULL.

Link: https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/730
Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 038bf897cc28..051074d5812f 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4162,7 +4162,7 @@ amdgpu_dm_register_backlight_device(struct 
amdgpu_dm_connector *aconnector)
 drm->primary->index + aconnector->bl_idx);
 
dm->backlight_dev[aconnector->bl_idx] =
-   backlight_device_register(bl_name, drm->dev, dm,
+   backlight_device_register(bl_name, aconnector->base.kdev, dm,
  _dm_backlight_ops, );
 
if (IS_ERR(dm->backlight_dev[aconnector->bl_idx])) {
@@ -4232,13 +4232,6 @@ static void setup_backlight_device(struct 
amdgpu_display_manager *dm,
 
amdgpu_dm_update_backlight_caps(dm, bl_idx);
dm->brightness[bl_idx] = AMDGPU_MAX_BL_LEVEL;
-
-   amdgpu_dm_register_backlight_device(aconnector);
-   if (!dm->backlight_dev[bl_idx]) {
-   aconnector->bl_idx = -1;
-   return;
-   }
-
dm->backlight_link[bl_idx] = link;
dm->num_of_edps++;
 
@@ -6297,6 +6290,8 @@ amdgpu_dm_connector_late_register(struct drm_connector 
*connector)
to_amdgpu_dm_connector(connector);
int r;
 
+   amdgpu_dm_register_backlight_device(amdgpu_dm_connector);
+
if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
(connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
amdgpu_dm_connector->dm_dp_aux.aux.dev = connector->kdev;
-- 
2.39.1



Re: [RFC] drm/amd/display: Pass proper parent for DM backlight device registration

2023-03-08 Thread Hans de Goede
Hi,

On 2/15/23 12:38, Hans de Goede wrote:
> The parent for the backlight device should be the drm-connector object,
> not the PCI device.
> 
> Userspace relies on this to be able to detect which backlight class device
> to use on hybrid gfx devices where there may be multiple native (raw)
> backlight devices registered.
> 
> Specifically gnome-settings-daemon expects the parent device to have
> an "enabled" sysfs attribute (as drm_connector devices do) and tests
> that this returns "enabled" when read.
> 
> This aligns the parent of the backlight device with i915, nouveau, radeon.
> Note that drivers/gpu/drm/amd/amdgpu/atombios_encoders.c also already
> uses the drm_connector as parent, only amdgpu_dm.c used the PCI device
> as parent before this change.
> 
> Note this is marked as a RFC because I don't have hw to test, so this
> has only been compile tested! If someone can test this on actual
> hw which hits the changed code path that would be great.
> 
> Link: https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/730
> Signed-off-by: Hans de Goede 

Self NACK. This has been tested by 2 reporters of:

https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/730

Now and it does not work. Instead of setting the parent device pointer 
correctly,
this makes the backlight device not have a parent device any more at all.
I already was afraid this might happen, since the drm_connector object is not 
yet
registered at the time when the amdgpu code calls backlight_device_register().

Other drivers like e.g. nouveau register the backlight later from
a drm_connector_funcs.late_register callback. I was hoping doing it
the simple way as this patch did would work, but it looks like some bigger
changes to the amdgpu code (using a drm_connector_funcs.late_register callback)
are necessary.

I'll try to make some time to prepare a new patch.

Regards,

Hans



> ---
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
> b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 31bce529f685..33b0e1de2770 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -4065,7 +4065,8 @@ static const struct backlight_ops 
> amdgpu_dm_backlight_ops = {
>  };
>  
>  static void
> -amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm)
> +amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm,
> + struct amdgpu_dm_connector *aconnector)
>  {
>   char bl_name[16];
>   struct backlight_properties props = { 0 };
> @@ -4088,7 +4089,7 @@ amdgpu_dm_register_backlight_device(struct 
> amdgpu_display_manager *dm)
>adev_to_drm(dm->adev)->primary->index + dm->num_of_edps);
>  
>   dm->backlight_dev[dm->num_of_edps] = backlight_device_register(bl_name,
> -
> adev_to_drm(dm->adev)->dev,
> +
> aconnector->base.kdev,
>  dm,
>  
> _dm_backlight_ops,
>  );
> @@ -4141,6 +4142,7 @@ static int initialize_plane(struct 
> amdgpu_display_manager *dm,
>  
>  
>  static void register_backlight_device(struct amdgpu_display_manager *dm,
> +   struct amdgpu_dm_connector *aconnector,
> struct dc_link *link)
>  {
>   if ((link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) &&
> @@ -4151,7 +4153,7 @@ static void register_backlight_device(struct 
> amdgpu_display_manager *dm,
>* is better then a black screen.
>*/
>   if (!dm->backlight_dev[dm->num_of_edps])
> - amdgpu_dm_register_backlight_device(dm);
> + amdgpu_dm_register_backlight_device(dm, aconnector);
>  
>   if (dm->backlight_dev[dm->num_of_edps]) {
>   dm->backlight_link[dm->num_of_edps] = link;
> @@ -4337,7 +4339,7 @@ static int amdgpu_dm_initialize_drm_device(struct 
> amdgpu_device *adev)
>  
>   if (ret) {
>   
> amdgpu_dm_update_connector_after_detect(aconnector);
> - register_backlight_device(dm, link);
> + register_backlight_device(dm, aconnector, link);
>  
>   if (dm->num_of_edps)
>   update_connector_ext_caps(aconnector);



[RFC] drm/amd/display: Pass proper parent for DM backlight device registration

2023-02-15 Thread Hans de Goede
The parent for the backlight device should be the drm-connector object,
not the PCI device.

Userspace relies on this to be able to detect which backlight class device
to use on hybrid gfx devices where there may be multiple native (raw)
backlight devices registered.

Specifically gnome-settings-daemon expects the parent device to have
an "enabled" sysfs attribute (as drm_connector devices do) and tests
that this returns "enabled" when read.

This aligns the parent of the backlight device with i915, nouveau, radeon.
Note that drivers/gpu/drm/amd/amdgpu/atombios_encoders.c also already
uses the drm_connector as parent, only amdgpu_dm.c used the PCI device
as parent before this change.

Note this is marked as a RFC because I don't have hw to test, so this
has only been compile tested! If someone can test this on actual
hw which hits the changed code path that would be great.

Link: https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/730
Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 31bce529f685..33b0e1de2770 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4065,7 +4065,8 @@ static const struct backlight_ops amdgpu_dm_backlight_ops 
= {
 };
 
 static void
-amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm)
+amdgpu_dm_register_backlight_device(struct amdgpu_display_manager *dm,
+   struct amdgpu_dm_connector *aconnector)
 {
char bl_name[16];
struct backlight_properties props = { 0 };
@@ -4088,7 +4089,7 @@ amdgpu_dm_register_backlight_device(struct 
amdgpu_display_manager *dm)
 adev_to_drm(dm->adev)->primary->index + dm->num_of_edps);
 
dm->backlight_dev[dm->num_of_edps] = backlight_device_register(bl_name,
-  
adev_to_drm(dm->adev)->dev,
+  
aconnector->base.kdev,
   dm,
   
_dm_backlight_ops,
   );
@@ -4141,6 +4142,7 @@ static int initialize_plane(struct amdgpu_display_manager 
*dm,
 
 
 static void register_backlight_device(struct amdgpu_display_manager *dm,
+ struct amdgpu_dm_connector *aconnector,
  struct dc_link *link)
 {
if ((link->connector_signal & (SIGNAL_TYPE_EDP | SIGNAL_TYPE_LVDS)) &&
@@ -4151,7 +4153,7 @@ static void register_backlight_device(struct 
amdgpu_display_manager *dm,
 * is better then a black screen.
 */
if (!dm->backlight_dev[dm->num_of_edps])
-   amdgpu_dm_register_backlight_device(dm);
+   amdgpu_dm_register_backlight_device(dm, aconnector);
 
if (dm->backlight_dev[dm->num_of_edps]) {
dm->backlight_link[dm->num_of_edps] = link;
@@ -4337,7 +4339,7 @@ static int amdgpu_dm_initialize_drm_device(struct 
amdgpu_device *adev)
 
if (ret) {

amdgpu_dm_update_connector_after_detect(aconnector);
-   register_backlight_device(dm, link);
+   register_backlight_device(dm, aconnector, link);
 
if (dm->num_of_edps)
update_connector_ext_caps(aconnector);
-- 
2.39.1



Re: [RFC PATCH 1/9] apple-gmux: use cpu_to_be32 instead of manual reorder

2023-02-13 Thread Hans de Goede
Hi,

On 2/11/23 00:30, Orlando Chamberlain wrote:
> On Fri, 10 Feb 2023 20:19:27 +0100
> Hans de Goede  wrote:
> 
>> Hi,
>>
>> On 2/10/23 20:09, Hans de Goede wrote:
>>> Hi,
>>>
>>> On 2/10/23 05:48, Orlando Chamberlain wrote:  
>>>> Currently it manually flips the byte order, but we can instead use
>>>> cpu_to_be32(val) for this.
>>>>
>>>> Signed-off-by: Orlando Chamberlain 
>>>> ---
>>>>  drivers/platform/x86/apple-gmux.c | 18 ++
>>>>  1 file changed, 2 insertions(+), 16 deletions(-)
>>>>
>>>> diff --git a/drivers/platform/x86/apple-gmux.c
>>>> b/drivers/platform/x86/apple-gmux.c index
>>>> 9333f82cfa8a..e8cb084cb81f 100644 ---
>>>> a/drivers/platform/x86/apple-gmux.c +++
>>>> b/drivers/platform/x86/apple-gmux.c @@ -94,13 +94,7 @@ static u32
>>>> gmux_pio_read32(struct apple_gmux_data *gmux_data, int port)
>>>> static void gmux_pio_write32(struct apple_gmux_data *gmux_data,
>>>> int port, u32 val) {
>>>> -  int i;
>>>> -  u8 tmpval;
>>>> -
>>>> -  for (i = 0; i < 4; i++) {
>>>> -  tmpval = (val >> (i * 8)) & 0xff;
>>>> -  outb(tmpval, gmux_data->iostart + port + i);
>>>> -  }
>>>> +  outl(cpu_to_be32(val), gmux_data->iostart + port);
>>>>  }
>>>>  
>>>>  static int gmux_index_wait_ready(struct apple_gmux_data
>>>> *gmux_data)  
>>>
>>> The ioport / indexed-ioport accessed apple_gmux-es likely are (part
>>> of?) LPC bus devices . Looking at the bus level you are now
>>> changing 4 io accesses with a size of 1 byte, to 1 32 bit io-access.
>>>
>>> Depending on the decoding hw in the chip this may work fine,
>>> or this may work not at all.
>>>
>>> I realized that you have asked for more testing, but most surviving
>>> macbooks from the older apple-gmux era appear to be models without
>>> a discrete GPU (which are often the first thing to break) and thus
>>> without a gmux.
>>>
>>> Unless we get a bunch of testers to show up, which I doubt. I would
>>> prefer slightly bigger / less pretty code and not change the
>>> functional behavior of the driver on these older models.  
>>
>> A quick follow up on this, I just noticed that only the pio_write32
>> is doing the one byte at a time thing:
>>
>> static u32 gmux_pio_read32(struct apple_gmux_data *gmux_data, int
>> port) {
>> return inl(gmux_data->iostart + port);
>> }
>>
>> static void gmux_pio_write32(struct apple_gmux_data *gmux_data, int
>> port, u32 val)
>> {
>> int i;
>> u8 tmpval;
>>
>> for (i = 0; i < 4; i++) {
>> tmpval = (val >> (i * 8)) & 0xff;
>> outb(tmpval, gmux_data->iostart + port + i);
>> }
>> }
>>
>> And if you look closely gmux_pio_write32() is not swapping
>> the order to be32 at all, it is just taking the bytes
>> in little-endian memory order, starting with the first
>> (index 0) byte which is the least significant byte of
>> the value.
>>
>> On x86 the original code is no different then doing:
>>
>> static void gmux_pio_write32(struct apple_gmux_data *gmux_data, int
>> port, u32 val)
>> {
>> u8 *data = (u8 *)
>> int i;
>>
>> for (i = 0; i < 4; i++)
>> outb(data[i], gmux_data->iostart + port + i);
>> }
>>
>> So yeah this patch is definitely wrong, it actually swaps
>> the byte order compared to the original code. Which becomes
>> clear when you look the weird difference between the read32 and
>> write32 functions after this patch.
>>
>> Presumably there is a specific reason why gmux_pio_write32()
>> is not already doing a single outl(..., val) and byte-ordering
>> is not the reason.
>>
>> Regards,
>>
>> Hans
> 
> Sounds like it may be better to just drop this patch as there's very
> little benefit for the risk of causing a regression.

Yes if it is easy to drop this please drop this.

And the same more or less applies to 2/9. I would rather have
an extra "if () ... else ..."  in the code in a couple of places
then change behavior on old hw where we cannot get proper test
coverage (but will likely eventually get regressions reports
if we break things).

Thanks & Regards,

Hans



>>>> @@ -177,16 +171,8 @@ static u32 gmux_index_read32(struct
>>>> apple_gmux_data *gmux_data, int port) static void
>>>> gmux_index_write32(struct apple_gmux_data *gmux_data, int port,
>>>> u32 val) {
>>>> -  int i;
>>>> -  u8 tmpval;
>>>> -
>>>>mutex_lock(_data->index_lock);
>>>> -
>>>> -  for (i = 0; i < 4; i++) {
>>>> -  tmpval = (val >> (i * 8)) & 0xff;
>>>> -  outb(tmpval, gmux_data->iostart + GMUX_PORT_VALUE
>>>> + i);
>>>> -  }
>>>> -
>>>> +  outl(cpu_to_be32(val), gmux_data->iostart +
>>>> GMUX_PORT_VALUE); gmux_index_wait_ready(gmux_data);
>>>>outb(port & 0xff, gmux_data->iostart + GMUX_PORT_WRITE);
>>>>gmux_index_wait_complete(gmux_data);  
>>>   
>>
> 



Re: [RFC PATCH 7/9] apple-gmux: add sysfs interface

2023-02-10 Thread Hans de Goede
Hi,

On 2/10/23 05:48, Orlando Chamberlain wrote:
> Allow reading gmux ports from userspace. When the unsafe module
> parameter allow_user_writes is true, writing 1 byte
> values is also allowed.
> 
> For example:
> 
> cd /sys/bus/acpi/devices/APP000B:00/physical_node/
> echo 4 > gmux_selected_port
> cat gmux_selected_port_data | xxd -p
> 
> Will show the gmux version information (0005 in this case)

Please use debugfs for this and as part of the conversion
drop the #ifdef-s (debugfs has stubs for when not enabled)
and drop all the error checking of creating the files, debugfs
is deliberately designed to not have any error checking in
the setup / teardown code.

This also removes the need for the allow_user_writes parameter
replacing it with the new kernel lockdown mechanism. debugfs
will automatically block access to writable files when
the kernel is in lockdown mode.

Regards,

Hans




> Signed-off-by: Orlando Chamberlain 
> ---
>  drivers/platform/x86/apple-gmux.c | 129 ++
>  1 file changed, 129 insertions(+)
> 
> diff --git a/drivers/platform/x86/apple-gmux.c 
> b/drivers/platform/x86/apple-gmux.c
> index c38d6ef0c15a..756059d48393 100644
> --- a/drivers/platform/x86/apple-gmux.c
> +++ b/drivers/platform/x86/apple-gmux.c
> @@ -66,6 +66,11 @@ struct apple_gmux_data {
>   enum vga_switcheroo_client_id switch_state_external;
>   enum vga_switcheroo_state power_state;
>   struct completion powerchange_done;
> +
> +#ifdef CONFIG_SYSFS
> + /* sysfs data */
> + int selected_port;
> +#endif /* CONFIG_SYSFS */
>  };
>  
>  static struct apple_gmux_data *apple_gmux_data;
> @@ -651,6 +656,121 @@ static void gmux_notify_handler(acpi_handle device, u32 
> value, void *context)
>   complete(_data->powerchange_done);
>  }
>  
> +/**
> + * DOC: Sysfs Interface
> + *
> + * gmux ports can be read from userspace as a sysfs interface. For example:
> + *
> + * # echo 4 > 
> /sys/bus/acpi/devices/APP000B:00/physical_node/gmux_selected_port
> + * # cat 
> /sys/bus/acpi/devices/APP000B:00/physical_node/gmux_selected_port_data | xxd 
> -p
> + * 0005
> + *
> + * Reads 4 bytes from port 4 (GMUX_PORT_VERSION_MAJOR).
> + *
> + * Single byte writes are also supported, however this must be enabled with 
> the
> + * unsafe allow_user_writes module parameter.
> + *
> + */
> +
> +#ifdef CONFIG_SYSFS
> +
> +static bool allow_user_writes;
> +module_param_unsafe(allow_user_writes, bool, 0);
> +MODULE_PARM_DESC(allow_user_writes, "Allow userspace to write to gmux ports 
> (default: false) (bool)");
> +
> +static ssize_t gmux_selected_port_store(struct device *dev,
> + struct device_attribute *attr, const char *sysfsbuf, size_t 
> count)
> +{
> + struct apple_gmux_data *gmux_data = dev_get_drvdata(dev);
> + u8 port;
> +
> + if (kstrtou8(sysfsbuf, 10, ) < 0)
> + return -EINVAL;
> +
> + /* On pio gmux's, make sure the user doesn't access too high of a port. 
> */
> + if ((gmux_data->config == _gmux_pio) &&
> + port > (gmux_data->iolen - 4))
> + return -EINVAL;
> +
> + gmux_data->selected_port = port;
> + return count;
> +}
> +
> +static ssize_t gmux_selected_port_show(struct device *dev,
> + struct device_attribute *attr, char *sysfsbuf)
> +{
> + struct apple_gmux_data *gmux_data = dev_get_drvdata(dev);
> +
> + return sysfs_emit(sysfsbuf, "%d\n", gmux_data->selected_port);
> +}
> +
> +DEVICE_ATTR_RW(gmux_selected_port);
> +
> +static ssize_t gmux_selected_port_data_store(struct device *dev,
> + struct device_attribute *attr, const char *sysfsbuf, size_t 
> count)
> +{
> + struct apple_gmux_data *gmux_data = dev_get_drvdata(dev);
> +
> + if (count == 1)
> + gmux_write8(gmux_data, gmux_data->selected_port, *sysfsbuf);
> + else
> + return -EINVAL;
> +
> + return count;
> +}
> +
> +static ssize_t gmux_selected_port_data_show(struct device *dev,
> + struct device_attribute *attr, char *sysfsbuf)
> +{
> + struct apple_gmux_data *gmux_data = dev_get_drvdata(dev);
> + u32 data;
> +
> + data = gmux_read32(gmux_data, gmux_data->selected_port);
> + memcpy(sysfsbuf, , sizeof(data));
> +
> + return sizeof(data);
> +}
> +
> +struct device_attribute dev_attr_gmux_selected_port_data_rw = 
> __ATTR_RW(gmux_selected_port_data);
> +struct device_attribute dev_attr_gmux_selected_port_data_ro = 
> __ATTR_RO(gmux_selected_port_data);
> +
> +static int gmux_init_sysfs(struct pnp_dev *pnp)
> +{
> + int ret;
> +
> + ret = device_create_file(>dev, _attr_gmux_selected_port);
> + if (ret)
> + return ret;
> + if (allow_user_writes)
> + ret = device_create_file(>dev, 
> _attr_gmux_selected_port_data_rw);
> + else
> + ret = device_create_file(>dev, 
> _attr_gmux_selected_port_data_ro);
> + if (ret)
> + device_remove_file(>dev, _attr_gmux_selected_port);
> + 

Re: [RFC PATCH 7/9] apple-gmux: add sysfs interface

2023-02-10 Thread Hans de Goede
Hi,

On 2/10/23 21:15, Hans de Goede wrote:
> Hi,
> 
> On 2/10/23 05:48, Orlando Chamberlain wrote:
>> Allow reading gmux ports from userspace. When the unsafe module
>> parameter allow_user_writes is true, writing 1 byte
>> values is also allowed.
>>
>> For example:
>>
>> cd /sys/bus/acpi/devices/APP000B:00/physical_node/
>> echo 4 > gmux_selected_port
>> cat gmux_selected_port_data | xxd -p
>>
>> Will show the gmux version information (0005 in this case)
> 
> Please use debugfs for this and as part of the conversion
> drop the #ifdef-s (debugfs has stubs for when not enabled)
> and drop all the error checking of creating the files, debugfs
> is deliberately designed to not have any error checking in
> the setup / teardown code.
> 
> This also removes the need for the allow_user_writes parameter
> replacing it with the new kernel lockdown mechanism. debugfs
> will automatically block access to writable files when
> the kernel is in lockdown mode.
> 
> Regards,
> 
> Hans

p.s.

I just realized I forgot my usual thank you for contributing
to the kernel reply to the cover letter before diving into
the review (oops).

So let me correct that: thank you very much for your work on this!

Regards,

Hans






>> Signed-off-by: Orlando Chamberlain 
>> ---
>>  drivers/platform/x86/apple-gmux.c | 129 ++
>>  1 file changed, 129 insertions(+)
>>
>> diff --git a/drivers/platform/x86/apple-gmux.c 
>> b/drivers/platform/x86/apple-gmux.c
>> index c38d6ef0c15a..756059d48393 100644
>> --- a/drivers/platform/x86/apple-gmux.c
>> +++ b/drivers/platform/x86/apple-gmux.c
>> @@ -66,6 +66,11 @@ struct apple_gmux_data {
>>  enum vga_switcheroo_client_id switch_state_external;
>>  enum vga_switcheroo_state power_state;
>>  struct completion powerchange_done;
>> +
>> +#ifdef CONFIG_SYSFS
>> +/* sysfs data */
>> +int selected_port;
>> +#endif /* CONFIG_SYSFS */
>>  };
>>  
>>  static struct apple_gmux_data *apple_gmux_data;
>> @@ -651,6 +656,121 @@ static void gmux_notify_handler(acpi_handle device, 
>> u32 value, void *context)
>>  complete(_data->powerchange_done);
>>  }
>>  
>> +/**
>> + * DOC: Sysfs Interface
>> + *
>> + * gmux ports can be read from userspace as a sysfs interface. For example:
>> + *
>> + * # echo 4 > 
>> /sys/bus/acpi/devices/APP000B:00/physical_node/gmux_selected_port
>> + * # cat 
>> /sys/bus/acpi/devices/APP000B:00/physical_node/gmux_selected_port_data | xxd 
>> -p
>> + * 0005
>> + *
>> + * Reads 4 bytes from port 4 (GMUX_PORT_VERSION_MAJOR).
>> + *
>> + * Single byte writes are also supported, however this must be enabled with 
>> the
>> + * unsafe allow_user_writes module parameter.
>> + *
>> + */
>> +
>> +#ifdef CONFIG_SYSFS
>> +
>> +static bool allow_user_writes;
>> +module_param_unsafe(allow_user_writes, bool, 0);
>> +MODULE_PARM_DESC(allow_user_writes, "Allow userspace to write to gmux ports 
>> (default: false) (bool)");
>> +
>> +static ssize_t gmux_selected_port_store(struct device *dev,
>> +struct device_attribute *attr, const char *sysfsbuf, size_t 
>> count)
>> +{
>> +struct apple_gmux_data *gmux_data = dev_get_drvdata(dev);
>> +u8 port;
>> +
>> +if (kstrtou8(sysfsbuf, 10, ) < 0)
>> +return -EINVAL;
>> +
>> +/* On pio gmux's, make sure the user doesn't access too high of a port. 
>> */
>> +if ((gmux_data->config == _gmux_pio) &&
>> +port > (gmux_data->iolen - 4))
>> +return -EINVAL;
>> +
>> +gmux_data->selected_port = port;
>> +return count;
>> +}
>> +
>> +static ssize_t gmux_selected_port_show(struct device *dev,
>> +struct device_attribute *attr, char *sysfsbuf)
>> +{
>> +struct apple_gmux_data *gmux_data = dev_get_drvdata(dev);
>> +
>> +return sysfs_emit(sysfsbuf, "%d\n", gmux_data->selected_port);
>> +}
>> +
>> +DEVICE_ATTR_RW(gmux_selected_port);
>> +
>> +static ssize_t gmux_selected_port_data_store(struct device *dev,
>> +struct device_attribute *attr, const char *sysfsbuf, size_t 
>> count)
>> +{
>> +struct apple_gmux_data *gmux_data = dev_get_drvdata(dev);
>> +
>> +if (count == 1)
>> +gmux_write8(gmux_data, gmux_data->selected_port, *sysfsbuf);
>> +else
&g

Re: [RFC PATCH 1/9] apple-gmux: use cpu_to_be32 instead of manual reorder

2023-02-10 Thread Hans de Goede
Hi,

On 2/10/23 20:09, Hans de Goede wrote:
> Hi,
> 
> On 2/10/23 05:48, Orlando Chamberlain wrote:
>> Currently it manually flips the byte order, but we can instead use
>> cpu_to_be32(val) for this.
>>
>> Signed-off-by: Orlando Chamberlain 
>> ---
>>  drivers/platform/x86/apple-gmux.c | 18 ++
>>  1 file changed, 2 insertions(+), 16 deletions(-)
>>
>> diff --git a/drivers/platform/x86/apple-gmux.c 
>> b/drivers/platform/x86/apple-gmux.c
>> index 9333f82cfa8a..e8cb084cb81f 100644
>> --- a/drivers/platform/x86/apple-gmux.c
>> +++ b/drivers/platform/x86/apple-gmux.c
>> @@ -94,13 +94,7 @@ static u32 gmux_pio_read32(struct apple_gmux_data 
>> *gmux_data, int port)
>>  static void gmux_pio_write32(struct apple_gmux_data *gmux_data, int port,
>>   u32 val)
>>  {
>> -int i;
>> -u8 tmpval;
>> -
>> -for (i = 0; i < 4; i++) {
>> -tmpval = (val >> (i * 8)) & 0xff;
>> -outb(tmpval, gmux_data->iostart + port + i);
>> -}
>> +outl(cpu_to_be32(val), gmux_data->iostart + port);
>>  }
>>  
>>  static int gmux_index_wait_ready(struct apple_gmux_data *gmux_data)
> 
> The ioport / indexed-ioport accessed apple_gmux-es likely are (part of?)
> LPC bus devices . Looking at the bus level you are now changing 4 io
> accesses with a size of 1 byte, to 1 32 bit io-access.
> 
> Depending on the decoding hw in the chip this may work fine,
> or this may work not at all.
> 
> I realized that you have asked for more testing, but most surviving
> macbooks from the older apple-gmux era appear to be models without
> a discrete GPU (which are often the first thing to break) and thus
> without a gmux.
> 
> Unless we get a bunch of testers to show up, which I doubt. I would
> prefer slightly bigger / less pretty code and not change the functional
> behavior of the driver on these older models.

A quick follow up on this, I just noticed that only the pio_write32
is doing the one byte at a time thing:

static u32 gmux_pio_read32(struct apple_gmux_data *gmux_data, int port)
{
return inl(gmux_data->iostart + port);
}

static void gmux_pio_write32(struct apple_gmux_data *gmux_data, int port,
 u32 val)
{
int i;
u8 tmpval;

for (i = 0; i < 4; i++) {
tmpval = (val >> (i * 8)) & 0xff;
outb(tmpval, gmux_data->iostart + port + i);
}
}

And if you look closely gmux_pio_write32() is not swapping
the order to be32 at all, it is just taking the bytes
in little-endian memory order, starting with the first
(index 0) byte which is the least significant byte of
the value.

On x86 the original code is no different then doing:

static void gmux_pio_write32(struct apple_gmux_data *gmux_data, int port,
 u32 val)
{
u8 *data = (u8 *)
int i;

for (i = 0; i < 4; i++)
outb(data[i], gmux_data->iostart + port + i);
}

So yeah this patch is definitely wrong, it actually swaps
the byte order compared to the original code. Which becomes
clear when you look the weird difference between the read32 and
write32 functions after this patch.

Presumably there is a specific reason why gmux_pio_write32()
is not already doing a single outl(..., val) and byte-ordering
is not the reason.

Regards,

Hans



>> @@ -177,16 +171,8 @@ static u32 gmux_index_read32(struct apple_gmux_data 
>> *gmux_data, int port)
>>  static void gmux_index_write32(struct apple_gmux_data *gmux_data, int port,
>> u32 val)
>>  {
>> -int i;
>> -u8 tmpval;
>> -
>>  mutex_lock(_data->index_lock);
>> -
>> -for (i = 0; i < 4; i++) {
>> -tmpval = (val >> (i * 8)) & 0xff;
>> -outb(tmpval, gmux_data->iostart + GMUX_PORT_VALUE + i);
>> -}
>> -
>> +outl(cpu_to_be32(val), gmux_data->iostart + GMUX_PORT_VALUE);
>>  gmux_index_wait_ready(gmux_data);
>>  outb(port & 0xff, gmux_data->iostart + GMUX_PORT_WRITE);
>>  gmux_index_wait_complete(gmux_data);
> 



Re: [RFC PATCH 1/9] apple-gmux: use cpu_to_be32 instead of manual reorder

2023-02-10 Thread Hans de Goede
Hi,

On 2/10/23 20:09, Hans de Goede wrote:
> Hi,
> 
> On 2/10/23 05:48, Orlando Chamberlain wrote:
>> Currently it manually flips the byte order, but we can instead use
>> cpu_to_be32(val) for this.
>>
>> Signed-off-by: Orlando Chamberlain 
>> ---
>>  drivers/platform/x86/apple-gmux.c | 18 ++
>>  1 file changed, 2 insertions(+), 16 deletions(-)
>>
>> diff --git a/drivers/platform/x86/apple-gmux.c 
>> b/drivers/platform/x86/apple-gmux.c
>> index 9333f82cfa8a..e8cb084cb81f 100644
>> --- a/drivers/platform/x86/apple-gmux.c
>> +++ b/drivers/platform/x86/apple-gmux.c
>> @@ -94,13 +94,7 @@ static u32 gmux_pio_read32(struct apple_gmux_data 
>> *gmux_data, int port)
>>  static void gmux_pio_write32(struct apple_gmux_data *gmux_data, int port,
>>   u32 val)
>>  {
>> -int i;
>> -u8 tmpval;
>> -
>> -for (i = 0; i < 4; i++) {
>> -tmpval = (val >> (i * 8)) & 0xff;
>> -outb(tmpval, gmux_data->iostart + port + i);
>> -}
>> +outl(cpu_to_be32(val), gmux_data->iostart + port);
>>  }
>>  
>>  static int gmux_index_wait_ready(struct apple_gmux_data *gmux_data)
> 
> The ioport / indexed-ioport accessed apple_gmux-es likely are (part of?)
> LPC bus devices . Looking at the bus level you are now changing 4 io
> accesses with a size of 1 byte, to 1 32 bit io-access.

Correction to myself, re-reading the LPC specification, then
if I'm right and this is a LPC device then all IO in/out accesses
are always 1 byte accesses. Since the LPC bus only supports 16 / 32
bit accesses for DMA cycles.

So presumably the outl() would get split into 4 separate 8 bit
(port) IO accesses.

Regards,

Hans





>> @@ -177,16 +171,8 @@ static u32 gmux_index_read32(struct apple_gmux_data 
>> *gmux_data, int port)
>>  static void gmux_index_write32(struct apple_gmux_data *gmux_data, int port,
>> u32 val)
>>  {
>> -int i;
>> -u8 tmpval;
>> -
>>  mutex_lock(_data->index_lock);
>> -
>> -for (i = 0; i < 4; i++) {
>> -tmpval = (val >> (i * 8)) & 0xff;
>> -outb(tmpval, gmux_data->iostart + GMUX_PORT_VALUE + i);
>> -}
>> -
>> +outl(cpu_to_be32(val), gmux_data->iostart + GMUX_PORT_VALUE);
>>  gmux_index_wait_ready(gmux_data);
>>  outb(port & 0xff, gmux_data->iostart + GMUX_PORT_WRITE);
>>  gmux_index_wait_complete(gmux_data);
> 



Re: [RFC PATCH 5/9] apple-gmux: Use GMSP acpi method for interrupt clear

2023-02-10 Thread Hans de Goede
Hi,

On 2/10/23 05:48, Orlando Chamberlain wrote:
> This is needed for interrupts to be cleared correctly on MMIO based
> gmux's. It is untested if this helps/hinders other gmux types, but I
> have seen the GMSP method in the acpi tables of a MacBook with an
> indexed gmux.
> 
> If this turns out to break support for older gmux's, this can instead
> be only done on MMIO gmux's.
> 
> There is also a "GMLV" acpi method, and the "GMSP" method can be called
> with 1 as its argument, but the purposes of these aren't known and they
> don't seem to be needed.
> 
> Signed-off-by: Orlando Chamberlain 
> ---
>  drivers/platform/x86/apple-gmux.c | 26 +-
>  1 file changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/platform/x86/apple-gmux.c 
> b/drivers/platform/x86/apple-gmux.c
> index 760434a527c1..c605f036ea0b 100644
> --- a/drivers/platform/x86/apple-gmux.c
> +++ b/drivers/platform/x86/apple-gmux.c
> @@ -494,8 +494,29 @@ static const struct apple_gmux_config apple_gmux_index = 
> {
>   * MCP79, on all following generations it's GPIO pin 6 of the Intel PCH.
>   * The GPE merely signals that an interrupt occurred, the actual type of 
> event
>   * is identified by reading a gmux register.
> + *
> + * On MMIO gmux's, we also need to call the acpi method GMSP to properly 
> clear
> + * interrupts. TODO: Do other types need this? Does this break other types?
>   */
>  
> +static int gmux_call_acpi_gmsp(struct apple_gmux_data *gmux_data, int arg)
> +{
> + acpi_status status = AE_OK;
> + union acpi_object arg0 = { ACPI_TYPE_INTEGER };
> + struct acpi_object_list arg_list = { 1,  };
> +
> + arg0.integer.value = arg;
> +
> + status = acpi_evaluate_object(gmux_data->dhandle, "GMSP", _list, 
> NULL);
> + if (ACPI_FAILURE(status)) {
> + pr_err("GMSP call failed: %s\n",
> +acpi_format_exception(status));
> + return -ENODEV;
> + }
> +
> + return 0;
> +}
> +
>  static inline void gmux_disable_interrupts(struct apple_gmux_data *gmux_data)
>  {
>   gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_ENABLE,
> @@ -519,7 +540,10 @@ static void gmux_clear_interrupts(struct apple_gmux_data 
> *gmux_data)
>  
>   /* to clear interrupts write back current status */
>   status = gmux_interrupt_get_status(gmux_data);
> - gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_STATUS, status);
> + if (status) {
> + gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_STATUS, status);
> + gmux_call_acpi_gmsp(gmux_data, 0);

Ugh no, please don't go around calling random ACPI methods from untested
firmware revisions / device models.

ACPI code (even Apple's I have learned) tends to be full of bugs. If we
did not need to call GMSP before then please lets keep not calling it
on the older models. Just because it is there does not mean that calling
it is useful, it might even be harmful.

Regards,

Hans






> + }
>  }
>  
>  static void gmux_notify_handler(acpi_handle device, u32 value, void *context)



Re: [RFC PATCH 2/9] apple-gmux: consolidate version reading

2023-02-10 Thread Hans de Goede
Hi,

On 2/10/23 05:48, Orlando Chamberlain wrote:
> Read gmux version in one go as 32 bits on both indexed and classic
> gmux's.
> 
> Classic gmux's used to read the version as
> 
> major = inb(base + 0x4);
> minor = inb(base + 0x5);
> release = inb(base + 0x6);
> 
> but this can instead be done the same way as indexed gmux's with
> gmux_read32(), so the same version reading code is used for classic
> and indexed gmux's (as well as mmio gmux's that will be added to this
> driver).
> 
> Signed-off-by: Orlando Chamberlain 
> ---
>  drivers/platform/x86/apple-gmux.c | 14 ++
>  include/linux/apple-gmux.h|  6 +-
>  2 files changed, 7 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/platform/x86/apple-gmux.c 
> b/drivers/platform/x86/apple-gmux.c
> index e8cb084cb81f..67628104f31a 100644
> --- a/drivers/platform/x86/apple-gmux.c
> +++ b/drivers/platform/x86/apple-gmux.c
> @@ -580,15 +580,13 @@ static int gmux_probe(struct pnp_dev *pnp, const struct 
> pnp_device_id *id)
>   if (indexed) {
>   mutex_init(_data->index_lock);
>   gmux_data->indexed = true;
> - version = gmux_read32(gmux_data, GMUX_PORT_VERSION_MAJOR);
> - ver_major = (version >> 24) & 0xff;
> - ver_minor = (version >> 16) & 0xff;
> - ver_release = (version >> 8) & 0xff;
> - } else {
> - ver_major = gmux_read8(gmux_data, GMUX_PORT_VERSION_MAJOR);
> - ver_minor = gmux_read8(gmux_data, GMUX_PORT_VERSION_MINOR);
> - ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE);
>   }
> +
> + version = gmux_read32(gmux_data, GMUX_PORT_VERSION_MAJOR);
> + ver_major = (version >> 24) & 0xff;
> + ver_minor = (version >> 16) & 0xff;
> + ver_release = (version >> 8) & 0xff;
> +
>   pr_info("Found gmux version %d.%d.%d [%s]\n", ver_major, ver_minor,
>   ver_release, (gmux_data->indexed ? "indexed" : "classic"));
>  

The problem with this is that there is nothing (no known register)
at address base + 7 and now you are reading from address base + 7
here where before the code was not, we have no idea how the hw
will respond to this.  This should be pretty innocent but still ...

> diff --git a/include/linux/apple-gmux.h b/include/linux/apple-gmux.h
> index 1f68b49bcd68..eb2caee04abd 100644
> --- a/include/linux/apple-gmux.h
> +++ b/include/linux/apple-gmux.h
> @@ -67,7 +67,6 @@ static inline bool apple_gmux_is_indexed(unsigned long 
> iostart)
>   */
>  static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, bool 
> *indexed_ret)
>  {
> - u8 ver_major, ver_minor, ver_release;
>   struct device *dev = NULL;
>   struct acpi_device *adev;
>   struct resource *res;
> @@ -95,10 +94,7 @@ static inline bool apple_gmux_detect(struct pnp_dev 
> *pnp_dev, bool *indexed_ret)
>* Invalid version information may indicate either that the gmux
>* device isn't present or that it's a new one that uses indexed io.
>*/
> - ver_major = inb(res->start + GMUX_PORT_VERSION_MAJOR);
> - ver_minor = inb(res->start + GMUX_PORT_VERSION_MINOR);
> - ver_release = inb(res->start + GMUX_PORT_VERSION_RELEASE);
> - if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) {
> + if (!(~inl(res->start + GMUX_PORT_VERSION_MAJOR))) {

Assuming we can get this tested well enough that I'm ok with the change in 
general
please write this as:

if (inl(res->start + GMUX_PORT_VERSION_MAJOR) == 0x) {

Which I believe is what you are trying to achieve here ?

Regards,

Hans



>   indexed = apple_gmux_is_indexed(res->start);
>   if (!indexed)
>   goto out;



Re: [RFC PATCH 1/9] apple-gmux: use cpu_to_be32 instead of manual reorder

2023-02-10 Thread Hans de Goede
Hi,

On 2/10/23 05:48, Orlando Chamberlain wrote:
> Currently it manually flips the byte order, but we can instead use
> cpu_to_be32(val) for this.
> 
> Signed-off-by: Orlando Chamberlain 
> ---
>  drivers/platform/x86/apple-gmux.c | 18 ++
>  1 file changed, 2 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/platform/x86/apple-gmux.c 
> b/drivers/platform/x86/apple-gmux.c
> index 9333f82cfa8a..e8cb084cb81f 100644
> --- a/drivers/platform/x86/apple-gmux.c
> +++ b/drivers/platform/x86/apple-gmux.c
> @@ -94,13 +94,7 @@ static u32 gmux_pio_read32(struct apple_gmux_data 
> *gmux_data, int port)
>  static void gmux_pio_write32(struct apple_gmux_data *gmux_data, int port,
>u32 val)
>  {
> - int i;
> - u8 tmpval;
> -
> - for (i = 0; i < 4; i++) {
> - tmpval = (val >> (i * 8)) & 0xff;
> - outb(tmpval, gmux_data->iostart + port + i);
> - }
> + outl(cpu_to_be32(val), gmux_data->iostart + port);
>  }
>  
>  static int gmux_index_wait_ready(struct apple_gmux_data *gmux_data)

The ioport / indexed-ioport accessed apple_gmux-es likely are (part of?)
LPC bus devices . Looking at the bus level you are now changing 4 io
accesses with a size of 1 byte, to 1 32 bit io-access.

Depending on the decoding hw in the chip this may work fine,
or this may work not at all.

I realized that you have asked for more testing, but most surviving
macbooks from the older apple-gmux era appear to be models without
a discrete GPU (which are often the first thing to break) and thus
without a gmux.

Unless we get a bunch of testers to show up, which I doubt. I would
prefer slightly bigger / less pretty code and not change the functional
behavior of the driver on these older models.

Regards,

Hans



> @@ -177,16 +171,8 @@ static u32 gmux_index_read32(struct apple_gmux_data 
> *gmux_data, int port)
>  static void gmux_index_write32(struct apple_gmux_data *gmux_data, int port,
>  u32 val)
>  {
> - int i;
> - u8 tmpval;
> -
>   mutex_lock(_data->index_lock);
> -
> - for (i = 0; i < 4; i++) {
> - tmpval = (val >> (i * 8)) & 0xff;
> - outb(tmpval, gmux_data->iostart + GMUX_PORT_VALUE + i);
> - }
> -
> + outl(cpu_to_be32(val), gmux_data->iostart + GMUX_PORT_VALUE);
>   gmux_index_wait_ready(gmux_data);
>   outb(port & 0xff, gmux_data->iostart + GMUX_PORT_WRITE);
>   gmux_index_wait_complete(gmux_data);



Re: [RFC PATCH 9/9] drm/amdgpu: register a vga_switcheroo client for all GPUs that are not thunderbolt attached

2023-02-10 Thread Hans de Goede
Hi,

On 2/10/23 16:53, Alex Deucher wrote:
> On Fri, Feb 10, 2023 at 3:04 AM Orlando Chamberlain
>  wrote:
>>
>> From: Kerem Karabay 
>>
>> Commit 3840c5bcc245 ("drm/amdgpu: disentangle runtime pm and
>> vga_switcheroo") made amdgpu only register a vga_switcheroo client for
>> GPU's with PX, however AMD GPUs in dual gpu Apple Macbooks do need to
>> register, but don't have PX. Instead of AMD's PX, they use apple-gmux.
> 
> Is there a way to detect apple-gmux instead?  Otherwise, we register
> vga_switcheroo on any system with multiple GPUs which is not what we
> want.

Yes since 6.1.y (either stable series or just take 6.2.0) the apple-gmux
detect code has been factored out into a stand-alone
apple_gmux_detect() helper inside:

include/linux/apple-gmux.h

For usage outside of the actual apple-gmux driver you can simply
pass NULL for both arguments.

This was necessary to reliably check if the apple-gmux should be
used for backlight control.

Note there also is the older apple_gmux_present() helper, which is
already used in some drm code. That function is not reliable though
it detects if the ACPI tables contain an ACPI device describing
the presence of a gmux, but it turns out even Apple has buggy ACPI
tables and the mere presence of that ACPI device is not a reliable
indicator the gmux is actually there.

I have not changed over any of the existing apple_gmux_present()
users for fear of unwanted side effects...

Regards,

Hans




>> Revert to the old logic of registering for all non-thunderbolt gpus,
>> like radeon and nouveau.
>>
>> Fixes: 3840c5bcc245 ("drm/amdgpu: disentangle runtime pm and vga_switcheroo")
>> Signed-off-by: Kerem Karabay 
>> [Orlando Chamberlain : add commit description]
>> Signed-off-by: Orlando Chamberlain 
>> ---
>>  drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 18 +++---
>>  1 file changed, 11 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c 
>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> index 2f28a8c02f64..0bb553a61552 100644
>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
>> @@ -3919,12 +3919,13 @@ int amdgpu_device_init(struct amdgpu_device *adev,
>> if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
>> vga_client_register(adev->pdev, 
>> amdgpu_device_vga_set_decode);
>>
>> -   if (amdgpu_device_supports_px(ddev)) {
>> -   px = true;
>> -   vga_switcheroo_register_client(adev->pdev,
>> -  _switcheroo_ops, px);
>> +   px = amdgpu_device_supports_px(ddev);
>> +
>> +   if (!pci_is_thunderbolt_attached(adev->pdev))
>> +   vga_switcheroo_register_client(adev->pdev, 
>> _switcheroo_ops, px);
>> +
>> +   if (px)
>> vga_switcheroo_init_domain_pm_ops(adev->dev, 
>> >vga_pm_domain);
>> -   }
>>
>> if (adev->gmc.xgmi.pending_reset)
>> queue_delayed_work(system_wq, _info.delayed_reset_work,
>> @@ -4048,10 +4049,13 @@ void amdgpu_device_fini_sw(struct amdgpu_device 
>> *adev)
>>
>> kfree(adev->bios);
>> adev->bios = NULL;
>> -   if (amdgpu_device_supports_px(adev_to_drm(adev))) {
>> +
>> +   if (!pci_is_thunderbolt_attached(adev->pdev))
>> vga_switcheroo_unregister_client(adev->pdev);
>> +
>> +   if (amdgpu_device_supports_px(adev_to_drm(adev)))
>> vga_switcheroo_fini_domain_pm_ops(adev->dev);
>> -   }
>> +
>> if ((adev->pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
>> vga_client_unregister(adev->pdev);
>>
>> --
>> 2.39.1
>>
> 



New? amdgpu drm_modeset_drop_locks oops/warning with 6.2-rc#

2023-01-23 Thread Hans de Goede
Hi,

Since I'm dogfooding 6.2-rc# I'm regularly (not always directly after boot) 
seeing
the following warning / oops in my logs.

This is on an AMD Ryzen 7 5700G on a B550M PRO-VDH WIFI with 2 1920x1080 
monitors
connected (one over DVI and over HDMI IIRC).

[4.896028] [drm] amdgpu kernel modesetting enabled.
[4.907400] amdgpu: Virtual CRAT table created for CPU
[4.907499] amdgpu: Topology: Add CPU node
[4.907664] amdgpu :30:00.0: enabling device drm_modeset_drop_locks(0006 
-> 0007)
[4.907730] [drm] initializing kernel modesetting (RENOIR 0x1002:0x1638 
0x1002:0x1636 0xC8).
[4.907744] [drm] register mmio base: 0xFCB0
[4.907745] [drm] register mmio size: 524288
[4.909911] [drm] add ip block number 0 
[4.909913] [drm] add ip block number 1 
[4.909915] [drm] add ip block number 2 
[4.909916] [drm] add ip block number 3 
[4.909917] [drm] add ip block number 4 
[4.909918] [drm] add ip block number 5 
[4.909919] [drm] add ip block number 6 
[4.909920] [drm] add ip block number 7 
[4.909921] [drm] add ip block number 8 
[4.909923] [drm] add ip block number 9 
[4.909932] amdgpu :30:00.0: amdgpu: Fetched VBIOS from VFCT
[4.909935] amdgpu: ATOM BIOS: 13-CEZANNE-019
[4.911735] [drm] VCN decode is enabled in VM mode
[4.911737] [drm] VCN encode is enabled in VM mode
[4.911739] [drm] JPEG decode is enabled in VM mode
[4.929838] amdgpu :30:00.0: vgaarb: deactivate vga console
[4.929842] amdgpu :30:00.0: amdgpu: Trusted Memory Zone (TMZ) feature 
enabled
[4.929845] amdgpu :30:00.0: amdgpu: PCIE atomic ops is not supported
[4.929853] amdgpu :30:00.0: amdgpu: MODE2 reset
[4.930075] [drm] vm size is 262144 GB, 4 levels, block size is 9-bit, 
fragment size is 9-bit
[4.930083] amdgpu :30:00.0: amdgpu: VRAM: 2048M 0x00F4 - 
0x00F47FFF (2048M used)
[4.930085] amdgpu :30:00.0: amdgpu: GART: 1024M 0x - 
0x3FFF
[4.930087] amdgpu :30:00.0: amdgpu: AGP: 267419648M 0x00F8 
- 0x
[4.930094] [drm] Detected VRAM RAM=2048M, BAR=2048M
[4.930095] [drm] RAM width 128bits DDR4
[4.930461] [drm] amdgpu: 2048M of VRAM memory ready
[4.930463] [drm] amdgpu: 6783M of GTT memory ready.
[4.930518] [drm] GART: num cpu pages 262144, num gpu pages 262144
[4.930719] [drm] PCIE GART of 1024M enabled.
[4.930721] [drm] PTB located at 0x00F47FC0
[4.935904] amdgpu :30:00.0: amdgpu: PSP runtime database doesn't exist
[4.935907] amdgpu :30:00.0: amdgpu: PSP runtime database doesn't exist
[4.940478] [drm] Loading DMUB firmware via PSP: version=0x01010024
[4.966086] [drm] Found VCN firmware Version ENC: 1.19 DEC: 5 VEP: 0 
Revision: 0
[4.966103] amdgpu :30:00.0: amdgpu: Will use PSP to load VCN firmware
[5.694615] [drm] reserve 0x40 from 0xf47f80 for PSP TMR
[5.779476] amdgpu :30:00.0: amdgpu: RAS: optional ras ta ucode is not 
available
[5.790135] amdgpu :30:00.0: amdgpu: RAP: optional rap ta ucode is not 
available
[5.790137] amdgpu :30:00.0: amdgpu: SECUREDISPLAY: securedisplay ta 
ucode is not available
[5.790656] amdgpu :30:00.0: amdgpu: SMU is initialized successfully!
[5.791598] [drm] Display Core initialized with v3.2.215!
[5.792138] [drm] DMUB hardware initialized: version=0x01010024
[5.873355] [drm] kiq ring mec 2 pipe 1 q 0
[5.878565] [drm] VCN decode and encode initialized successfully(under DPG 
Mode).
[5.878612] [drm] JPEG decode initialized successfully.
[5.880995] kfd kfd: amdgpu: Allocated 3969056 bytes on gart
[5.881100] amdgpu: sdma_bitmap: 3
[5.897760] memmap_init_zone_device initialised 524288 pages in 2ms
[5.897763] amdgpu: HMM registered 2048MB device memory
[5.897882] amdgpu: SRAT table not found
[5.897886] amdgpu: Virtual CRAT table created for GPU
[5.898794] amdgpu: Topology: Add dGPU node [0x1638:0x1002]
[5.898798] kfd kfd: amdgpu: added device 1002:1638
[5.898875] amdgpu :30:00.0: amdgpu: SE 1, SH per SE 1, CU per SH 8, 
active_cu_number 8
[5.899077] amdgpu :30:00.0: amdgpu: ring gfx uses VM inv eng 0 on hub 0
[5.899079] amdgpu :30:00.0: amdgpu: ring gfx_low uses VM inv eng 1 on 
hub 0
[5.899080] amdgpu :30:00.0: amdgpu: ring gfx_high uses VM inv eng 4 on 
hub 0
[5.899081] amdgpu :30:00.0: amdgpu: ring comp_1.0.0 uses VM inv eng 5 
on hub 0
[5.899082] amdgpu :30:00.0: amdgpu: ring comp_1.1.0 uses VM inv eng 6 
on hub 0
[5.899083] amdgpu :30:00.0: amdgpu: ring comp_1.2.0 uses VM inv eng 7 
on hub 0
[5.899084] amdgpu :30:00.0: amdgpu: ring comp_1.3.0 uses VM inv eng 8 
on hub 0
[5.899085] amdgpu :30:00.0: amdgpu: ring comp_1.0.1 uses VM inv eng 9 
on hub 0
[5.899086] amdgpu :30:00.0: amdgpu: ring comp_1.1.1 uses VM inv eng 10 
on hub 0
[5.899087] amdgpu 

Re: [PATCH v2 0/3] Adjust ACPI video detection fallback path

2022-12-08 Thread Hans de Goede
Hi,

On 12/8/22 02:09, Mario Limonciello wrote:
> In kernel 6.1 the backlight registration code was overhauled so that
> at most one backlight device got registered. As part of this change
> there was code added to still allow making an acpi_video0 device if the
> BIOS contained backlight control methods but no native or vendor drivers
> registered.
> 
> Even after the overhaul this fallback logic is failing on the BIOS from
> a number of motherboard manufacturers supporting Ryzen APUs.
> What happens is the amdgpu driver finishes registration and as expected
> doesn't create a backlight control device since no eDP panels are connected
> to a desktop.
> 
> Then 8 seconds later the ACPI video detection code creates an
> acpi_video0 device that is non-operational. GNOME then creates a
> backlight slider.
> 
> To avoid this situation from happening make two sets of changes:
> 
> Prevent desktop problems w/ fallback logic
> --
> 1) Add support for the video detect code to let native drivers cancel the
> fallback logic if they didn't find a panel.
> 
> This is done this way so that if another driver decides that the ACPI
> mechanism is still needed it can instead directly call the registration
> function.
> 
> 2) Add code to amdgpu to notify the ACPI video detection code that no panel
> was detected on an APU.
> 
> Disable fallback logic by default
> -
> This fallback logic was introduced to prevent regressions in the backlight
> overhaul.  As it has been deemed unnecessary by Hans explicitly disable the
> timeout.  If this turns out to be mistake and this part is reverted, the
> other patches for preventing desktop problems will avoid regressions on
> desktops.

Thanks, the entire v2 series looks good to me:

Reviewed-by: Hans de Goede 

for the series.

Regards,

Hans




> Mario Limonciello (3):
>   ACPI: video: Allow GPU drivers to report no panels
>   drm/amd/display: Report to ACPI video if no panels were found
>   ACPI: video: Don't enable fallback path for creating ACPI backlight by
> default
> 
>  drivers/acpi/acpi_video.c   | 17 -
>  .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c   |  4 
>  include/acpi/video.h|  1 +
>  3 files changed, 17 insertions(+), 5 deletions(-)
> 



Re: [PATCH 0/2] Avoid creating acpi_video0 on desktop APUs

2022-12-07 Thread Hans de Goede
Hi,

On 12/7/22 22:21, Limonciello, Mario wrote:
> On 12/7/2022 15:04, Hans de Goede wrote:
>> Hi All,
>>
>> Mario, thank you for working on this.
> 
> Sure
> 
> 
>>
>> Note that the problem of the creating a non functional acpi_video0
>> device happened before the overhaul too.
>>
>> The difference is that now we have the in kernel GPU drivers
>> all call acpi_video_register_backlight() when they detect an
>> internal-panel for which they don't provide native-backlight
>> control themselves (to avoid the acpi_video0 backlight registering
>> before the native backlight gets a chance to register).
>>
>> The timeout is only there in case no drivers ever call
>> acpi_video_register_backlight(). nomodeset is one case, but
>> loosing backlight control in the nomodeset case would be fine
>> IMHO. The bigger worry why we have the timeout is because of
>> the nvidia binary driver, for devices which use that driver +
>> rely on apci_video# for backlight control.
>>
>> Back to the issue at hand of the unwanted (non functional)
>> apci_video# on various AMD APU using desktops.
>>
> 
> Thanks for explaining.
> 
>> The native drivers now all calling acpi_video_register_backlight()
>> gives us a chance to actually do something about it, so in that
>> sense the 6.1 backlight refactor is relevant.
>>
>>> To avoid this situation from happening add support for video drivers
>>> to notify the ACPI video detection code that no panel was detected.
>>>
>>> To reduce the risk of regressions on multi-GPU systems:
>>> * only use this logic when the system is reported as a desktop enclosure.
>>> * in the amdgpu code only report into this for APUs.
>>
>> I'm afraid that there still is a potential issue for dual
>> GPU machines. The chassistype is not 100% reliable.
> 
> Have you ever seen an A+N machine with unreliable chassis type?

Not specifically. I just know from experience to not
rely on chassis type.

E.g. I would not be surprised to have some of the desktop-replacement
class laptops from e.g. clevo which sometimes even come with
a desktop CPU for moar power, have their chassis type wrong.

Granted those are not using AMD APUs (yet), but that might change
with the ryzen 7000 series where every CPU is an APU too...

> Given Windows HLK certification and knowing that these are to
> be based off reference BIOS of laptops, I would be really surprised
> if this was wrong on an A+N laptop.

I agree this is unlikely. But I have seen all sort of wrong
chassis-type settings in devices which are not from the
big OEMs.  And AFAIK these sometimes also play fasr and loose
with the Windows certification.

>> Lets say we have a machine with the wrong chassis-type with
>> an AMD APU + nvidia GPU which relies on acpi_video0 for
>> backlight control.
>>
>> Then if the LCD is connected to the nvidia GPU only, the
>> amdgpu code will call the new acpi_video_report_nolcd()
>> function.
> 
> + Dan Dadap
> 
> Dan - the context is this series:
> https://patchwork.freedesktop.org/series/111745/
> 
> Do you know if this is real or just conceptual?
> 
>>
>> And then even if the nvidia binary driver is patched
>> by nvidia to call the new  acpi_video_register_backlight()
>> when it does see a panel, then acpi_video_should_register_backlight()
>> will still return false.
>>
>> Basically the problem is that we only want to not try
>> and register the acpi_video0 backlight on dual GPU
>> machines if the output detection on *both* GPUs has not
>> found any builtin LCD panel.
>>
>> But this series disables acpi_video0 backlight registration
>> as soon as *one* of the *two* GPUs has not found an internal
>> LCD panel.
>>
>> As discussed above, after the backlight refactor,
>> GPU(KMS) drivers are expected to call
>> acpi_video_register_backlight() when necessary for any
>> internal panels connected to the GPU they are driving.
>>
>> This mostly fixes the issue of having an acpi_video0 on
>> desktop APUs, except that the timeout thingie which was
>> added to avoid regressions still causes the acpi_video0
>> backlight to get registered.
>>
>> Note that this timeout is already configurable through
>> the register_backlight_delay module option; and setting
>> that option to 0 disables the timeout based fallback
>> completely.
>>
>> So another fix for this might be to just change the
>> default value of register_backlight_delay to 0 for
>> kernel 6.2 .  This is a change which I want to make
>> eventually anyways; so we might j

Re: [PATCH 0/2] Avoid creating acpi_video0 on desktop APUs

2022-12-07 Thread Hans de Goede
Hi All,

Mario, thank you for working on this.

On 12/7/22 20:31, Mario Limonciello wrote:
> In kernel 6.1 the backlight registration code was overhauled so that
> at most one backlight device got registered. As part of this change
> there was code added to cover the "nomodeset" case to still allow
> making an acpi_video0 device if the BIOS contained backlight control
> methods.
> 
> This fallback logic however is failing on the BIOS from a number of
> motherboard manufacturers supporting Ryzen APUs.  What happens is
> the amdgpu driver finishes registration and as expected doesn't
> create a backlight control device since no eDP panels are connected
> to a desktop.
> 
> Then 8 seconds later the ACPI video detection code creates an
> acpi_video0 device that is non-operational. GNOME then creates a
> backlight slider.

Note that the problem of the creating a non functional acpi_video0
device happened before the overhaul too.

The difference is that now we have the in kernel GPU drivers
all call acpi_video_register_backlight() when they detect an
internal-panel for which they don't provide native-backlight
control themselves (to avoid the acpi_video0 backlight registering
before the native backlight gets a chance to register).

The timeout is only there in case no drivers ever call
acpi_video_register_backlight(). nomodeset is one case, but
loosing backlight control in the nomodeset case would be fine
IMHO. The bigger worry why we have the timeout is because of
the nvidia binary driver, for devices which use that driver +
rely on apci_video# for backlight control.

Back to the issue at hand of the unwanted (non functional)
apci_video# on various AMD APU using desktops.

The native drivers now all calling acpi_video_register_backlight()
gives us a chance to actually do something about it, so in that
sense the 6.1 backlight refactor is relevant.

> To avoid this situation from happening add support for video drivers
> to notify the ACPI video detection code that no panel was detected.
> 
> To reduce the risk of regressions on multi-GPU systems:
> * only use this logic when the system is reported as a desktop enclosure.
> * in the amdgpu code only report into this for APUs.

I'm afraid that there still is a potential issue for dual
GPU machines. The chassistype is not 100% reliable.

Lets say we have a machine with the wrong chassis-type with
an AMD APU + nvidia GPU which relies on acpi_video0 for
backlight control.

Then if the LCD is connected to the nvidia GPU only, the
amdgpu code will call the new acpi_video_report_nolcd()
function.

And then even if the nvidia binary driver is patched
by nvidia to call the new  acpi_video_register_backlight()
when it does see a panel, then acpi_video_should_register_backlight()
will still return false.

Basically the problem is that we only want to not try
and register the acpi_video0 backlight on dual GPU
machines if the output detection on *both* GPUs has not
found any builtin LCD panel.

But this series disables acpi_video0 backlight registration
as soon as *one* of the *two* GPUs has not found an internal
LCD panel.

As discussed above, after the backlight refactor,
GPU(KMS) drivers are expected to call
acpi_video_register_backlight() when necessary for any
internal panels connected to the GPU they are driving.

This mostly fixes the issue of having an acpi_video0 on
desktop APUs, except that the timeout thingie which was
added to avoid regressions still causes the acpi_video0
backlight to get registered.

Note that this timeout is already configurable through
the register_backlight_delay module option; and setting
that option to 0 disables the timeout based fallback
completely.

So another fix for this might be to just change the
default value of register_backlight_delay to 0 for
kernel 6.2 .  This is a change which I want to make
eventually anyways; so we might just as well do this
now to fix the spurious acpi_video0 on desktop APUs
issue.   And if this does cause issues for nvidia
binary driver users, they can easily work around this
by setting the module option.

Or alternatively we could go with this series,
reworked so that calling acpi_video_report_nolcd()
only cancels the timeout.  This way drivers for another
GPU can still get the acpi_video0 if necessary by
explicitly calling acpi_video_register_backlight().

Personally I have a small preference for just changing
the default of register_backlight_delay to 0, disabling
the timeout based fallback starting with 6.2 .

I did not do this for 6.1 because there were already
many other backlight changes in 6.1, so I wanted to
have the fallback behavior there as a safeguard
against things not working as planned.

Regards,

Hans










> 
> Mario Limonciello (2):
>   ACPI: video: Allow GPU drivers to report no panels
>   drm/amd/display: Report to ACPI video if no panels were found
> 
>  drivers/acpi/acpi_video.c | 12 
>  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |  4 

Re: [PATCH v5 02/31] drm/i915: Don't register backlight when another backlight should be used (v2)

2022-11-04 Thread Hans de Goede
Hi Matthew, Rafael,

On 10/27/22 14:09, Rafael J. Wysocki wrote:
> On Thu, Oct 27, 2022 at 12:37 PM Hans de Goede  wrote:
>>
>> Hi,
>>
>> On 10/27/22 11:52, Matthew Garrett wrote:
>>> On Thu, Oct 27, 2022 at 11:39:38AM +0200, Hans de Goede wrote:
>>>
>>>> The *only* behavior which actually is new in 6.1 is the native GPU
>>>> drivers now doing the equivalent of:
>>>>
>>>>  if (acpi_video_get_backlight_type() != acpi_backlight_native)
>>>>  return;
>>>>
>>>> In their backlight register paths (i), which is causing the native
>>>> backlight to disappear on your custom laptop setup and on Chromebooks
>>>> (with the Chromebooks case being already solved I hope.).
>>>
>>> It's causing the backlight control to vanish on any machine that isn't
>>> ((acpi_video || vendor interface) || !acpi). Most machines that fall
>>> into that are either weird or Chromebooks or old, but there are machines
>>> that fall into that.
>>
>> I acknowledge that their are machines that fall into this category,
>> but I expect / hope there to be so few of them that we can just DMI
>> quirk our way out if this.
>>
>> I believe the old group to be small because:
>>
>> 1. Generally speaking the "native" control method is usually not
>> present on the really old (pre ACPI video spec) mobile GPUs.
>>
>> 2. On most old laptops I would still expect there to be a vendor
>> interface too, and if both get registered standard desktop environments
>> will prefer the vendor one, so then we need a native DMI quirk to
>> disable the vendor interface anyways and we already have a bunch of
>> those, so some laptops in this group are already covered by DMI quirks.
>>
>> And a fix for the Chromebook case is already in Linus' tree, which
>> just leaves the weird case, of which there will hopefully be only
>> a few.
>>
>> I do share your worry that this might break some machines, but
>> the only way to really find out is to get this code out there
>> I'm afraid.
>>
>> I have just written a blog post asking for people to check if
>> their laptop might be affected; and to report various details
>> to me of their laptop is affected:
>>
>> https://hansdegoede.dreamwidth.org/26548.html
>>
>> Lets wait and see how this goes. If I get (too) many reports then
>> I will send a revert of the addition of the:
>>
>> if (acpi_video_get_backlight_type() != acpi_backlight_native)
>> return;
>>
>> check to the i915 / radeon / amd / nouveau drivers.
>>
>> (And if I only get a couple of reports I will probably just submit
>> DMI quirks for the affected models).
> 
> Sounds reasonable to me, FWIW.

I have received quite a few test reports as a result of my blogpost
(and of the blogpost's mention in an arstechnica article).

Long story short, Matthew, you are right. Quite a few laptop models
will end up with an empty /sys/class/backlight because of the native
backlight class devices no longer registering when
acpi_video_backlight_use_native() returns false.

I will submit a patch-set later today to fix this (by making 
cpi_video_backlight_use_native() always return true for now).

More detailed summary/analysis of the received test reports:

-30 unaffected models

-The following laptop models:
 Acer Aspire 1640
 Apple MacBook 2.1
 Apple MacBook 4.1
 Apple MacBook Pro 7.1 (uses nv_backligh instead of intel_backlight!)
 HP Compaq nc6120
 IBM ThinkPad X40
 System76 Starling Star1

 All only have a native intel_backlight interface and the heuristics from
 acpi_video_get_backlight_type() return acpi_backlight_vendor there causing
 the changes in 6.1 to not register native backlights when
 acpi_video_backlight_use_native() returns false resulting in an empty
 /sys/class/backlight, breaking users ability to control their laptop
 panel's brightness.

 I will submit a patch to always make acpi_video_backlight_use_native()
 return true for now to work around this for 6.1.

 I do plan to try to re-introduce that change again later. First I need to
 change the heuristics to still native on more models so that on models
 where the native backlight is the only (working) entry they will
 return native.

-The Dell N1410 has acpi_video support and acpi_osi_is_win8() returns false
 so acpi_video_get_backlight_type() returns acpi_video, but acpi_video
 fails to register a backlight device due to a_BCM eval error.
 The intel_backlight interface works fine, but this model is going to need
 a DMI-use-native-quirk to avoid intel_backlight disappearing when
 acpi_video_backlight_use_native() is change

Re: [PATCH v5 02/31] drm/i915: Don't register backlight when another backlight should be used (v2)

2022-10-27 Thread Hans de Goede
Hi Matthew,

On 10/27/22 11:11, Matthew Garrett wrote:
> On Thu, Oct 27, 2022 at 10:51:45AM +0200, Hans de Goede wrote:
> 
>> In their backlight register paths and this has been present since
>> circa 2015.
>>
>> So both before and after my 6.1 refactor vendor is only preferred
>> on devices which don't implement the ACPI video bus control method.
> 
> Sorry, yes, that's the case I meant.
> 
>> Just because a vendor interface is present does not mean that it will
>> work. Unfortunately for none of the 3 main native/acpi_video/vendor
>> backlight control methods the control method being present also guarantees
>> that it will work. Which completely sucks, but it is the reality we
>> have to deal with.
> 
> But traditionally that's been logic that we've encoded into the vendor 
> drivers, which can take other factors into account when determining 
> whether the exposed interface works. You've now discarded that 
> knowledge.

As I already mentioned in my previous email, the vendor drivers have
been using something like:

if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
return;

In their backlight register paths *since 2015* and even before
then most of them called some acpi_video helper function to determine
if ACPI video backlight control was available and skipped registering
their backlight device if that returned true. And calling that
acpi_video helper is as smart as they traditionally were. That +
DMI quirks and we still have all those quirks.

I was very careful with the refactoring landing in 6.1 to *not*
change any of this.

The *only* behavior which actually is new in 6.1 is the native GPU
drivers now doing the equivalent of:

if (acpi_video_get_backlight_type() != acpi_backlight_native)
return;

In their backlight register paths (i), which is causing the native
backlight to disappear on your custom laptop setup and on Chromebooks
(with the Chromebooks case being already solved I hope.).

I am fully aware that this may turn out to also impact other laptops.
I'm keeping out an eye for this and I have specifically reached-out
to the coreboot community asking them to test 6.1 .

> The only way you can maintain the degree of functionality 
> that 6.0 had is to move that determination into core code, or 
> alternatively support dynamic reattachment of backlight interfaces based 
> on vendor drivers loading later. An alternative would be to just revert 
> all of this, and instead only use this logic for the output property 
> interface (which would still result in different outcomes, but only for 
> userland that's choosing to use the new interface, so that's a different 
> problem).

Yes I am considering dropping the "acpi_video_get_backlight_type() !=
acpi_backlight_native" check from at least the i915 driver if we get more
bug reports and then indeed only do the equivalent of that check in
the code for the new output property.

I agree this is a possible solution if this turns out to break more
systems and there is no other easy/clean way to fix those. But I would
greatly prefer to keep this change and stop the IMHO bad kernel behavior
of "registering multiple backlight-devices for a single panel and then
let userspace sort it out".

Regards,

Hans


i) Before this, the kernel was relying on userspace preferring acpi_video
or vendor backlight devices over native if both are present and the
native backlight devices were registered unconditionally.





Re: [PATCH v5 02/31] drm/i915: Don't register backlight when another backlight should be used (v2)

2022-10-27 Thread Hans de Goede
Hi,

On 10/26/22 22:49, Matthew Garrett wrote:
> On Wed, Oct 26, 2022 at 11:59:28AM +0200, Hans de Goede wrote:
> 
>> Ok, so this is a local customization to what is already a custom BIOS
>> for a custom motherboard. There is a lot of custom in that sentence and
>> TBH at some point things might become too custom for them to be expected
>> to work OOTB.
> 
> But it *did* work OOTB before. You broke it. I accept that I'm a 
> ludicrously weird corner case here, but there are going to be other 
> systems that are also affected by this.
> 
>> I'm afraid things are not that simple. I assume that with
>> "if ACPI backlight control is expected to work" you mean don't
>> use ACPI backlight control when (acpi_osi_is_win8() && native_available)
>> evaluates to true because it is known to be broken on some of
>> those systems because Windows 8 stopped using it ?
> 
> Correct.
> 
>> Unfortunately something similar applies to vendor interfaces,
>> When Windows XP started using (and mandating for certification
>> IIRC) ACPI backlight control, vendors still kept their own
>> vendor specific EC/smbios/ACPI/WMI backlight interfaces around for
>> a long long time, except they were often no longer tested.
> 
> The current situation (both before your patchset and with its current 
> implementation) is that vendor is preferred to native, so if the vendor 
> interface is present then we're already using it.

All vendor drivers that I'm aware of have:

if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
return;

In their backlight register paths and this has been present since
circa 2015.

So both before and after my 6.1 refactor vendor is only preferred
on devices which don't implement the ACPI video bus control method.

>>> The 
>>> problem you're dealing with is that the knowledge of whether or not 
>>> there's a vendor interface isn't something the core kernel code knows 
>>> about. What you're proposing here is effectively for us to expose 
>>> additional information about whether or not there's a vendor interface 
>>> in the system firmware, but since we're talking in some cases about 
>>> hardware that's almost 20 years old, we're not realistically going to 
>>> get those old machines fixed.
>>
>> I don't understand why you keep talking about the old vendor interfaces,
>> at least for the chromebook part of this thread the issue is that
>> the i915 driver no longer registers the intel_backlight device which
>> is a native device type, which is caused by the patch this email
>> thread is about (and old vendor interfaces do not come into play
>> at all here). So AFAICT this is a native vs acpi backlight control
>> issue ?
> 
> I'm referring to your proposed patch that changed the default from 
> backlight_vendor to backlight_native, which would fix my machine and 
> Chromebooks but break anything that relies on the vendor interfaces.

I see. I agree that preferring native over vendor on machines
which do not have ACPI video backlight control will cause issues
on older machines. Avoiding this scenario is exactly why currently
the native check is conditional on the presence of ACPI video
backlight control.

>> I really want to resolve your bug, but I still lack a lot of info,
>> like what backlight interface you were actually using in 6.0 ?
> 
> Native.
> 
>> {
>>  .callback = video_detect_force_video,
>>  /* ThinkPad X201s */
>>  .matches = {
>> DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
>> DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X201s"),
>> },
>> },
>>
>> will trigger.
> 
> In this case you'd break anyone else running the system who isn't using 
> the hacked EC and different ACPI tables - obviously there's ways round 
> this, but realistically since I'm (as far as I know) the only person in 
> this situation it makes more sense for me to add a kernel parameter than 
> carry around an exceedingly niche DMI quirk. I'm fine with that. But the 
> point I'm trying to make is that the machines *are* telling you whether 
> they'd prefer vendor or native.

I wish that that ("telling you whether they'd prefer vendor or native")
were true. But that does not match my experience at all and I've been
working on making the kernel pick the right backlight interface on
laptops since 2014.

Just because a vendor interface is present does not mean that it will
work. Unfortunately for none of the 3 main native/acpi_video/vendor
backlight control methods the control method being present also guarantees
that it will work. Which completely sucks, but it is the reality we
have to deal with.

> , and you're not taking that into account 
> in the video_detect code.

Regards,

Hans



Re: [PATCH v5 02/31] drm/i915: Don't register backlight when another backlight should be used (v2)

2022-10-27 Thread Hans de Goede
Hi,

On 10/27/22 14:09, Rafael J. Wysocki wrote:
> On Thu, Oct 27, 2022 at 12:37 PM Hans de Goede  wrote:
>>
>> Hi,
>>
>> On 10/27/22 11:52, Matthew Garrett wrote:
>>> On Thu, Oct 27, 2022 at 11:39:38AM +0200, Hans de Goede wrote:
>>>
>>>> The *only* behavior which actually is new in 6.1 is the native GPU
>>>> drivers now doing the equivalent of:
>>>>
>>>>  if (acpi_video_get_backlight_type() != acpi_backlight_native)
>>>>  return;
>>>>
>>>> In their backlight register paths (i), which is causing the native
>>>> backlight to disappear on your custom laptop setup and on Chromebooks
>>>> (with the Chromebooks case being already solved I hope.).
>>>
>>> It's causing the backlight control to vanish on any machine that isn't
>>> ((acpi_video || vendor interface) || !acpi). Most machines that fall
>>> into that are either weird or Chromebooks or old, but there are machines
>>> that fall into that.
>>
>> I acknowledge that their are machines that fall into this category,
>> but I expect / hope there to be so few of them that we can just DMI
>> quirk our way out if this.
>>
>> I believe the old group to be small because:
>>
>> 1. Generally speaking the "native" control method is usually not
>> present on the really old (pre ACPI video spec) mobile GPUs.
>>
>> 2. On most old laptops I would still expect there to be a vendor
>> interface too, and if both get registered standard desktop environments
>> will prefer the vendor one, so then we need a native DMI quirk to
>> disable the vendor interface anyways and we already have a bunch of
>> those, so some laptops in this group are already covered by DMI quirks.
>>
>> And a fix for the Chromebook case is already in Linus' tree, which
>> just leaves the weird case, of which there will hopefully be only
>> a few.
>>
>> I do share your worry that this might break some machines, but
>> the only way to really find out is to get this code out there
>> I'm afraid.
>>
>> I have just written a blog post asking for people to check if
>> their laptop might be affected; and to report various details
>> to me of their laptop is affected:
>>
>> https://hansdegoede.dreamwidth.org/26548.html
>>
>> Lets wait and see how this goes. If I get (too) many reports then
>> I will send a revert of the addition of the:
>>
>> if (acpi_video_get_backlight_type() != acpi_backlight_native)
>> return;
>>
>> check to the i915 / radeon / amd / nouveau drivers.
>>
>> (And if I only get a couple of reports I will probably just submit
>> DMI quirks for the affected models).
> 
> Sounds reasonable to me, FWIW.
> 
> And IIUC the check above can be overridden by passing
> acpi_backlight=native in the kernel command line, right?

Right, that can be used as a quick workaround, but we really do
want this to work OOTB everywhere.

Regards,

Hans



Re: [PATCH v5 02/31] drm/i915: Don't register backlight when another backlight should be used (v2)

2022-10-27 Thread Hans de Goede
Hi,

On 10/27/22 11:52, Matthew Garrett wrote:
> On Thu, Oct 27, 2022 at 11:39:38AM +0200, Hans de Goede wrote:
> 
>> The *only* behavior which actually is new in 6.1 is the native GPU
>> drivers now doing the equivalent of:
>>
>>  if (acpi_video_get_backlight_type() != acpi_backlight_native)
>>  return;
>>
>> In their backlight register paths (i), which is causing the native
>> backlight to disappear on your custom laptop setup and on Chromebooks
>> (with the Chromebooks case being already solved I hope.).
> 
> It's causing the backlight control to vanish on any machine that isn't 
> ((acpi_video || vendor interface) || !acpi). Most machines that fall 
> into that are either weird or Chromebooks or old, but there are machines 
> that fall into that.

I acknowledge that their are machines that fall into this category,
but I expect / hope there to be so few of them that we can just DMI
quirk our way out if this.

I believe the old group to be small because:

1. Generally speaking the "native" control method is usually not
present on the really old (pre ACPI video spec) mobile GPUs.

2. On most old laptops I would still expect there to be a vendor
interface too, and if both get registered standard desktop environments
will prefer the vendor one, so then we need a native DMI quirk to
disable the vendor interface anyways and we already have a bunch of
those, so some laptops in this group are already covered by DMI quirks.

And a fix for the Chromebook case is already in Linus' tree, which
just leaves the weird case, of which there will hopefully be only
a few.

I do share your worry that this might break some machines, but
the only way to really find out is to get this code out there
I'm afraid.

I have just written a blog post asking for people to check if
their laptop might be affected; and to report various details
to me of their laptop is affected:

https://hansdegoede.dreamwidth.org/26548.html

Lets wait and see how this goes. If I get (too) many reports then
I will send a revert of the addition of the:

if (acpi_video_get_backlight_type() != acpi_backlight_native)
return;

check to the i915 / radeon / amd / nouveau drivers.

(And if I only get a couple of reports I will probably just submit
DMI quirks for the affected models).

Regards,

Hans





Re: [PATCH v5 02/31] drm/i915: Don't register backlight when another backlight should be used (v2)

2022-10-26 Thread Hans de Goede
Hi,

On 10/26/22 01:40, Matthew Garrett wrote:
> On Wed, Oct 26, 2022 at 01:27:25AM +0200, Hans de Goede wrote:
> 
>> this code should actually set the ACPI_VIDEO_BACKLIGHT flag:
>> drivers/acpi/scan.c:
>>
>> static acpi_status
>> acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context,
>>   void **return_value)
>> {
>> long *cap = context;
>>
>> if (acpi_has_method(handle, "_BCM") &&
>> acpi_has_method(handle, "_BCL")) {
>> acpi_handle_debug(handle, "Found generic backlight 
>> support\n");
>> *cap |= ACPI_VIDEO_BACKLIGHT;
>> /* We have backlight support, no need to scan further */
>> return AE_CTRL_TERMINATE;
>> }
>> return 0;
>> }
> 
> Ah, yeah, my local tree no longer matches the upstream behaviour because 
> I've hacked the EC firmware to remove the backlight trigger because it 
> had an extremely poor brightness curve and also automatically changed it 
> on AC events - as a result I removed the backlight code from the DSDT 
> and just fell back to the native control. Like I said I'm a long way 
> from the normal setup, but this did previously work.

Ok, so this is a local customization to what is already a custom BIOS
for a custom motherboard. There is a lot of custom in that sentence and
TBH at some point things might become too custom for them to be expected
to work OOTB.

Note that you can always just override the choses made by the heuristisc/
quirks on the kernel commandline by adding:

acpi_backlight=native   (I think you want this one?)

or if you want the old thinkpad_acpi module vendor/EC interface:

acpi_backlight=vendor

Asking you to pass this on the commandline does not seem like a huge
stretch given the large amount of hw/firmware customization you have done ?

> The "right" logic here seems pretty simple: if ACPI backlight control is 
> expected to work, use it. If it isn't, but there's a vendor interface, 
> use it. If there's no vendor interface, use the native interface.

I'm afraid things are not that simple. I assume that with
"if ACPI backlight control is expected to work" you mean don't
use ACPI backlight control when (acpi_osi_is_win8() && native_available)
evaluates to true because it is known to be broken on some of
those systems because Windows 8 stopped using it ?

Unfortunately something similar applies to vendor interfaces,
When Windows XP started using (and mandating for certification
IIRC) ACPI backlight control, vendors still kept their own
vendor specific EC/smbios/ACPI/WMI backlight interfaces around for
a long long time, except they were often no longer tested.

So basically we have 3 major backlight control methods:

1. native GPU backlight control, which sometimes does not work
on older laptops because the backlight is connected to the EC
rather then the GPU there, yet often still enabled in the
video-bios-tables so the GPU drivers will still try to use it.

2. ACPI -> known to be always present on recent Windows laptops
because mandated by the hardware certification requirements
(even on Windows 8+), but regularly broken on Windows 8+ because
their backlight control was moved from the core-os to the GPU
drivers and those typically use the native method.

3. Vendor specific EC/smbios/ACPI/WMI interfaces which work
on older laptops, but are often present on newer laptops
despite them no longer working and to get working backlight
control either 1. or 2. should be used.

So basically non of the 3 main backlight control methods can
be trusted even if they are present. Which is why need to have
a combination of heuristics + quirks.

And I have been working on moving all this into a central
place in drivers/acpi/video_detect.c because having
the heuristics + quirks spread out all over the place does
not help.

> The 
> problem you're dealing with is that the knowledge of whether or not 
> there's a vendor interface isn't something the core kernel code knows 
> about. What you're proposing here is effectively for us to expose 
> additional information about whether or not there's a vendor interface 
> in the system firmware, but since we're talking in some cases about 
> hardware that's almost 20 years old, we're not realistically going to 
> get those old machines fixed.

I don't understand why you keep talking about the old vendor interfaces,
at least for the chromebook part of this thread the issue is that
the i915 driver no longer registers the intel_backlight device which
is a native device type, which is caused by the patch this email
thread is about (and old vendor interfaces do not come into play
at all here). So AFAICT this is a native vs acpi backlight control
issue ?

I rea

Re: [PATCH v5 02/31] drm/i915: Don't register backlight when another backlight should be used (v2)

2022-10-26 Thread Hans de Goede
Hi,

On 10/25/22 22:40, Matthew Garrett wrote:
> On Tue, Oct 25, 2022 at 10:25:33PM +0200, Hans de Goede wrote:
> 
>> Having the native driver come and then go and be replaced
>> with the vendor driver would also be quite inconvenient
>> for these planned changes.
> 
> I understand that it would be inconvenient, but you've broken existing 
> working setups.

I fully acknowledge that I have broken existing working setups
and I definitely want to see this fixed before say 6.1-rc6!

I'm not convinced (at all) that any solutions which re-introduce
acpi_video_get_backlight_type() return-s value changing
half way the boot, with some backlight interface getting
registered and then unregistered again later because
it turns out to be the wrong one is a good fix here.

The whole goal of the refactor was to leave these sorts
of shenanigans behind us.

>> Can you perhaps explain a bit in what way your laptop
>> is weird ?
> 
> It's a Chinese replacement motherboard for a Thinkpad X201, running my 
> own port of Coreboot. Its DMI strings look like an actual Thinkpad in 
> order to ensure that thinkpad_acpi can bind for hotkey suport, so it's 
> hard to quirk. It'll actually be fixed by your proposed patch to fall 
> back to native rather than vendor, but that patch will break any older 
> machines that offer a vendor interface and don't have the native control 
> hooked up (pretty sure at least the Thinkpad X40 falls into that 
> category).

So looking at:

https://review.coreboot.org/plugins/gitiles/coreboot/+/refs/heads/master/src/mainboard/51nb/x210/acpi/graphics.asl

this code should actually set the ACPI_VIDEO_BACKLIGHT flag:
drivers/acpi/scan.c:

static acpi_status
acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context,
  void **return_value)
{
long *cap = context;

if (acpi_has_method(handle, "_BCM") &&
acpi_has_method(handle, "_BCL")) {
acpi_handle_debug(handle, "Found generic backlight support\n");
*cap |= ACPI_VIDEO_BACKLIGHT;
/* We have backlight support, no need to scan further */
return AE_CTRL_TERMINATE;
}
return 0;
}

What does seem to be missing compared to a "normal" DSDT
is a call to _OSI("Windows 2012") so I would expect this code
in acpi_video_get_backlight_type():

/* On systems with ACPI video use either native or ACPI video. */
if (video_caps & ACPI_VIDEO_BACKLIGHT) {
/*
 * Windows 8 and newer no longer use the ACPI video interface,
 * so it often does not work. If the ACPI tables are written
 * for win8 and native brightness ctl is available, use that.
 *
 * The native check deliberately is inside the if acpi-video
 * block on older devices without acpi-video support native
 * is usually not the best choice.
 */
if (acpi_osi_is_win8() && native_available)
return acpi_backlight_native;
else
return acpi_backlight_video;
}

To enter the "return acpi_backlight_video" path since acpi_osi_is_win8()
will return false.

And then the ACPI backlight methods from:
https://review.coreboot.org/plugins/gitiles/coreboot/+/refs/heads/master/src/mainboard/51nb/x210/acpi/graphics.asl

should get called when changing the backlight brightness,
so assuming that those methods work then things should work fine.

What does "ls /sys/class/backlight" output on the X210 / NB51 board
with a 6.0 kernel? And what does it output with the 6.1-rc? kernels?

IOW which backlight device / control method is being selected
and which one do you want / which one(s) do actually work?

I have been thinking about maybe doing something with 
a dmi_get_bios_year() check (see below), but that will cause
native to get prefered over vendor on old ThinkPads with
coreboot (and thus a new enough year in DMI_BIOS_DATE), which
will likely break backlight control there (if i915 offers
backlight control on those that is).

Also I wonder if it would be possible to set DMI_BIOS_VENDOR
to "Coreboot" so that we can use that? Note that thinkpad_acpi
does not care about the DMI_BIOS_VENDOR value, at least
not on models which start their DMI_PRODUCT_VERSION with
either "ThinkPad" or "Lenovo".

###

Looking more at this I notice that coreboot has a
drivers_intel_gma_displays_ssdt_generate() which seems to
at least always generate ACPI video bus ASL including
backlight control bits.

So the only reason why the current heurstics are not
returning native is the acpi_osi_is_win8() check.

So maybe that beeds to become:

if ((acpi_osi_is_win8() || dmi_get_bios_year() &

Re: [PATCH v5 02/31] drm/i915: Don't register backlight when another backlight should be used (v2)

2022-10-25 Thread Hans de Goede
Hi (again),

On 10/25/22 22:25, Hans de Goede wrote:
> Hi Matthew,
> 
> On 10/25/22 21:32, Matthew Garrett wrote:
>> On Tue, Oct 25, 2022 at 08:50:54PM +0200, Hans de Goede wrote:
>>
>>> That is a valid point, but keep in mind that this is only used on ACPI
>>> platforms and then only on devices with a builtin LCD panel and then
>>> only by GPU drivers which actually call acpi_video_get_backlight_type(),
>>> so e.g. not by all the ARM specific display drivers.
>>>
>>> So I believe that Chromebooks quite likely are the only devices with
>>> this issue.
>>
>> My laptop is, uh, weird, but it falls into this category.
>>  
>>>> I think for this to work correctly you need to have 
>>>> the infrastructure be aware of whether or not a vendor interface exists, 
>>>> which means having to handle cleanup if a vendor-specific module gets 
>>>> loaded later.
>>>
>>> Getting rid of the whole ping-ponging of which backlight drivers
>>> get loaded during boot was actually one of the goals of the rework
>>> which landed in 6.1 this actually allowed us to remove some quirks
>>> because some hw/firmware did not like us changing our mind and
>>> switching backlight interfaces after first poking another one.
>>> So we definitely don't want to go back to the ping-pong thing.
>>
>> Defaulting to native but then having a vendor driver be able to disable 
>> native drivers seems easiest? It shouldn't be a regression over the 
>> previous state of affairs since both drivers were being loaded already.
> 
> Part of the reason for the ACPI backlight detect refactor is
> because of a planned new backlight uAPI where the brightness
> control becomes a property on the drm connector object, for a
> RFC including the rationale behind this planned uAPI change see:
> https://lore.kernel.org/dri-devel/b61d3eeb-6213-afac-2e70-7b9791c86...@redhat.com/
> 
> These plans require that there is only 1 backlight device
> registered (per panel).
> 
> Having the native driver come and then go and be replaced
> with the vendor driver would also be quite inconvenient
> for these planned changes.
> 
> As such I would rather find a solution for your "weird"
> laptop so that acpi_video_get_backlight_type() just always
> returns vendor there.

I just realized that your have vendor driver unregister
the native one is suggested as an alternative for
the new behavior where the i915 driver no longer
registers its native backlight in cases where
acpi_video_get_backlight_type() does not return native,
and that you probably actually want the native backlight
device, right ?

So the above should read:

"so that acpi_video_get_backlight_type() just always
returns native there."

> Note that drivers/acpi/video_detect.c already has a DMI
> quirk tables for models where the heuristics from
> acpi_video_get_backlight_type() don't work. In general
> we (mostly me) try to make it so that the heuristics
> work on most models, to avoid needing to add every model
> under the sun to the DMI quirk table, but if your laptop
> is somehow special then adding a DMI quirk for it should
> be fine ?
> 
> Can you perhaps explain a bit in what way your laptop
> is weird ?

I guess it is weird in that it does not have the ACPI video,
or at least does not offer ACPI video bus backlight control
in its ACPI tables?

Can you perhaps email me an acpidump of the laptop ?

> Note that technically if the native backlight does not work,
> then the GPU driver really should not even try to register
> it. But sometimes the video-bios-tables claim the backlight
> pwm input is attached to the GPU while it is not and things
> have evolved in such a way that the DMI quirks for that
> live in acpi/video_detect.c rather then in the GPU driver.

And this bit can be ignored then because it certainly
is not relevant if you actually want the native driver.

Regards,

Hans




Re: [PATCH v5 02/31] drm/i915: Don't register backlight when another backlight should be used (v2)

2022-10-25 Thread Hans de Goede
Hi Matthew,

On 10/25/22 21:32, Matthew Garrett wrote:
> On Tue, Oct 25, 2022 at 08:50:54PM +0200, Hans de Goede wrote:
> 
>> That is a valid point, but keep in mind that this is only used on ACPI
>> platforms and then only on devices with a builtin LCD panel and then
>> only by GPU drivers which actually call acpi_video_get_backlight_type(),
>> so e.g. not by all the ARM specific display drivers.
>>
>> So I believe that Chromebooks quite likely are the only devices with
>> this issue.
> 
> My laptop is, uh, weird, but it falls into this category.
>  
>>> I think for this to work correctly you need to have 
>>> the infrastructure be aware of whether or not a vendor interface exists, 
>>> which means having to handle cleanup if a vendor-specific module gets 
>>> loaded later.
>>
>> Getting rid of the whole ping-ponging of which backlight drivers
>> get loaded during boot was actually one of the goals of the rework
>> which landed in 6.1 this actually allowed us to remove some quirks
>> because some hw/firmware did not like us changing our mind and
>> switching backlight interfaces after first poking another one.
>> So we definitely don't want to go back to the ping-pong thing.
> 
> Defaulting to native but then having a vendor driver be able to disable 
> native drivers seems easiest? It shouldn't be a regression over the 
> previous state of affairs since both drivers were being loaded already.

Part of the reason for the ACPI backlight detect refactor is
because of a planned new backlight uAPI where the brightness
control becomes a property on the drm connector object, for a
RFC including the rationale behind this planned uAPI change see:
https://lore.kernel.org/dri-devel/b61d3eeb-6213-afac-2e70-7b9791c86...@redhat.com/

These plans require that there is only 1 backlight device
registered (per panel).

Having the native driver come and then go and be replaced
with the vendor driver would also be quite inconvenient
for these planned changes.

As such I would rather find a solution for your "weird"
laptop so that acpi_video_get_backlight_type() just always
returns vendor there.

Note that drivers/acpi/video_detect.c already has a DMI
quirk tables for models where the heuristics from
acpi_video_get_backlight_type() don't work. In general
we (mostly me) try to make it so that the heuristics
work on most models, to avoid needing to add every model
under the sun to the DMI quirk table, but if your laptop
is somehow special then adding a DMI quirk for it should
be fine ?

Can you perhaps explain a bit in what way your laptop
is weird ?

Note that technically if the native backlight does not work,
then the GPU driver really should not even try to register
it. But sometimes the video-bios-tables claim the backlight
pwm input is attached to the GPU while it is not and things
have evolved in such a way that the DMI quirks for that
live in acpi/video_detect.c rather then in the GPU driver.

Regards,

Hans



Re: [PATCH v5 02/31] drm/i915: Don't register backlight when another backlight should be used (v2)

2022-10-25 Thread Hans de Goede
Hi,

On 10/24/22 22:30, Matthew Garrett wrote:
> On Tue, Sep 27, 2022 at 01:04:52PM +0200, Hans de Goede wrote:
> 
>> So to fix this we need to make acpi_video_get_backlight_type()
>> return native on the Acer Chromebook Spin 713.
> 
> Isn't the issue broader than that? Unless the platform is Windows 8 or 
> later, we'll *always* (outside of some corner cases) return 
> acpi_backlight_vendor if there's no ACPI video interface. This is broken 
> for any platform that implements ACPI but relies on native video 
> control, which is going to include a range of Coreboot platforms, not 
> just Chromebooks.

That is a valid point, but keep in mind that this is only used on ACPI
platforms and then only on devices with a builtin LCD panel and then
only by GPU drivers which actually call acpi_video_get_backlight_type(),
so e.g. not by all the ARM specific display drivers.

So I believe that Chromebooks quite likely are the only devices with
this issue.

We could do something like the patch which I have pasted at the end
of this email, but as its commit message notes there is a real
good chance this will cause regressions on some laptops.

So if we ever decide to go with something like the patch below,
I think we should at a minimum wait for the next cycle with that,
because 6.1 already significantly reworks the ACPI backlight
detect handling and I don't want to throw this into the mix
on top of those changes.

> I think for this to work correctly you need to have 
> the infrastructure be aware of whether or not a vendor interface exists, 
> which means having to handle cleanup if a vendor-specific module gets 
> loaded later.

Getting rid of the whole ping-ponging of which backlight drivers
get loaded during boot was actually one of the goals of the rework
which landed in 6.1 this actually allowed us to remove some quirks
because some hw/firmware did not like us changing our mind and
switching backlight interfaces after first poking another one.
So we definitely don't want to go back to the ping-pong thing.

Regards,

Hans



>From 67ee5d7163e33e65dca06887befd0639b0345883 Mon Sep 17 00:00:00 2001
From: Hans de Goede 
Date: Tue, 25 Oct 2022 20:38:56 +0200
Subject: [PATCH] ACPI: video: Simplify __acpi_video_get_backlight_type()

Simplify __acpi_video_get_backlight_type() removing a nested if which
makes the flow harder to follow.

Note this will cause a behavior change on devices which do not have
ACPI video support but do have both a vendor and native backlight
driver available. This change will cause these devices to switch
from vendor to native.

This may not be desirable in all cases, this is likely to happen
on significantly older laptops, where there very well might be
cases where the native driver does not work because the backlight is
controlled by the EC.

This removes the need for the special handling of Chromebooks,
these will now hit the if (native_available) return acpi_backlight_native;
path.

Signed-off-by: Hans de Goede 
---
 drivers/acpi/video_detect.c | 36 +++-
 1 file changed, 11 insertions(+), 25 deletions(-)

diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 9cd8797d12bb..9bd85b159e02 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -668,11 +668,6 @@ static const struct dmi_system_id video_detect_dmi_table[] 
= {
{ },
 };
 
-static bool google_cros_ec_present(void)
-{
-   return acpi_dev_found("GOOG0004");
-}
-
 /*
  * Determine which type of backlight interface to use on this system,
  * First check cmdline, then dmi quirks, then do autodetect.
@@ -718,30 +713,21 @@ static enum acpi_backlight_type 
__acpi_video_get_backlight_type(bool native)
if (apple_gmux_present())
return acpi_backlight_apple_gmux;
 
-   /* On systems with ACPI video use either native or ACPI video. */
-   if (video_caps & ACPI_VIDEO_BACKLIGHT) {
-   /*
-* Windows 8 and newer no longer use the ACPI video interface,
-* so it often does not work. If the ACPI tables are written
-* for win8 and native brightness ctl is available, use that.
-*
-* The native check deliberately is inside the if acpi-video
-* block on older devices without acpi-video support native
-* is usually not the best choice.
-*/
-   if (acpi_osi_is_win8() && native_available)
-   return acpi_backlight_native;
-   else
-   return acpi_backlight_video;
-   }
-
/*
-* Chromebooks that don't have backlight handle in ACPI table
-* are supposed to use native backlight if it's available.
+* Pre Windows 8, Windows uses ACPI video, so prefer that over native
+* on pre-win8 systems (Windows 8+ no longer uses ACPI 

Re: [PATCH v5 02/31] drm/i915: Don't register backlight when another backlight should be used (v2)

2022-09-27 Thread Hans de Goede
Hi Dmitry,

On 9/26/22 01:39, Dmitry Osipenko wrote:
> 25.08.2022 17:36, Hans de Goede пишет:
>> Before this commit when we want userspace to use the acpi_video backlight
>> device we register both the GPU's native backlight device and acpi_video's
>> firmware acpi_video# backlight device. This relies on userspace preferring
>> firmware type backlight devices over native ones.
>>
>> Registering 2 backlight devices for a single display really is
>> undesirable, don't register the GPU's native backlight device when
>> another backlight device should be used.
>>
>> Changes in v2:
>> - Use drm_info(drm_dev,  ...) for log messages
>>
>> Reviewed-by: Jani Nikula 
>> Signed-off-by: Hans de Goede 
>> ---
>>  drivers/gpu/drm/i915/display/intel_backlight.c | 7 +++
>>  1 file changed, 7 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c 
>> b/drivers/gpu/drm/i915/display/intel_backlight.c
>> index 681ebcda97ad..03c7966f68d6 100644
>> --- a/drivers/gpu/drm/i915/display/intel_backlight.c
>> +++ b/drivers/gpu/drm/i915/display/intel_backlight.c
>> @@ -8,6 +8,8 @@
>>  #include 
>>  #include 
>>  
>> +#include 
>> +
>>  #include "intel_backlight.h"
>>  #include "intel_backlight_regs.h"
>>  #include "intel_connector.h"
>> @@ -952,6 +954,11 @@ int intel_backlight_device_register(struct 
>> intel_connector *connector)
>>  
>>  WARN_ON(panel->backlight.max == 0);
>>  
>> +if (!acpi_video_backlight_use_native()) {
>> +drm_info(>drm, "Skipping intel_backlight registration\n");
>> +return 0;
>> +}
>> +
>>  memset(, 0, sizeof(props));
>>  props.type = BACKLIGHT_RAW;
>>  
> 
> This breaks backlight on Acer Chromebook Spin 713 because backlight
> isn't registered anymore. Any ideas how to fix it?

Thank you for reporting this.

Let me start with some background info on this change:

As you may have noticed sometimes on laptops there are multiple
backlights registered under /sys/class/backlight and we just let
userspace figure out which one to use, which is quite bad.

This patch is part of a series fixing this, this is also preparation
for adding a new display brightness control API where the brightness is
a property on the drm_connector object for the panel/display, which
of course requires the kernel to know which backlight control method
to use.

If you are want to know more about the new userspace API see:
https://lore.kernel.org/dri-devel/b61d3eeb-6213-afac-2e70-7b9791c86...@redhat.com/

What this series does is on x86/ACPI platforms make all the possible
/sys/class/backlight providers call: acpi_video_get_backlight_type()
(acpi_video_backlight_use_native() is a special wrapper) and only if
that returns their type then have them register their backlight device.

So to fix this we need to make acpi_video_get_backlight_type()
return native on the Acer Chromebook Spin 713.

The heuristics used in acpi_video_get_backlight_type() is
explained by comments in the function:

/*
 * The below heuristics / detection steps are in order of descending
 * presedence. The commandline takes presedence over anything else.
 */
/* DMI quirks override any autodetection. */
/* Special cases such as nvidia_wmi_ec and apple gmux. */

None of these apply here, so we end up in the core of this function:

/* On systems with ACPI video use either native or ACPI video. */
if (video_caps & ACPI_VIDEO_BACKLIGHT) {
/*
 * Windows 8 and newer no longer use the ACPI video interface,
 * so it often does not work. If the ACPI tables are written
 * for win8 and native brightness ctl is available, use that.
 *
 * The native check deliberately is inside the if acpi-video
 * block on older devices without acpi-video support native
 * is usually not the best choice.
 */
if (acpi_osi_is_win8() && native_available)
return acpi_backlight_native;
else
return acpi_backlight_video;
}

/* No ACPI video (old hw), use vendor specific fw methods. */
return acpi_backlight_vendor;


The acpi_video_backlight_use_native() wrappers causes native_available to
be true, so one or both of these 2 conditions fail:

1.  if (video_caps & ACPI_VIDEO_BACKLIGHT)
2.  if (acpi_osi_is_win8())

I assume that 2. will actually likely fail on quite a few chromebooks.
So to fix this you could do something like this:

diff --git a/drivers/acpi/video_detect.c b/drivers

Re: [GIT PULL] Immutable backlight-detect-refactor branch between acpi, drm-* and pdx86

2022-09-14 Thread Hans de Goede
Hi,

On 9/14/22 12:29, Maxime Ripard wrote:
> Hi Hans,
> 
> On Mon, Sep 05, 2022 at 10:35:47AM +0200, Hans de Goede wrote:
>> Hi All,
>>
>> Now that all patches have been reviewed/acked here is an immutable 
>> backlight-detect-refactor
>> branch with 6.0-rc1 + the v5 patch-set, for merging into the relevant (acpi, 
>> drm-* and pdx86)
>> subsystems.
>>
>> Please pull this branch into the relevant subsystems.
>>
>> I will merge this into the review-hans branch of the pdx86 git tree today and
>> from there it will move to for-next once the builders have successfully 
>> build-tested
>> the merge.
> 
> I merged it into drm-misc-next, thanks!

Great, thank you!

Regards,

Hans



[GIT PULL] Immutable backlight-detect-refactor branch between acpi, drm-* and pdx86

2022-09-06 Thread Hans de Goede
Hi All,

Now that all patches have been reviewed/acked here is an immutable 
backlight-detect-refactor
branch with 6.0-rc1 + the v5 patch-set, for merging into the relevant (acpi, 
drm-* and pdx86)
subsystems.

Please pull this branch into the relevant subsystems.

I will merge this into the review-hans branch of the pdx86 git tree today and
from there it will move to for-next once the builders have successfully 
build-tested
the merge.

Regards,

Hans


The following changes since commit 568035b01cfb107af8d2e4bd2fb9aea22cf5b868:

  Linux 6.0-rc1 (2022-08-14 15:50:18 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git 
tags/backlight-detect-refactor-1

for you to fetch changes up to 4f96b1bc156e7076f6efedc2a76a8c7e897c7977:

  drm/todo: Add entry about dealing with brightness control on devices with > 1 
panel (2022-09-03 12:17:27 +0200)


Immutable backlight-detect-refactor branch between acpi, drm-* and pdx86

Tag (immutable branch) with v6.0-rc1 + the (acpi/x86) backlight
detect refactor work. For merging into the acpi, drm-* and pdx86
subsystems.

----
Hans de Goede (31):
  ACPI: video: Add acpi_video_backlight_use_native() helper
  drm/i915: Don't register backlight when another backlight should be used 
(v2)
  drm/amdgpu: Don't register backlight when another backlight should be 
used (v3)
  drm/radeon: Don't register backlight when another backlight should be 
used (v3)
  drm/nouveau: Don't register backlight when another backlight should be 
used (v2)
  ACPI: video: Drop backlight_device_get_by_type() call from 
acpi_video_get_backlight_type()
  ACPI: video: Remove acpi_video_bus from list before tearing it down
  ACPI: video: Simplify acpi_video_unregister_backlight()
  ACPI: video: Make backlight class device registration a separate step (v2)
  ACPI: video: Remove code to unregister acpi_video backlight when a native 
backlight registers
  drm/i915: Call acpi_video_register_backlight() (v3)
  drm/nouveau: Register ACPI video backlight when nv_backlight registration 
fails (v2)
  drm/amdgpu: Register ACPI video backlight when skipping amdgpu backlight 
registration
  drm/radeon: Register ACPI video backlight when skipping radeon backlight 
registration
  platform/x86: nvidia-wmi-ec-backlight: Move fw interface definitions to a 
header (v2)
  ACPI: video: Refactor acpi_video_get_backlight_type() a bit
  ACPI: video: Add Nvidia WMI EC brightness control detection (v3)
  ACPI: video: Add Apple GMUX brightness control detection
  platform/x86: nvidia-wmi-ec-backlight: Use acpi_video_get_backlight_type()
  platform/x86: apple-gmux: Stop calling acpi/video.h functions
  platform/x86: toshiba_acpi: Stop using acpi_video_set_dmi_backlight_type()
  platform/x86: acer-wmi: Move backlight DMI quirks to acpi/video_detect.c
  platform/x86: asus-wmi: Drop DMI chassis-type check from backlight 
handling
  platform/x86: asus-wmi: Move acpi_backlight=vendor quirks to ACPI 
video_detect.c
  platform/x86: asus-wmi: Move acpi_backlight=native quirks to ACPI 
video_detect.c
  platform/x86: samsung-laptop: Move acpi_backlight=[vendor|native] quirks 
to ACPI video_detect.c
  ACPI: video: Remove acpi_video_set_dmi_backlight_type()
  ACPI: video: Drop "Samsung X360" acpi_backlight=native quirk
  ACPI: video: Drop NL5x?U, PF4NU1F and PF5?U?? acpi_backlight=native quirks
  ACPI: video: Fix indentation of video_detect_dmi_table[] entries
  drm/todo: Add entry about dealing with brightness control on devices with 
> 1 panel

 Documentation/gpu/todo.rst |  68 
 MAINTAINERS|   1 +
 drivers/acpi/Kconfig   |   1 +
 drivers/acpi/acpi_video.c  |  64 ++-
 drivers/acpi/video_detect.c| 428 -
 drivers/gpu/drm/Kconfig|  14 +
 drivers/gpu/drm/amd/amdgpu/atombios_encoders.c |  14 +-
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |   9 +
 drivers/gpu/drm/gma500/Kconfig |   2 +
 drivers/gpu/drm/i915/Kconfig   |   2 +
 drivers/gpu/drm/i915/display/intel_acpi.c  |  27 ++
 drivers/gpu/drm/i915/display/intel_acpi.h  |   3 +
 drivers/gpu/drm/i915/display/intel_backlight.c |   7 +
 drivers/gpu/drm/i915/display/intel_display.c   |   2 +-
 drivers/gpu/drm/nouveau/nouveau_acpi.c |  10 +
 drivers/gpu/drm/nouveau/nouveau_acpi.h |   4 +
 drivers/gpu/drm/nouveau/nouveau_backlight.c|  13 +
 drivers/gpu/drm/radeon/atombios_encoders.c |   7 +
 drivers/gpu/drm/radeon/radeon_encoders.c   |  11 +-
 driver

Re: [PATCH v5 17/31] ACPI: video: Add Nvidia WMI EC brightness control detection (v3)

2022-08-29 Thread Hans de Goede
Hi,

On 8/26/22 00:21, Daniel Dadap wrote:
> On 8/25/22 9:37 AM, Hans de Goede wrote:
>> On some new laptop designs a new Nvidia specific WMI interface is present
>> which gives info about panel brightness control and may allow controlling
>> the brightness through this interface when the embedded controller is used
>> for brightness control.
>>
>> When this WMI interface is present and indicates that the EC is used,
>> then this interface should be used for brightness control.
>>
>> Changes in v2:
>> - Use the new shared nvidia-wmi-ec-backlight.h header for the
>>    WMI firmware API definitions
>> - ACPI_VIDEO can now be enabled on non X86 too,
>>    adjust the Kconfig changes to match this.
>>
>> Changes in v3:
>> - Use WMI_BRIGHTNESS_GUID define
>>
>> Acked-by: Rafael J. Wysocki 
>> Signed-off-by: Hans de Goede 
>> ---
>>   drivers/acpi/Kconfig   |  1 +
>>   drivers/acpi/video_detect.c    | 37 ++
>>   drivers/gpu/drm/gma500/Kconfig |  2 ++
>>   drivers/gpu/drm/i915/Kconfig   |  2 ++
>>   include/acpi/video.h   |  1 +
>>   5 files changed, 43 insertions(+)
>>
>> diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
>> index 7802d8846a8d..44ad4b6bd234 100644
>> --- a/drivers/acpi/Kconfig
>> +++ b/drivers/acpi/Kconfig
>> @@ -212,6 +212,7 @@ config ACPI_VIDEO
>>   tristate "Video"
>>   depends on BACKLIGHT_CLASS_DEVICE
>>   depends on INPUT
>> +    depends on ACPI_WMI || !X86
>>   select THERMAL
>>   help
>>     This driver implements the ACPI Extensions For Display Adapters
>> diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
>> index cc9d0d91e268..4dc7fb865083 100644
>> --- a/drivers/acpi/video_detect.c
>> +++ b/drivers/acpi/video_detect.c
>> @@ -32,6 +32,7 @@
>>   #include 
>>   #include 
>>   #include 
>> +#include 
>>   #include 
>>   #include 
>>   #include 
>> @@ -75,6 +76,36 @@ find_video(acpi_handle handle, u32 lvl, void *context, 
>> void **rv)
>>   return AE_OK;
>>   }
>>   +/* This depends on ACPI_WMI which is X86 only */
>> +#ifdef CONFIG_X86
> 
> 
> This could probably also provide the { return false; } stub which you have 
> for non-x86 if the kernel is built without nvidia-wmi-ec-backight, e.g.:
> 
> #if defined(CONFIG_X86) && (defined(CONFIG_NVIDIA_WMI_EC_BACKLIGHT) || 
> defined(CONFIG_NVIDIA_WMI_EC_BACKLIGHT_MODULE))
> 
> Although I suppose that would break things if somebody has a kernel that 
> originally had NVIDIA_WMI_EC_BACKLIGHT=n in Kconfig, and then builds the 
> nvidia-wmi-ec-backlight driver out-of-tree later. I don't know whether that's 
> intended to be a supported use case, so I guess it is fine either way.

The video-detect code is about detecting what interface should be used.
So far it does this independently of the driver implementing that interface
actually being enabled or not.

If someone has a system which needs the nvidia-wmi-ec-backlight driver,
but it is disabled then they / their distro should enable that driver,
rather then trying to fallback on e.g. acpi_video.

Taking which drivers are enabled into account would both make
the code more complicated and would also explode the test matrix.

All of this is already somewhat fragile, so lets not make it
extra complicated :)

Regards,

Hans



> 
> 
>> +static bool nvidia_wmi_ec_supported(void)
>> +{
>> +    struct wmi_brightness_args args = {
>> +    .mode = WMI_BRIGHTNESS_MODE_GET,
>> +    .val = 0,
>> +    .ret = 0,
>> +    };
>> +    struct acpi_buffer buf = { (acpi_size)sizeof(args),  };
>> +    acpi_status status;
>> +
>> +    status = wmi_evaluate_method(WMI_BRIGHTNESS_GUID, 0,
>> + WMI_BRIGHTNESS_METHOD_SOURCE, , );
>> +    if (ACPI_FAILURE(status))
>> +    return false;
>> +
>> +    /*
>> + * If brightness is handled by the EC then nvidia-wmi-ec-backlight
>> + * should be used, else the GPU driver(s) should be used.
>> + */
>> +    return args.ret == WMI_BRIGHTNESS_SOURCE_EC;
>> +}
>> +#else
>> +static bool nvidia_wmi_ec_supported(void)
>> +{
>> +    return false;
>> +}
>> +#endif
>> +
>>   /* Force to use vendor driver when the ACPI device is known to be
>>    * buggy */
>>   static int video_detect_force_vendor(const struct dmi_system_id *d)
>> @@ -541,6 +572,7 @@ static const struct dmi_system_id 
>> video_detect_dmi_table[] = {
>>   static enum acpi_backligh

[PATCH v5 24/31] platform/x86: asus-wmi: Move acpi_backlight=vendor quirks to ACPI video_detect.c

2022-08-25 Thread Hans de Goede
Remove the asus-wmi quirk_entry.wmi_backlight_power quirk-flag, which
called acpi_video_set_dmi_backlight_type(acpi_backlight_vendor) and replace
it with acpi/video_detect.c video_detect_dmi_table[] entries using the
video_detect_force_vendor callback.

acpi_video_set_dmi_backlight_type() is troublesome because it may end up
getting called after other backlight drivers have already called
acpi_video_get_backlight_type() resulting in the other drivers
already being registered even though they should not.

Note no entries are dropped from the dmi_system_id table in asus-nb-wmi.c.
This is because the entries using the removed wmi_backlight_power flag
also use other model specific quirks from the asus-wmi quirk_entry struct.
So the quirk_asus_x55u struct and the entries pointing to it cannot be
dropped.

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/video_detect.c| 40 ++
 drivers/platform/x86/asus-nb-wmi.c |  7 --
 drivers/platform/x86/asus-wmi.c|  3 ---
 drivers/platform/x86/asus-wmi.h|  1 -
 drivers/platform/x86/eeepc-wmi.c   | 25 +--
 5 files changed, 41 insertions(+), 35 deletions(-)

diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 6a2523bc02ba..d893313fe1a0 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -174,6 +174,46 @@ static const struct dmi_system_id video_detect_dmi_table[] 
= {
DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"),
},
},
+   {
+.callback = video_detect_force_vendor,
+/* Asus X55U */
+.matches = {
+   DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+   DMI_MATCH(DMI_PRODUCT_NAME, "X55U"),
+   },
+   },
+   {
+.callback = video_detect_force_vendor,
+/* Asus X101CH */
+.matches = {
+   DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+   DMI_MATCH(DMI_PRODUCT_NAME, "X101CH"),
+   },
+   },
+   {
+.callback = video_detect_force_vendor,
+/* Asus X401U */
+.matches = {
+   DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+   DMI_MATCH(DMI_PRODUCT_NAME, "X401U"),
+   },
+   },
+   {
+.callback = video_detect_force_vendor,
+/* Asus X501U */
+.matches = {
+   DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+   DMI_MATCH(DMI_PRODUCT_NAME, "X501U"),
+   },
+   },
+   {
+.callback = video_detect_force_vendor,
+/* Asus 1015CX */
+.matches = {
+   DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+   DMI_MATCH(DMI_PRODUCT_NAME, "1015CX"),
+   },
+   },
{
.callback = video_detect_force_vendor,
/* GIGABYTE GB-BXBT-2807 */
diff --git a/drivers/platform/x86/asus-nb-wmi.c 
b/drivers/platform/x86/asus-nb-wmi.c
index 478dd300b9c9..810a94557a85 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -79,12 +79,10 @@ static struct quirk_entry quirk_asus_q500a = {
 
 /*
  * For those machines that need software to control bt/wifi status
- * and can't adjust brightness through ACPI interface
  * and have duplicate events(ACPI and WMI) for display toggle
  */
 static struct quirk_entry quirk_asus_x55u = {
.wapf = 4,
-   .wmi_backlight_power = true,
.wmi_backlight_set_devstate = true,
.no_display_toggle = true,
 };
@@ -147,11 +145,6 @@ static const struct dmi_system_id asus_quirks[] = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "U32U"),
},
-   /*
-* Note this machine has a Brazos APU, and most Brazos Asus
-* machines need quirk_asus_x55u / wmi_backlight_power but
-* here acpi-video seems to work fine for backlight control.
-*/
.driver_data = _asus_wapf4,
},
{
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index 301166a5697d..5cf9d9aff164 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -3634,9 +3634,6 @@ static int asus_wmi_add(struct platform_device *pdev)
if (asus->driver->quirks->wmi_force_als_set)
asus_wmi_set_als();
 
-   if (asus->driver->quirks->wmi_backlight_power)
-   acpi_video_set_dmi_backlight_type(acpi_backlight_vendor);
-
if (asus->driver->quirks->wmi_backlight_native)
acpi_video_set_dmi_backlight_type(acpi_backlight_native);
 
diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platfor

[PATCH v5 17/31] ACPI: video: Add Nvidia WMI EC brightness control detection (v3)

2022-08-25 Thread Hans de Goede
On some new laptop designs a new Nvidia specific WMI interface is present
which gives info about panel brightness control and may allow controlling
the brightness through this interface when the embedded controller is used
for brightness control.

When this WMI interface is present and indicates that the EC is used,
then this interface should be used for brightness control.

Changes in v2:
- Use the new shared nvidia-wmi-ec-backlight.h header for the
  WMI firmware API definitions
- ACPI_VIDEO can now be enabled on non X86 too,
  adjust the Kconfig changes to match this.

Changes in v3:
- Use WMI_BRIGHTNESS_GUID define

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/Kconfig   |  1 +
 drivers/acpi/video_detect.c| 37 ++
 drivers/gpu/drm/gma500/Kconfig |  2 ++
 drivers/gpu/drm/i915/Kconfig   |  2 ++
 include/acpi/video.h   |  1 +
 5 files changed, 43 insertions(+)

diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 7802d8846a8d..44ad4b6bd234 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -212,6 +212,7 @@ config ACPI_VIDEO
tristate "Video"
depends on BACKLIGHT_CLASS_DEVICE
depends on INPUT
+   depends on ACPI_WMI || !X86
select THERMAL
help
  This driver implements the ACPI Extensions For Display Adapters
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index cc9d0d91e268..4dc7fb865083 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -75,6 +76,36 @@ find_video(acpi_handle handle, u32 lvl, void *context, void 
**rv)
return AE_OK;
 }
 
+/* This depends on ACPI_WMI which is X86 only */
+#ifdef CONFIG_X86
+static bool nvidia_wmi_ec_supported(void)
+{
+   struct wmi_brightness_args args = {
+   .mode = WMI_BRIGHTNESS_MODE_GET,
+   .val = 0,
+   .ret = 0,
+   };
+   struct acpi_buffer buf = { (acpi_size)sizeof(args),  };
+   acpi_status status;
+
+   status = wmi_evaluate_method(WMI_BRIGHTNESS_GUID, 0,
+WMI_BRIGHTNESS_METHOD_SOURCE, , );
+   if (ACPI_FAILURE(status))
+   return false;
+
+   /*
+* If brightness is handled by the EC then nvidia-wmi-ec-backlight
+* should be used, else the GPU driver(s) should be used.
+*/
+   return args.ret == WMI_BRIGHTNESS_SOURCE_EC;
+}
+#else
+static bool nvidia_wmi_ec_supported(void)
+{
+   return false;
+}
+#endif
+
 /* Force to use vendor driver when the ACPI device is known to be
  * buggy */
 static int video_detect_force_vendor(const struct dmi_system_id *d)
@@ -541,6 +572,7 @@ static const struct dmi_system_id video_detect_dmi_table[] 
= {
 static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
 {
static DEFINE_MUTEX(init_mutex);
+   static bool nvidia_wmi_ec_present;
static bool native_available;
static bool init_done;
static long video_caps;
@@ -553,6 +585,7 @@ static enum acpi_backlight_type 
__acpi_video_get_backlight_type(bool native)
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, find_video, NULL,
_caps, NULL);
+   nvidia_wmi_ec_present = nvidia_wmi_ec_supported();
init_done = true;
}
if (native)
@@ -570,6 +603,10 @@ static enum acpi_backlight_type 
__acpi_video_get_backlight_type(bool native)
if (acpi_backlight_dmi != acpi_backlight_undef)
return acpi_backlight_dmi;
 
+   /* Special cases such as nvidia_wmi_ec and apple gmux. */
+   if (nvidia_wmi_ec_present)
+   return acpi_backlight_nvidia_wmi_ec;
+
/* On systems with ACPI video use either native or ACPI video. */
if (video_caps & ACPI_VIDEO_BACKLIGHT) {
/*
diff --git a/drivers/gpu/drm/gma500/Kconfig b/drivers/gpu/drm/gma500/Kconfig
index 0cff20265f97..807b989e3c77 100644
--- a/drivers/gpu/drm/gma500/Kconfig
+++ b/drivers/gpu/drm/gma500/Kconfig
@@ -7,6 +7,8 @@ config DRM_GMA500
select ACPI_VIDEO if ACPI
select BACKLIGHT_CLASS_DEVICE if ACPI
select INPUT if ACPI
+   select X86_PLATFORM_DEVICES if ACPI
+   select ACPI_WMI if ACPI
help
  Say yes for an experimental 2D KMS framebuffer driver for the
  Intel GMA500 (Poulsbo), Intel GMA600 (Moorestown/Oak Trail) and
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 7ae3b7d67fcf..3efce05d7b57 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -23,6 +23,8 @@ config DRM_I915
# but for select to work, need to select ACPI_VIDEO's dependencies, ick
select BACKLIGHT_CLASS_DEVICE if ACPI
  

[PATCH v5 31/31] drm/todo: Add entry about dealing with brightness control on devices with > 1 panel

2022-08-25 Thread Hans de Goede
Add an entry summarizing the discussion about dealing with brightness
control on devices with more then 1 internal panel.

The original discussion can be found here:
https://lore.kernel.org/dri-devel/20220517152331.16217-1-hdego...@redhat.com/

Reviewed-by: Lyude Paul 
Signed-off-by: Hans de Goede 
---
 Documentation/gpu/todo.rst | 68 ++
 1 file changed, 68 insertions(+)

diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 7634c27ac562..393d218e4a0c 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -679,6 +679,74 @@ Contact: Sam Ravnborg
 
 Level: Advanced
 
+Brightness handling on devices with multiple internal panels
+
+
+On x86/ACPI devices there can be multiple backlight firmware interfaces:
+(ACPI) video, vendor specific and others. As well as direct/native (PWM)
+register programming by the KMS driver.
+
+To deal with this backlight drivers used on x86/ACPI call
+acpi_video_get_backlight_type() which has heuristics (+quirks) to select
+which backlight interface to use; and backlight drivers which do not match
+the returned type will not register themselves, so that only one backlight
+device gets registered (in a single GPU setup, see below).
+
+At the moment this more or less assumes that there will only
+be 1 (internal) panel on a system.
+
+On systems with 2 panels this may be a problem, depending on
+what interface acpi_video_get_backlight_type() selects:
+
+1. native: in this case the KMS driver is expected to know which backlight
+   device belongs to which output so everything should just work.
+2. video: this does support controlling multiple backlights, but some work
+   will need to be done to get the output <-> backlight device mapping
+
+The above assumes both panels will require the same backlight interface type.
+Things will break on systems with multiple panels where the 2 panels need
+a different type of control. E.g. one panel needs ACPI video backlight control,
+where as the other is using native backlight control. Currently in this case
+only one of the 2 required backlight devices will get registered, based on
+the acpi_video_get_backlight_type() return value.
+
+If this (theoretical) case ever shows up, then supporting this will need some
+work. A possible solution here would be to pass a device and connector-name
+to acpi_video_get_backlight_type() so that it can deal with this.
+
+Note in a way we already have a case where userspace sees 2 panels,
+in dual GPU laptop setups with a mux. On those systems we may see
+either 2 native backlight devices; or 2 native backlight devices.
+
+Userspace already has code to deal with this by detecting if the related
+panel is active (iow which way the mux between the GPU and the panels
+points) and then uses that backlight device. Userspace here very much
+assumes a single panel though. It picks only 1 of the 2 backlight devices
+and then only uses that one.
+
+Note that all userspace code (that I know off) is currently hardcoded
+to assume a single panel.
+
+Before the recent changes to not register multiple (e.g. video + native)
+/sys/class/backlight devices for a single panel (on a single GPU laptop),
+userspace would see multiple backlight devices all controlling the same
+backlight.
+
+To deal with this userspace had to always picks one preferred device under
+/sys/class/backlight and will ignore the others. So to support brightness
+control on multiple panels userspace will need to be updated too.
+
+There are plans to allow brightness control through the KMS API by adding
+a "display brightness" property to drm_connector objects for panels. This
+solves a number of issues with the /sys/class/backlight API, including not
+being able to map a sysfs backlight device to a specific connector. Any
+userspace changes to add support for brightness control on devices with
+multiple panels really should build on top of this new KMS property.
+
+Contact: Hans de Goede
+
+Level: Advanced
+
 Outside DRM
 ===
 
-- 
2.37.2



[PATCH v5 27/31] ACPI: video: Remove acpi_video_set_dmi_backlight_type()

2022-08-25 Thread Hans de Goede
acpi_video_set_dmi_backlight_type() is troublesome because it may end
up getting called after other backlight drivers have already called
acpi_video_get_backlight_type() resulting in the other drivers
already being registered even though they should not.

In case of the acpi_video backlight, acpi_video_set_dmi_backlight_type()
actually calls acpi_video_unregister_backlight() since that is often
probed earlier, leading to userspace seeing the acpi_video0 class
device being briefly available, leading to races in userspace where
udev probe-rules try to access the device and it is already gone.

All callers have been fixed to no longer call it, so remove
acpi_video_set_dmi_backlight_type() now.

This means we now also no longer need acpi_video_unregister_backlight()
for the remove acpi_video backlight after it was wrongly registered hack,
so remove that too.

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/acpi_video.c   | 10 --
 drivers/acpi/video_detect.c | 16 
 include/acpi/video.h|  4 
 3 files changed, 30 deletions(-)

diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
index d1e41f30c004..a7c3d11e0dac 100644
--- a/drivers/acpi/acpi_video.c
+++ b/drivers/acpi/acpi_video.c
@@ -2296,16 +2296,6 @@ void acpi_video_register_backlight(void)
 }
 EXPORT_SYMBOL(acpi_video_register_backlight);
 
-void acpi_video_unregister_backlight(void)
-{
-   struct acpi_video_bus *video;
-
-   mutex_lock(_list_lock);
-   list_for_each_entry(video, _bus_head, entry)
-   acpi_video_bus_unregister_backlight(video);
-   mutex_unlock(_list_lock);
-}
-
 bool acpi_video_handles_brightness_key_presses(void)
 {
return may_report_brightness_keys &&
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 3861d4121172..67a0211c07b4 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -38,8 +38,6 @@
 #include 
 #include 
 
-void acpi_video_unregister_backlight(void);
-
 static enum acpi_backlight_type acpi_backlight_cmdline = acpi_backlight_undef;
 static enum acpi_backlight_type acpi_backlight_dmi = acpi_backlight_undef;
 
@@ -817,17 +815,3 @@ bool acpi_video_backlight_use_native(void)
return __acpi_video_get_backlight_type(true) == acpi_backlight_native;
 }
 EXPORT_SYMBOL(acpi_video_backlight_use_native);
-
-/*
- * Set the preferred backlight interface type based on DMI info.
- * This function allows DMI blacklists to be implemented by external
- * platform drivers instead of putting a big blacklist in video_detect.c
- */
-void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type)
-{
-   acpi_backlight_dmi = type;
-   /* Remove acpi-video backlight interface if it is no longer desired */
-   if (acpi_video_get_backlight_type() != acpi_backlight_video)
-   acpi_video_unregister_backlight();
-}
-EXPORT_SYMBOL(acpi_video_set_dmi_backlight_type);
diff --git a/include/acpi/video.h b/include/acpi/video.h
index dbd48cb8bd23..a275c35e5249 100644
--- a/include/acpi/video.h
+++ b/include/acpi/video.h
@@ -60,7 +60,6 @@ extern int acpi_video_get_edid(struct acpi_device *device, 
int type,
   int device_id, void **edid);
 extern enum acpi_backlight_type acpi_video_get_backlight_type(void);
 extern bool acpi_video_backlight_use_native(void);
-extern void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type);
 /*
  * Note: The value returned by acpi_video_handles_brightness_key_presses()
  * may change over time and should not be cached.
@@ -86,9 +85,6 @@ static inline bool acpi_video_backlight_use_native(void)
 {
return true;
 }
-static inline void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type 
type)
-{
-}
 static inline bool acpi_video_handles_brightness_key_presses(void)
 {
return false;
-- 
2.37.2



[PATCH v5 23/31] platform/x86: asus-wmi: Drop DMI chassis-type check from backlight handling

2022-08-25 Thread Hans de Goede
Remove this check from the asus-wmi backlight handling:

/* Some Asus desktop boards export an acpi-video backlight interface,
   stop this from showing up */
chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE);
if (chassis_type && !strcmp(chassis_type, "3"))
acpi_video_set_dmi_backlight_type(acpi_backlight_vendor);

This acpi_video_set_dmi_backlight_type(acpi_backlight_vendor) call must be
removed because other changes in this series change the native backlight
drivers to no longer unconditionally register their backlight. Instead
these drivers now do this check:

if (acpi_video_get_backlight_type(false) != acpi_backlight_native)
return 0; /* bail */

So leaving this in place can break things on laptops with a broken
DMI chassis-type, which would have GPU native brightness control before
the addition of the acpi_video_get_backlight_type() != native check.

Removing this should be ok now, since the ACPI video code has improved
heuristics for this itself now (which includes a chassis-type check).

Signed-off-by: Hans de Goede 
---
 drivers/platform/x86/asus-wmi.c | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index 89b604e04d7f..301166a5697d 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -3553,7 +3553,6 @@ static int asus_wmi_add(struct platform_device *pdev)
struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv);
struct asus_wmi *asus;
-   const char *chassis_type;
acpi_status status;
int err;
u32 result;
@@ -3635,12 +3634,6 @@ static int asus_wmi_add(struct platform_device *pdev)
if (asus->driver->quirks->wmi_force_als_set)
asus_wmi_set_als();
 
-   /* Some Asus desktop boards export an acpi-video backlight interface,
-  stop this from showing up */
-   chassis_type = dmi_get_system_info(DMI_CHASSIS_TYPE);
-   if (chassis_type && !strcmp(chassis_type, "3"))
-   acpi_video_set_dmi_backlight_type(acpi_backlight_vendor);
-
if (asus->driver->quirks->wmi_backlight_power)
acpi_video_set_dmi_backlight_type(acpi_backlight_vendor);
 
-- 
2.37.2



[PATCH v5 28/31] ACPI: video: Drop "Samsung X360" acpi_backlight=native quirk

2022-08-25 Thread Hans de Goede
acpi_backlight=native is the default for the "Samsung X360", but as
the comment explains the quirk was still necessary because even
briefly registering the acpi_video0 backlight; and then unregistering
it once the native driver showed up, was leading to issues.

After the "ACPI: video: Make backlight class device registration
a separate step" patch from earlier in this patch-series, we no
longer briefly register the acpi_video0 backlight on systems where
the native driver should be used.

So this is no longer an issue an the quirk is no longer needed.

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/video_detect.c | 15 ---
 1 file changed, 15 deletions(-)

diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 67a0211c07b4..af2833b57b8b 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -132,21 +132,6 @@ static int video_detect_force_none(const struct 
dmi_system_id *d)
 }
 
 static const struct dmi_system_id video_detect_dmi_table[] = {
-   /* On Samsung X360, the BIOS will set a flag (VDRV) if generic
-* ACPI backlight device is used. This flag will definitively break
-* the backlight interface (even the vendor interface) until next
-* reboot. It's why we should prevent video.ko from being used here
-* and we can't rely on a later call to acpi_video_unregister().
-*/
-   {
-.callback = video_detect_force_vendor,
-/* X360 */
-.matches = {
-   DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
-   DMI_MATCH(DMI_PRODUCT_NAME, "X360"),
-   DMI_MATCH(DMI_BOARD_NAME, "X360"),
-   },
-   },
{
 /* https://bugzilla.redhat.com/show_bug.cgi?id=1128309 */
 .callback = video_detect_force_vendor,
-- 
2.37.2



[PATCH v5 15/31] platform/x86: nvidia-wmi-ec-backlight: Move fw interface definitions to a header (v2)

2022-08-25 Thread Hans de Goede
Move the WMI interface definitions to a header, so that the definitions
can be shared with drivers/acpi/video_detect.c .

Changes in v2:
- Add missing Nvidia copyright header
- Move WMI_BRIGHTNESS_GUID to nvidia-wmi-ec-backlight.h as well

Suggested-by: Daniel Dadap 
Signed-off-by: Hans de Goede 
---
 MAINTAINERS   |  1 +
 .../platform/x86/nvidia-wmi-ec-backlight.c| 68 +
 .../x86/nvidia-wmi-ec-backlight.h | 76 +++
 3 files changed, 78 insertions(+), 67 deletions(-)
 create mode 100644 include/linux/platform_data/x86/nvidia-wmi-ec-backlight.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 9d7f64dc0efe..d6f6b96f51f7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14527,6 +14527,7 @@ M:  Daniel Dadap 
 L: platform-driver-...@vger.kernel.org
 S: Supported
 F: drivers/platform/x86/nvidia-wmi-ec-backlight.c
+F: include/linux/platform_data/x86/nvidia-wmi-ec-backlight.h
 
 NVM EXPRESS DRIVER
 M: Keith Busch 
diff --git a/drivers/platform/x86/nvidia-wmi-ec-backlight.c 
b/drivers/platform/x86/nvidia-wmi-ec-backlight.c
index 61e37194df70..be803e47eac0 100644
--- a/drivers/platform/x86/nvidia-wmi-ec-backlight.c
+++ b/drivers/platform/x86/nvidia-wmi-ec-backlight.c
@@ -7,74 +7,10 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
-/**
- * enum wmi_brightness_method - WMI method IDs
- * @WMI_BRIGHTNESS_METHOD_LEVEL:  Get/Set EC brightness level status
- * @WMI_BRIGHTNESS_METHOD_SOURCE: Get/Set EC Brightness Source
- */
-enum wmi_brightness_method {
-   WMI_BRIGHTNESS_METHOD_LEVEL = 1,
-   WMI_BRIGHTNESS_METHOD_SOURCE = 2,
-   WMI_BRIGHTNESS_METHOD_MAX
-};
-
-/**
- * enum wmi_brightness_mode - Operation mode for WMI-wrapped method
- * @WMI_BRIGHTNESS_MODE_GET:Get the current brightness 
level/source.
- * @WMI_BRIGHTNESS_MODE_SET:Set the brightness level.
- * @WMI_BRIGHTNESS_MODE_GET_MAX_LEVEL:  Get the maximum brightness level. This
- *  is only valid when the WMI method is
- *  %WMI_BRIGHTNESS_METHOD_LEVEL.
- */
-enum wmi_brightness_mode {
-   WMI_BRIGHTNESS_MODE_GET = 0,
-   WMI_BRIGHTNESS_MODE_SET = 1,
-   WMI_BRIGHTNESS_MODE_GET_MAX_LEVEL = 2,
-   WMI_BRIGHTNESS_MODE_MAX
-};
-
-/**
- * enum wmi_brightness_source - Backlight brightness control source selection
- * @WMI_BRIGHTNESS_SOURCE_GPU: Backlight brightness is controlled by the GPU.
- * @WMI_BRIGHTNESS_SOURCE_EC:  Backlight brightness is controlled by the
- * system's Embedded Controller (EC).
- * @WMI_BRIGHTNESS_SOURCE_AUX: Backlight brightness is controlled over the
- * DisplayPort AUX channel.
- */
-enum wmi_brightness_source {
-   WMI_BRIGHTNESS_SOURCE_GPU = 1,
-   WMI_BRIGHTNESS_SOURCE_EC = 2,
-   WMI_BRIGHTNESS_SOURCE_AUX = 3,
-   WMI_BRIGHTNESS_SOURCE_MAX
-};
-
-/**
- * struct wmi_brightness_args - arguments for the WMI-wrapped ACPI method
- * @mode:Pass in an  wmi_brightness_mode value to select between
- *   getting or setting a value.
- * @val: In parameter for value to set when using %WMI_BRIGHTNESS_MODE_SET
- *   mode. Not used in conjunction with %WMI_BRIGHTNESS_MODE_GET or
- *   %WMI_BRIGHTNESS_MODE_GET_MAX_LEVEL mode.
- * @ret: Out parameter returning retrieved value when operating in
- *   %WMI_BRIGHTNESS_MODE_GET or %WMI_BRIGHTNESS_MODE_GET_MAX_LEVEL
- *   mode. Not used in %WMI_BRIGHTNESS_MODE_SET mode.
- * @ignored: Padding; not used. The ACPI method expects a 24 byte params 
struct.
- *
- * This is the parameters structure for the WmiBrightnessNotify ACPI method as
- * wrapped by WMI. The value passed in to @val or returned by @ret will be a
- * brightness value when the WMI method ID is %WMI_BRIGHTNESS_METHOD_LEVEL, or
- * an  wmi_brightness_source value with %WMI_BRIGHTNESS_METHOD_SOURCE.
- */
-struct wmi_brightness_args {
-   u32 mode;
-   u32 val;
-   u32 ret;
-   u32 ignored[3];
-};
-
 /**
  * wmi_brightness_notify() - helper function for calling WMI-wrapped ACPI 
method
  * @w:Pointer to the struct wmi_device identified by %WMI_BRIGHTNESS_GUID
@@ -191,8 +127,6 @@ static int nvidia_wmi_ec_backlight_probe(struct wmi_device 
*wdev, const void *ct
return PTR_ERR_OR_ZERO(bdev);
 }
 
-#define WMI_BRIGHTNESS_GUID "603E9613-EF25-4338-A3D0-C46177516DB7"
-
 static const struct wmi_device_id nvidia_wmi_ec_backlight_id_table[] = {
{ .guid_string = WMI_BRIGHTNESS_GUID },
{ }
diff --git a/include/linux/platform_data/x86/nvidia-wmi-ec-backlight.h 
b/include/linux/platform_data/x86/nvidia-wmi-ec-backlight.h
new file mode 100644
index ..23d60130272c
--- /dev/null
+++ b/include/linux/platform_data/x86/nvidia-wmi-ec-backlight.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020, NVIDIA C

[PATCH v5 09/31] ACPI: video: Make backlight class device registration a separate step (v2)

2022-08-25 Thread Hans de Goede
On x86/ACPI boards the acpi_video driver will usually initialize before
the kms driver (except i915). This causes /sys/class/backlight/acpi_video0
to show up and then the kms driver registers its own native backlight
device after which the drivers/acpi/video_detect.c code unregisters
the acpi_video0 device (when acpi_video_get_backlight_type()==native).

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

To fix this make backlight class device registration a separate step
done by a new acpi_video_register_backlight() function. The intend is for
this to be called by the drm/kms driver *after* it is done setting up its
own native backlight device. So that acpi_video_get_backlight_type() knows
if a native backlight will be available or not at acpi_video backlight
registration time, avoiding the add + remove dance.

Note the new acpi_video_register_backlight() function is also called from
a delayed work to ensure that the acpi_video backlight devices does get
registered if necessary even if there is no drm/kms driver or when it is
disabled.

Changes in v2:
- Make register_backlight_delay a module parameter, mainly so that it can
  be disabled by Nvidia binary driver users

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/acpi_video.c | 50 ---
 include/acpi/video.h  |  2 ++
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
index 8545bf94866f..09dd86f86cf3 100644
--- a/drivers/acpi/acpi_video.c
+++ b/drivers/acpi/acpi_video.c
@@ -73,6 +73,16 @@ module_param(device_id_scheme, bool, 0444);
 static int only_lcd = -1;
 module_param(only_lcd, int, 0444);
 
+/*
+ * Display probing is known to take up to 5 seconds, so delay the fallback
+ * backlight registration by 5 seconds + 3 seconds for some extra margin.
+ */
+static int register_backlight_delay = 8;
+module_param(register_backlight_delay, int, 0444);
+MODULE_PARM_DESC(register_backlight_delay,
+   "Delay in seconds before doing fallback (non GPU driver triggered) "
+   "backlight registration, set to 0 to disable.");
+
 static bool may_report_brightness_keys;
 static int register_count;
 static DEFINE_MUTEX(register_count_mutex);
@@ -81,6 +91,9 @@ static LIST_HEAD(video_bus_head);
 static int acpi_video_bus_add(struct acpi_device *device);
 static int acpi_video_bus_remove(struct acpi_device *device);
 static void acpi_video_bus_notify(struct acpi_device *device, u32 event);
+static void acpi_video_bus_register_backlight_work(struct work_struct 
*ignored);
+static DECLARE_DELAYED_WORK(video_bus_register_backlight_work,
+   acpi_video_bus_register_backlight_work);
 void acpi_video_detect_exit(void);
 
 /*
@@ -1859,8 +1872,6 @@ static int acpi_video_bus_register_backlight(struct 
acpi_video_bus *video)
if (video->backlight_registered)
return 0;
 
-   acpi_video_run_bcl_for_osi(video);
-
if (acpi_video_get_backlight_type() != acpi_backlight_video)
return 0;
 
@@ -2086,7 +2097,11 @@ static int acpi_video_bus_add(struct acpi_device *device)
list_add_tail(>entry, _bus_head);
mutex_unlock(_list_lock);
 
-   acpi_video_bus_register_backlight(video);
+   /*
+* The userspace visible backlight_device gets registered separately
+* from acpi_video_register_backlight().
+*/
+   acpi_video_run_bcl_for_osi(video);
acpi_video_bus_add_notify_handler(video);
 
return 0;
@@ -2125,6 +2140,11 @@ static int acpi_video_bus_remove(struct acpi_device 
*device)
return 0;
 }
 
+static void acpi_video_bus_register_backlight_work(struct work_struct *ignored)
+{
+   acpi_video_register_backlight();
+}
+
 static int __init is_i740(struct pci_dev *dev)
 {
if (dev->device == 0x00D1)
@@ -2235,6 +2255,18 @@ int acpi_video_register(void)
 */
register_count = 1;
 
+   /*
+* acpi_video_bus_add() skips registering the userspace visible
+* backlight_device. The intend is for this to be registered by the
+* drm/kms driver calling acpi_video_register_backlight() *after* it is
+* done setting up its own native backlight device. The delayed work
+* ensures that acpi_video_register_backlight() always gets called
+* eventually, in case there is no drm/kms driver or it is disabled.
+*/
+   if (register_backlight_delay)
+   schedule_delayed_work(_bus_register_backlight_work,
+ register_backlight_delay * HZ);
+
 leave:
mutex_unlock(_count_mutex);
return ret;
@@ -2245,6 +2277,7 @@ void acpi_video_unregister(void)
 {
mutex_lock(_count_mutex

[PATCH v5 16/31] ACPI: video: Refactor acpi_video_get_backlight_type() a bit

2022-08-25 Thread Hans de Goede
Refactor acpi_video_get_backlight_type() so that the heuristics /
detection steps are stricly in order of descending precedence.

Also move the comments describing the steps to when the various steps are
actually done, to avoid the comments getting out of sync with the code.

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/video_detect.c | 39 ++---
 1 file changed, 23 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index fb49b8f4523a..cc9d0d91e268 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -537,16 +537,6 @@ static const struct dmi_system_id video_detect_dmi_table[] 
= {
 /*
  * Determine which type of backlight interface to use on this system,
  * First check cmdline, then dmi quirks, then do autodetect.
- *
- * The autodetect order is:
- * 1) Is the acpi-video backlight interface supported ->
- *  no, use a vendor interface
- * 2) Is this a win8 "ready" BIOS and do we have a native interface ->
- *  yes, use a native interface
- * 3) Else use the acpi-video interface
- *
- * Arguably the native on win8 check should be done first, but that would
- * be a behavior change, which may causes issues.
  */
 static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
 {
@@ -569,19 +559,36 @@ static enum acpi_backlight_type 
__acpi_video_get_backlight_type(bool native)
native_available = true;
mutex_unlock(_mutex);
 
+   /*
+* The below heuristics / detection steps are in order of descending
+* presedence. The commandline takes presedence over anything else.
+*/
if (acpi_backlight_cmdline != acpi_backlight_undef)
return acpi_backlight_cmdline;
 
+   /* DMI quirks override any autodetection. */
if (acpi_backlight_dmi != acpi_backlight_undef)
return acpi_backlight_dmi;
 
-   if (!(video_caps & ACPI_VIDEO_BACKLIGHT))
-   return acpi_backlight_vendor;
-
-   if (acpi_osi_is_win8() && native_available)
-   return acpi_backlight_native;
+   /* On systems with ACPI video use either native or ACPI video. */
+   if (video_caps & ACPI_VIDEO_BACKLIGHT) {
+   /*
+* Windows 8 and newer no longer use the ACPI video interface,
+* so it often does not work. If the ACPI tables are written
+* for win8 and native brightness ctl is available, use that.
+*
+* The native check deliberately is inside the if acpi-video
+* block on older devices without acpi-video support native
+* is usually not the best choice.
+*/
+   if (acpi_osi_is_win8() && native_available)
+   return acpi_backlight_native;
+   else
+   return acpi_backlight_video;
+   }
 
-   return acpi_backlight_video;
+   /* No ACPI video (old hw), use vendor specific fw methods. */
+   return acpi_backlight_vendor;
 }
 
 enum acpi_backlight_type acpi_video_get_backlight_type(void)
-- 
2.37.2



[PATCH v5 29/31] ACPI: video: Drop NL5x?U, PF4NU1F and PF5?U?? acpi_backlight=native quirks

2022-08-25 Thread Hans de Goede
acpi_backlight=native is the default for these, but as the comment
explains the quirk was still necessary because even briefly registering
the acpi_video0 backlight; and then unregistering it once the native
driver showed up, was leading to issues.

After the "ACPI: video: Make backlight class device registration
a separate step" patch from earlier in this patch-series, we no
longer briefly register the acpi_video0 backlight on systems where
the native driver should be used.

So this is no longer an issue an the quirks are no longer needed.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=215683
Tested-by: Werner Sembach 
Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/video_detect.c | 92 +
 1 file changed, 1 insertion(+), 91 deletions(-)

diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index af2833b57b8b..789d5913c178 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -609,97 +609,7 @@ static const struct dmi_system_id video_detect_dmi_table[] 
= {
DMI_MATCH(DMI_BOARD_NAME, "N250P"),
},
},
-   /*
-* Clevo NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2 have both a
-* working native and video interface. However the default detection
-* mechanism first registers the video interface before unregistering
-* it again and switching to the native interface during boot. This
-* results in a dangling SBIOS request for backlight change for some
-* reason, causing the backlight to switch to ~2% once per boot on the
-* first power cord connect or disconnect event. Setting the native
-* interface explicitly circumvents this buggy behaviour, by avoiding
-* the unregistering process.
-*/
-   {
-   .callback = video_detect_force_native,
-   .ident = "Clevo NL5xRU",
-   .matches = {
-   DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"),
-   },
-   },
-   {
-   .callback = video_detect_force_native,
-   .ident = "Clevo NL5xRU",
-   .matches = {
-   DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
-   DMI_MATCH(DMI_BOARD_NAME, "AURA1501"),
-   },
-   },
-   {
-   .callback = video_detect_force_native,
-   .ident = "Clevo NL5xRU",
-   .matches = {
-   DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
-   DMI_MATCH(DMI_BOARD_NAME, "EDUBOOK1502"),
-   },
-   },
-   {
-   .callback = video_detect_force_native,
-   .ident = "Clevo NL5xNU",
-   .matches = {
-   DMI_MATCH(DMI_BOARD_NAME, "NL5xNU"),
-   },
-   },
-   /*
-* The TongFang PF5PU1G, PF4NU1F, PF5NU1G, and PF5LUXG/TUXEDO BA15 
Gen10,
-* Pulse 14/15 Gen1, and Pulse 15 Gen2 have the same problem as the 
Clevo
-* NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2. See the description
-* above.
-*/
-   {
-   .callback = video_detect_force_native,
-   .ident = "TongFang PF5PU1G",
-   .matches = {
-   DMI_MATCH(DMI_BOARD_NAME, "PF5PU1G"),
-   },
-   },
-   {
-   .callback = video_detect_force_native,
-   .ident = "TongFang PF4NU1F",
-   .matches = {
-   DMI_MATCH(DMI_BOARD_NAME, "PF4NU1F"),
-   },
-   },
-   {
-   .callback = video_detect_force_native,
-   .ident = "TongFang PF4NU1F",
-   .matches = {
-   DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
-   DMI_MATCH(DMI_BOARD_NAME, "PULSE1401"),
-   },
-   },
-   {
-   .callback = video_detect_force_native,
-   .ident = "TongFang PF5NU1G",
-   .matches = {
-   DMI_MATCH(DMI_BOARD_NAME, "PF5NU1G"),
-   },
-   },
-   {
-   .callback = video_detect_force_native,
-   .ident = "TongFang PF5NU1G",
-   .matches = {
-   DMI_MATCH(DMI_SYS_VENDOR, "TUXEDO"),
-   DMI_MATCH(DMI_BOARD_NAME, "PULSE1501"),
-   },
-   },
-   {
-   .callback = video_detect_force_native,
-   .ident = "TongFang PF5LUXG",
-   .matches = {
-   DMI_MATCH(DMI_BOARD_NAME, "PF5LUXG"),
-   },
-   },
+
/*
 * Desktops which falsely report a backlight and which our heuristics
 * for this do not catch.
-- 
2.37.2



[PATCH v5 26/31] platform/x86: samsung-laptop: Move acpi_backlight=[vendor|native] quirks to ACPI video_detect.c

2022-08-25 Thread Hans de Goede
acpi_video_set_dmi_backlight_type() is troublesome because it may end up
getting called after other backlight drivers have already called
acpi_video_get_backlight_type() resulting in the other drivers
already being registered even though they should not.

Move all the acpi_backlight=[vendor|native] quirks from samsung-laptop to
drivers/acpi/video_detect.c .

Note the X360 -> acpi_backlight=native quirk is not moved because that
already was present in drivers/acpi/video_detect.c .

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/video_detect.c   | 54 +
 drivers/platform/x86/samsung-laptop.c | 87 ---
 2 files changed, 54 insertions(+), 87 deletions(-)

diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index a09089e7fada..3861d4121172 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -222,6 +222,33 @@ static const struct dmi_system_id video_detect_dmi_table[] 
= {
DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"),
},
},
+   {
+.callback = video_detect_force_vendor,
+/* Samsung N150/N210/N220 */
+.matches = {
+   DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+   DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"),
+   DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"),
+   },
+   },
+   {
+.callback = video_detect_force_vendor,
+/* Samsung NF110/NF210/NF310 */
+.matches = {
+   DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+   DMI_MATCH(DMI_PRODUCT_NAME, "NF110/NF210/NF310"),
+   DMI_MATCH(DMI_BOARD_NAME, "NF110/NF210/NF310"),
+   },
+   },
+   {
+.callback = video_detect_force_vendor,
+/* Samsung NC210 */
+.matches = {
+   DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+   DMI_MATCH(DMI_PRODUCT_NAME, "NC210/NC110"),
+   DMI_MATCH(DMI_BOARD_NAME, "NC210/NC110"),
+   },
+   },
{
.callback = video_detect_force_vendor,
/* Sony VPCEH3U1E */
@@ -572,6 +599,33 @@ static const struct dmi_system_id video_detect_dmi_table[] 
= {
DMI_MATCH(DMI_PRODUCT_NAME, "UX303UB"),
},
},
+   {
+.callback = video_detect_force_native,
+/* Samsung N150P */
+.matches = {
+   DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+   DMI_MATCH(DMI_PRODUCT_NAME, "N150P"),
+   DMI_MATCH(DMI_BOARD_NAME, "N150P"),
+   },
+   },
+   {
+.callback = video_detect_force_native,
+/* Samsung N145P/N250P/N260P */
+.matches = {
+   DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+   DMI_MATCH(DMI_PRODUCT_NAME, "N145P/N250P/N260P"),
+   DMI_MATCH(DMI_BOARD_NAME, "N145P/N250P/N260P"),
+   },
+   },
+   {
+.callback = video_detect_force_native,
+/* Samsung N250P */
+.matches = {
+   DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+   DMI_MATCH(DMI_PRODUCT_NAME, "N250P"),
+   DMI_MATCH(DMI_BOARD_NAME, "N250P"),
+   },
+   },
/*
 * Clevo NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2 have both a
 * working native and video interface. However the default detection
diff --git a/drivers/platform/x86/samsung-laptop.c 
b/drivers/platform/x86/samsung-laptop.c
index c187dcdf82f0..cc30cf08f32d 100644
--- a/drivers/platform/x86/samsung-laptop.c
+++ b/drivers/platform/x86/samsung-laptop.c
@@ -356,23 +356,13 @@ struct samsung_laptop {
 };
 
 struct samsung_quirks {
-   bool broken_acpi_video;
bool four_kbd_backlight_levels;
bool enable_kbd_backlight;
-   bool use_native_backlight;
bool lid_handling;
 };
 
 static struct samsung_quirks samsung_unknown = {};
 
-static struct samsung_quirks samsung_broken_acpi_video = {
-   .broken_acpi_video = true,
-};
-
-static struct samsung_quirks samsung_use_native_backlight = {
-   .use_native_backlight = true,
-};
-
 static struct samsung_quirks samsung_np740u3e = {
.four_kbd_backlight_levels = true,
.enable_kbd_backlight = true,
@@ -1540,76 +1530,6 @@ static const struct dmi_system_id samsung_dmi_table[] 
__initconst = {
},
},
/* Specific DMI ids for laptop with quirks */
-   {
-.callback = samsung_dmi_matched,
-.ident = "N150P",
-.matches = {
-   DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., L

[PATCH v5 12/31] drm/nouveau: Register ACPI video backlight when nv_backlight registration fails (v2)

2022-08-25 Thread Hans de Goede
Typically the acpi_video driver will initialize before nouveau, which
used to cause /sys/class/backlight/acpi_video0 to get registered and then
nouveau would register its own nv_backlight device later. After which
the drivers/acpi/video_detect.c code unregistered the acpi_video0 device
to avoid there being 2 backlight devices.

This means that userspace used to briefly see 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

To fix this the ACPI video code has been modified to make backlight class
device registration a separate step, relying on the drm/kms driver to
ask for the acpi_video backlight registration after it is done setting up
its native backlight device.

Add a call to the new acpi_video_register_backlight() when native backlight
device registration has failed / was skipped to ensure that there is a
backlight device available before the drm_device gets registered with
userspace.

Changes in v2:
- Add nouveau_acpi_video_register_backlight() wrapper to avoid unresolved
  symbol errors on non X86

Reviewed-by: Lyude Paul 
Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/nouveau/nouveau_acpi.c  | 5 +
 drivers/gpu/drm/nouveau/nouveau_acpi.h  | 2 ++
 drivers/gpu/drm/nouveau/nouveau_backlight.c | 7 +++
 3 files changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c 
b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index 1592c9cd7750..8cf096f841a9 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -391,3 +391,8 @@ bool nouveau_acpi_video_backlight_use_native(void)
 {
return acpi_video_backlight_use_native();
 }
+
+void nouveau_acpi_video_register_backlight(void)
+{
+   acpi_video_register_backlight();
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.h 
b/drivers/gpu/drm/nouveau/nouveau_acpi.h
index 3c666c30dfca..e39dd8b94b8b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.h
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.h
@@ -12,6 +12,7 @@ void nouveau_unregister_dsm_handler(void);
 void nouveau_switcheroo_optimus_dsm(void);
 void *nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
 bool nouveau_acpi_video_backlight_use_native(void);
+void nouveau_acpi_video_register_backlight(void);
 #else
 static inline bool nouveau_is_optimus(void) { return false; };
 static inline bool nouveau_is_v1_dsm(void) { return false; };
@@ -20,6 +21,7 @@ static inline void nouveau_unregister_dsm_handler(void) {}
 static inline void nouveau_switcheroo_optimus_dsm(void) {}
 static inline void *nouveau_acpi_edid(struct drm_device *dev, struct 
drm_connector *connector) { return NULL; }
 static inline bool nouveau_acpi_video_backlight_use_native(void) { return 
true; }
+static inline void nouveau_acpi_video_register_backlight(void) {}
 #endif
 
 #endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c 
b/drivers/gpu/drm/nouveau/nouveau_backlight.c
index d2b8f8c13db4..a614582779ca 100644
--- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
+++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
@@ -436,6 +436,13 @@ nouveau_backlight_init(struct drm_connector *connector)
 
 fail_alloc:
kfree(bl);
+   /*
+* If we get here we have an internal panel, but no nv_backlight,
+* try registering an ACPI video backlight device instead.
+*/
+   if (ret == 0)
+   nouveau_acpi_video_register_backlight();
+
return ret;
 }
 
-- 
2.37.2



[PATCH v5 21/31] platform/x86: toshiba_acpi: Stop using acpi_video_set_dmi_backlight_type()

2022-08-25 Thread Hans de Goede
acpi_video_set_dmi_backlight_type() is troublesome because it may end up
getting called after other backlight drivers have already called
acpi_video_get_backlight_type() resulting in the other drivers
already being registered even though they should not.

In case of the acpi_video backlight, acpi_video_set_dmi_backlight_type()
actually calls acpi_video_unregister_backlight() since that is often
probed earlier, leading to userspace seeing the acpi_video0 class
device being briefly available, leading to races in userspace where
udev probe-rules try to access the device and it is already gone.

In case of toshiba_acpi there are no DMI quirks to move to
acpi/video_detect.c, but it also (ab)uses it for transflective
displays. Adding transflective display support to video_detect.c would
be quite involved. But luckily there are only 2 known models with
a transflective display, so we can just add DMI quirks for those.

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/video_detect.c | 19 +++
 drivers/platform/x86/toshiba_acpi.c | 16 
 2 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index be2fc43418af..74e2087c8ff0 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -190,6 +190,25 @@ static const struct dmi_system_id video_detect_dmi_table[] 
= {
},
},
 
+   /*
+* Toshiba models with Transflective display, these need to use
+* the toshiba_acpi vendor driver for proper Transflective handling.
+*/
+   {
+.callback = video_detect_force_vendor,
+.matches = {
+   DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+   DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R500"),
+   },
+   },
+   {
+.callback = video_detect_force_vendor,
+.matches = {
+   DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+   DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE R600"),
+   },
+   },
+
/*
 * These models have a working acpi_video backlight control, and using
 * native backlight causes a regression where backlight does not work
diff --git a/drivers/platform/x86/toshiba_acpi.c 
b/drivers/platform/x86/toshiba_acpi.c
index 0fc9e8b8827b..030dc37d50b8 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -271,14 +271,6 @@ static const struct key_entry toshiba_acpi_alt_keymap[] = {
{ KE_END, 0 },
 };
 
-/*
- * List of models which have a broken acpi-video backlight interface and thus
- * need to use the toshiba (vendor) interface instead.
- */
-static const struct dmi_system_id toshiba_vendor_backlight_dmi[] = {
-   {}
-};
-
 /*
  * Utility
  */
@@ -2881,14 +2873,6 @@ static int toshiba_acpi_setup_backlight(struct 
toshiba_acpi_dev *dev)
return 0;
}
 
-   /*
-* Tell acpi-video-detect code to prefer vendor backlight on all
-* systems with transflective backlight and on dmi matched systems.
-*/
-   if (dev->tr_backlight_supported ||
-   dmi_check_system(toshiba_vendor_backlight_dmi))
-   acpi_video_set_dmi_backlight_type(acpi_backlight_vendor);
-
if (acpi_video_get_backlight_type() != acpi_backlight_vendor)
return 0;
 
-- 
2.37.2



[PATCH v5 08/31] ACPI: video: Simplify acpi_video_unregister_backlight()

2022-08-25 Thread Hans de Goede
When acpi_video_register() has not run yet the video_bus_head will be
empty, so there is no need to check the register_count flag first.

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/acpi_video.c | 12 
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
index cde8ffa9f0b8..8545bf94866f 100644
--- a/drivers/acpi/acpi_video.c
+++ b/drivers/acpi/acpi_video.c
@@ -2257,14 +2257,10 @@ void acpi_video_unregister_backlight(void)
 {
struct acpi_video_bus *video;
 
-   mutex_lock(_count_mutex);
-   if (register_count) {
-   mutex_lock(_list_lock);
-   list_for_each_entry(video, _bus_head, entry)
-   acpi_video_bus_unregister_backlight(video);
-   mutex_unlock(_list_lock);
-   }
-   mutex_unlock(_count_mutex);
+   mutex_lock(_list_lock);
+   list_for_each_entry(video, _bus_head, entry)
+   acpi_video_bus_unregister_backlight(video);
+   mutex_unlock(_list_lock);
 }
 
 bool acpi_video_handles_brightness_key_presses(void)
-- 
2.37.2



[PATCH v5 11/31] drm/i915: Call acpi_video_register_backlight() (v3)

2022-08-25 Thread Hans de Goede
On machins without an i915 opregion the acpi_video driver immediately
probes the ACPI video bus and used to also immediately register
acpi_video# backlight devices when supported.

Once the drm/kms driver then loaded later and possibly registered
a native backlight device then the drivers/acpi/video_detect.c code
unregistered the acpi_video0 device to avoid there being 2 backlight
devices (when acpi_video_get_backlight_type()==native).

This means that userspace used to briefly see 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

To fix this the ACPI video code has been modified to make backlight class
device registration a separate step, relying on the drm/kms driver to
ask for the acpi_video backlight registration after it is done setting up
its native backlight device.

Add a call to the new acpi_video_register_backlight() after the i915 calls
acpi_video_register() (after setting up the i915 opregion) so that the
acpi_video backlight devices get registered on systems where the i915
native backlight device is not registered.

Changes in v2:
-Only call acpi_video_register_backlight() when a panel is detected

Changes in v3:
-Add a new intel_acpi_video_register() helper which checks if a panel
 is present and then calls acpi_video_register_backlight()

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/display/intel_acpi.c| 27 
 drivers/gpu/drm/i915/display/intel_acpi.h|  3 +++
 drivers/gpu/drm/i915/display/intel_display.c |  2 +-
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c 
b/drivers/gpu/drm/i915/display/intel_acpi.c
index e78430001f07..9df78e7caa2b 100644
--- a/drivers/gpu/drm/i915/display/intel_acpi.c
+++ b/drivers/gpu/drm/i915/display/intel_acpi.c
@@ -7,6 +7,7 @@
 
 #include 
 #include 
+#include 
 
 #include "i915_drv.h"
 #include "intel_acpi.h"
@@ -331,3 +332,29 @@ void intel_acpi_assign_connector_fwnodes(struct 
drm_i915_private *i915)
 */
fwnode_handle_put(fwnode);
 }
+
+void intel_acpi_video_register(struct drm_i915_private *i915)
+{
+   struct drm_connector_list_iter conn_iter;
+   struct drm_connector *connector;
+
+   acpi_video_register();
+
+   /*
+* If i915 is driving an internal panel without registering its native
+* backlight handler try to register the acpi_video backlight.
+* For panels not driven by i915 another GPU driver may still register
+* a native backlight later and acpi_video_register_backlight() should
+* only be called after any native backlights have been registered.
+*/
+   drm_connector_list_iter_begin(>drm, _iter);
+   drm_for_each_connector_iter(connector, _iter) {
+   struct intel_panel *panel = 
_intel_connector(connector)->panel;
+
+   if (panel->backlight.funcs && !panel->backlight.device) {
+   acpi_video_register_backlight();
+   break;
+   }
+   }
+   drm_connector_list_iter_end(_iter);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_acpi.h 
b/drivers/gpu/drm/i915/display/intel_acpi.h
index 4a760a2baed9..6a0007452f95 100644
--- a/drivers/gpu/drm/i915/display/intel_acpi.h
+++ b/drivers/gpu/drm/i915/display/intel_acpi.h
@@ -14,6 +14,7 @@ void intel_unregister_dsm_handler(void);
 void intel_dsm_get_bios_data_funcs_supported(struct drm_i915_private *i915);
 void intel_acpi_device_id_update(struct drm_i915_private *i915);
 void intel_acpi_assign_connector_fwnodes(struct drm_i915_private *i915);
+void intel_acpi_video_register(struct drm_i915_private *i915);
 #else
 static inline void intel_register_dsm_handler(void) { return; }
 static inline void intel_unregister_dsm_handler(void) { return; }
@@ -23,6 +24,8 @@ static inline
 void intel_acpi_device_id_update(struct drm_i915_private *i915) { return; }
 static inline
 void intel_acpi_assign_connector_fwnodes(struct drm_i915_private *i915) { 
return; }
+static inline
+void intel_acpi_video_register(struct drm_i915_private *i915) { return; }
 #endif /* CONFIG_ACPI */
 
 #endif /* __INTEL_ACPI_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_display.c 
b/drivers/gpu/drm/i915/display/intel_display.c
index 6103b02c081f..129a13375101 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -9087,7 +9087,7 @@ void intel_display_driver_register(struct 
drm_i915_private *i915)
 
/* Must be done after probing outputs */
intel_opregion_register(i915);
-   acpi_video_register();
+   intel_acpi_video_register(i915);
 
intel_audio_init(i915);
 
-- 
2.37.2



[PATCH v5 22/31] platform/x86: acer-wmi: Move backlight DMI quirks to acpi/video_detect.c

2022-08-25 Thread Hans de Goede
Move the backlight DMI quirks to acpi/video_detect.c, so that
the driver no longer needs to call acpi_video_set_dmi_backlight_type().

acpi_video_set_dmi_backlight_type() is troublesome because it may end up
getting called after other backlight drivers have already called
acpi_video_get_backlight_type() resulting in the other drivers
already being registered even though they should not.

Note that even though the DMI quirk table name was video_vendor_dmi_table,
5/6 quirks were actually quirks to use the GPU native backlight.

These 5 quirks also had a callback in their dmi_system_id entry which
disabled the acer-wmi vendor driver; and any DMI match resulted in:

acpi_video_set_dmi_backlight_type(acpi_backlight_vendor);

which disabled the acpi_video driver, so only the native driver was left.
The new entries for these 5/6 devices correctly marks these as needing
the native backlight driver.

Also note that other changes in this series change the native backlight
drivers to no longer unconditionally register their backlight. Instead
these drivers now do this check:

if (acpi_video_get_backlight_type(false) != acpi_backlight_native)
return 0; /* bail */

which without this patch would have broken these 5/6 "special" quirks.

Since I had to look at all the commits adding the quirks anyways, to make
sure that I understood the code correctly, I've also added links to
the various original bugzillas for these quirks to the new entries.

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/video_detect.c | 53 ++
 drivers/platform/x86/acer-wmi.c | 66 -
 2 files changed, 53 insertions(+), 66 deletions(-)

diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 74e2087c8ff0..6a2523bc02ba 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -149,6 +149,15 @@ static const struct dmi_system_id video_detect_dmi_table[] 
= {
DMI_MATCH(DMI_BOARD_NAME, "X360"),
},
},
+   {
+/* https://bugzilla.redhat.com/show_bug.cgi?id=1128309 */
+.callback = video_detect_force_vendor,
+/* Acer KAV80 */
+.matches = {
+   DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+   DMI_MATCH(DMI_PRODUCT_NAME, "KAV80"),
+   },
+   },
{
.callback = video_detect_force_vendor,
/* Asus UL30VT */
@@ -437,6 +446,41 @@ static const struct dmi_system_id video_detect_dmi_table[] 
= {
DMI_MATCH(DMI_BOARD_NAME, "JV50"),
},
},
+   {
+/* https://bugzilla.redhat.com/show_bug.cgi?id=1012674 */
+.callback = video_detect_force_native,
+/* Acer Aspire 5741 */
+.matches = {
+   DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
+   DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5741"),
+   },
+   },
+   {
+/* https://bugzilla.kernel.org/show_bug.cgi?id=42993 */
+.callback = video_detect_force_native,
+/* Acer Aspire 5750 */
+.matches = {
+   DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
+   DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5750"),
+   },
+   },
+   {
+/* https://bugzilla.kernel.org/show_bug.cgi?id=42833 */
+.callback = video_detect_force_native,
+/* Acer Extensa 5235 */
+.matches = {
+   DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
+   DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5235"),
+   },
+   },
+   {
+.callback = video_detect_force_native,
+/* Acer TravelMate 4750 */
+.matches = {
+   DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
+   DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4750"),
+   },
+   },
{
 /* https://bugzilla.kernel.org/show_bug.cgi?id=207835 */
 .callback = video_detect_force_native,
@@ -447,6 +491,15 @@ static const struct dmi_system_id video_detect_dmi_table[] 
= {
DMI_MATCH(DMI_BOARD_NAME, "BA51_MV"),
},
},
+   {
+/* https://bugzilla.kernel.org/show_bug.cgi?id=36322 */
+.callback = video_detect_force_native,
+/* Acer TravelMate 5760 */
+.matches = {
+   DMI_MATCH(DMI_BOARD_VENDOR, "Acer"),
+   DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5760"),
+   },
+   },
{
.callback = video_detect_force_native,
/* ASUSTeK COMPUTER INC. GA401 */
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index e0230ea0cb7e..b933a5165edb 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -643,69 +643,6 @@ static const struct dmi_system

[PATCH v5 20/31] platform/x86: apple-gmux: Stop calling acpi/video.h functions

2022-08-25 Thread Hans de Goede
Now that acpi_video_get_backlight_type() has apple-gmux detection (using
apple_gmux_present()), it is no longer necessary for the apple-gmux code
to manually remove possibly conflicting drivers.

So remove the handling for this from the apple-gmux driver.

Signed-off-by: Hans de Goede 
---
 drivers/platform/x86/apple-gmux.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/platform/x86/apple-gmux.c 
b/drivers/platform/x86/apple-gmux.c
index ffe98a18440b..ca33df7ea550 100644
--- a/drivers/platform/x86/apple-gmux.c
+++ b/drivers/platform/x86/apple-gmux.c
@@ -21,7 +21,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 
 /**
@@ -694,7 +693,6 @@ static int gmux_probe(struct pnp_dev *pnp, const struct 
pnp_device_id *id)
 * backlight control and supports more levels than other options.
 * Disable the other backlight choices.
 */
-   acpi_video_set_dmi_backlight_type(acpi_backlight_vendor);
apple_bl_unregister();
 
gmux_data->power_state = VGA_SWITCHEROO_ON;
@@ -804,7 +802,6 @@ static void gmux_remove(struct pnp_dev *pnp)
apple_gmux_data = NULL;
kfree(gmux_data);
 
-   acpi_video_register();
apple_bl_register();
 }
 
-- 
2.37.2



[PATCH v5 02/31] drm/i915: Don't register backlight when another backlight should be used (v2)

2022-08-25 Thread Hans de Goede
Before this commit when we want userspace to use the acpi_video backlight
device we register both the GPU's native backlight device and acpi_video's
firmware acpi_video# backlight device. This relies on userspace preferring
firmware type backlight devices over native ones.

Registering 2 backlight devices for a single display really is
undesirable, don't register the GPU's native backlight device when
another backlight device should be used.

Changes in v2:
- Use drm_info(drm_dev,  ...) for log messages

Reviewed-by: Jani Nikula 
Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/i915/display/intel_backlight.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c 
b/drivers/gpu/drm/i915/display/intel_backlight.c
index 681ebcda97ad..03c7966f68d6 100644
--- a/drivers/gpu/drm/i915/display/intel_backlight.c
+++ b/drivers/gpu/drm/i915/display/intel_backlight.c
@@ -8,6 +8,8 @@
 #include 
 #include 
 
+#include 
+
 #include "intel_backlight.h"
 #include "intel_backlight_regs.h"
 #include "intel_connector.h"
@@ -952,6 +954,11 @@ int intel_backlight_device_register(struct intel_connector 
*connector)
 
WARN_ON(panel->backlight.max == 0);
 
+   if (!acpi_video_backlight_use_native()) {
+   drm_info(>drm, "Skipping intel_backlight registration\n");
+   return 0;
+   }
+
memset(, 0, sizeof(props));
props.type = BACKLIGHT_RAW;
 
-- 
2.37.2



[PATCH v5 25/31] platform/x86: asus-wmi: Move acpi_backlight=native quirks to ACPI video_detect.c

2022-08-25 Thread Hans de Goede
Remove the asus-wmi quirk_entry.wmi_backlight_native quirk-flag, which
called acpi_video_set_dmi_backlight_type(acpi_backlight_native) and replace
it with acpi/video_detect.c video_detect_dmi_table[] entries using the
video_detect_force_native callback.

acpi_video_set_dmi_backlight_type() is troublesome because it may end up
getting called after other backlight drivers have already called
acpi_video_get_backlight_type() resulting in the other drivers
already being registered even though they should not.

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/video_detect.c|  8 
 drivers/platform/x86/asus-nb-wmi.c | 14 --
 drivers/platform/x86/asus-wmi.c|  3 ---
 drivers/platform/x86/asus-wmi.h|  1 -
 4 files changed, 8 insertions(+), 18 deletions(-)

diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index d893313fe1a0..a09089e7fada 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -564,6 +564,14 @@ static const struct dmi_system_id video_detect_dmi_table[] 
= {
DMI_MATCH(DMI_PRODUCT_NAME, "GA503"),
},
},
+   {
+.callback = video_detect_force_native,
+/* Asus UX303UB */
+.matches = {
+   DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+   DMI_MATCH(DMI_PRODUCT_NAME, "UX303UB"),
+   },
+   },
/*
 * Clevo NL5xRU and NL5xNU/TUXEDO Aura 15 Gen1 and Gen2 have both a
 * working native and video interface. However the default detection
diff --git a/drivers/platform/x86/asus-nb-wmi.c 
b/drivers/platform/x86/asus-nb-wmi.c
index 810a94557a85..bbfed85051ee 100644
--- a/drivers/platform/x86/asus-nb-wmi.c
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -97,11 +97,6 @@ static struct quirk_entry quirk_asus_x200ca = {
.wmi_backlight_set_devstate = true,
 };
 
-static struct quirk_entry quirk_asus_ux303ub = {
-   .wmi_backlight_native = true,
-   .wmi_backlight_set_devstate = true,
-};
-
 static struct quirk_entry quirk_asus_x550lb = {
.wmi_backlight_set_devstate = true,
.xusb2pr = 0x01D9,
@@ -372,15 +367,6 @@ static const struct dmi_system_id asus_quirks[] = {
},
.driver_data = _asus_x200ca,
},
-   {
-   .callback = dmi_matched,
-   .ident = "ASUSTeK COMPUTER INC. UX303UB",
-   .matches = {
-   DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
-   DMI_MATCH(DMI_PRODUCT_NAME, "UX303UB"),
-   },
-   .driver_data = _asus_ux303ub,
-   },
{
.callback = dmi_matched,
.ident = "ASUSTeK COMPUTER INC. UX330UAK",
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index 5cf9d9aff164..434249ac47a5 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -3634,9 +3634,6 @@ static int asus_wmi_add(struct platform_device *pdev)
if (asus->driver->quirks->wmi_force_als_set)
asus_wmi_set_als();
 
-   if (asus->driver->quirks->wmi_backlight_native)
-   acpi_video_set_dmi_backlight_type(acpi_backlight_native);
-
if (asus->driver->quirks->xusb2pr)
asus_wmi_set_xusb2pr(asus);
 
diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h
index 30770e411301..f30252efe1db 100644
--- a/drivers/platform/x86/asus-wmi.h
+++ b/drivers/platform/x86/asus-wmi.h
@@ -29,7 +29,6 @@ struct quirk_entry {
bool hotplug_wireless;
bool scalar_panel_brightness;
bool store_backlight_power;
-   bool wmi_backlight_native;
bool wmi_backlight_set_devstate;
bool wmi_force_als_set;
bool use_kbd_dock_devid;
-- 
2.37.2



[PATCH v5 19/31] platform/x86: nvidia-wmi-ec-backlight: Use acpi_video_get_backlight_type()

2022-08-25 Thread Hans de Goede
Add an acpi_video_get_backlight_type() == acpi_backlight_nvidia_wmi_ec
check. This will make nvidia-wmi-ec-backlight properly honor the user
selecting a different backlight driver through the acpi_backlight=...
kernel commandline option.

Since the auto-detect code check for nvidia-wmi-ec-backlight in
drivers/acpi/video_detect.c already checks that the WMI advertised
brightness-source is the embedded controller, this new check makes it
unnecessary for nvidia_wmi_ec_backlight_probe() to check this itself.

Suggested-by: Daniel Dadap 
Reviewed-by: Daniel Dadap 
Signed-off-by: Hans de Goede 
---
 drivers/platform/x86/Kconfig   |  1 +
 drivers/platform/x86/nvidia-wmi-ec-backlight.c | 14 +++---
 2 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index f2f98e942cf2..0cc5ac35fc57 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -93,6 +93,7 @@ config PEAQ_WMI
 
 config NVIDIA_WMI_EC_BACKLIGHT
tristate "EC Backlight Driver for Hybrid Graphics Notebook Systems"
+   depends on ACPI_VIDEO
depends on ACPI_WMI
depends on BACKLIGHT_CLASS_DEVICE
help
diff --git a/drivers/platform/x86/nvidia-wmi-ec-backlight.c 
b/drivers/platform/x86/nvidia-wmi-ec-backlight.c
index be803e47eac0..baccdf658538 100644
--- a/drivers/platform/x86/nvidia-wmi-ec-backlight.c
+++ b/drivers/platform/x86/nvidia-wmi-ec-backlight.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /**
  * wmi_brightness_notify() - helper function for calling WMI-wrapped ACPI 
method
@@ -87,19 +88,10 @@ static int nvidia_wmi_ec_backlight_probe(struct wmi_device 
*wdev, const void *ct
 {
struct backlight_properties props = {};
struct backlight_device *bdev;
-   u32 source;
int ret;
 
-   ret = wmi_brightness_notify(wdev, WMI_BRIGHTNESS_METHOD_SOURCE,
-  WMI_BRIGHTNESS_MODE_GET, );
-   if (ret)
-   return ret;
-
-   /*
-* This driver is only to be used when brightness control is handled
-* by the EC; otherwise, the GPU driver(s) should control brightness.
-*/
-   if (source != WMI_BRIGHTNESS_SOURCE_EC)
+   /* drivers/acpi/video_detect.c also checks that SOURCE == EC */
+   if (acpi_video_get_backlight_type() != acpi_backlight_nvidia_wmi_ec)
return -ENODEV;
 
/*
-- 
2.37.2



[PATCH v5 04/31] drm/radeon: Don't register backlight when another backlight should be used (v3)

2022-08-25 Thread Hans de Goede
Before this commit when we want userspace to use the acpi_video backlight
device we register both the GPU's native backlight device and acpi_video's
firmware acpi_video# backlight device. This relies on userspace preferring
firmware type backlight devices over native ones.

Registering 2 backlight devices for a single display really is
undesirable, don't register the GPU's native backlight device when
another backlight device should be used.

Changes in v2:
- To avoid linker errors when amdgpu is builtin and video_detect.c is in
  a module, select ACPI_VIDEO and its deps if ACPI is enabled.
  When ACPI is disabled, ACPI_VIDEO is also always disabled, ensuring
  the stubs from acpi/video.h will be used.

Changes in v3:
- Use drm_info(drm_dev, "...") to log messages
- ACPI_VIDEO can now be enabled on non X86 too,
  adjust the Kconfig changes to match this.

Acked-by: Alex Deucher 
Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/Kconfig | 7 +++
 drivers/gpu/drm/radeon/atombios_encoders.c  | 7 +++
 drivers/gpu/drm/radeon/radeon_legacy_encoders.c | 7 +++
 3 files changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 95ca33938b4a..0471505e951d 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -234,6 +234,13 @@ config DRM_RADEON
select HWMON
select BACKLIGHT_CLASS_DEVICE
select INTERVAL_TREE
+   # radeon depends on ACPI_VIDEO when ACPI is enabled, for select to work
+   # ACPI_VIDEO's dependencies must also be selected.
+   select INPUT if ACPI
+   select ACPI_VIDEO if ACPI
+   # On x86 ACPI_VIDEO also needs ACPI_WMI
+   select X86_PLATFORM_DEVICES if ACPI && X86
+   select ACPI_WMI if ACPI && X86
help
  Choose this option if you have an ATI Radeon graphics card.  There
  are both PCI and AGP versions.  You don't need to choose this to
diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c 
b/drivers/gpu/drm/radeon/atombios_encoders.c
index 0eae05dfb385..c841c273222e 100644
--- a/drivers/gpu/drm/radeon/atombios_encoders.c
+++ b/drivers/gpu/drm/radeon/atombios_encoders.c
@@ -32,6 +32,8 @@
 #include 
 #include 
 
+#include 
+
 #include "atom.h"
 #include "radeon_atombios.h"
 #include "radeon.h"
@@ -209,6 +211,11 @@ void radeon_atom_backlight_init(struct radeon_encoder 
*radeon_encoder,
if (!(rdev->mode_info.firmware_flags & 
ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
return;
 
+   if (!acpi_video_backlight_use_native()) {
+   drm_info(dev, "Skipping radeon atom DIG backlight 
registration\n");
+   return;
+   }
+
pdata = kmalloc(sizeof(struct radeon_backlight_privdata), GFP_KERNEL);
if (!pdata) {
DRM_ERROR("Memory allocation failed\n");
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c 
b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
index 1a66fb969ee7..0cd32c65456c 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c
@@ -33,6 +33,8 @@
 #include 
 #include 
 
+#include 
+
 #include "radeon.h"
 #include "radeon_asic.h"
 #include "radeon_legacy_encoders.h"
@@ -387,6 +389,11 @@ void radeon_legacy_backlight_init(struct radeon_encoder 
*radeon_encoder,
return;
 #endif
 
+   if (!acpi_video_backlight_use_native()) {
+   drm_info(dev, "Skipping radeon legacy LVDS backlight 
registration\n");
+   return;
+   }
+
pdata = kmalloc(sizeof(struct radeon_backlight_privdata), GFP_KERNEL);
if (!pdata) {
DRM_ERROR("Memory allocation failed\n");
-- 
2.37.2



[PATCH v5 10/31] ACPI: video: Remove code to unregister acpi_video backlight when a native backlight registers

2022-08-25 Thread Hans de Goede
Remove the code to unregister acpi_video backlight devices when
a native backlight device gets registered later.

Now that the acpi_video backlight device registration is a separate step
which runs later, after the drm/kms driver is done setting up its own
native backlight device, it is no longer necessary to monitor for a
native (BACKLIGHT_RAW) device showing up later and to then unregister
the acpi_video backlight device(s).

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/acpi_video.c   |  2 --
 drivers/acpi/video_detect.c | 36 
 2 files changed, 38 deletions(-)

diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
index 09dd86f86cf3..d1e41f30c004 100644
--- a/drivers/acpi/acpi_video.c
+++ b/drivers/acpi/acpi_video.c
@@ -94,7 +94,6 @@ static void acpi_video_bus_notify(struct acpi_device *device, 
u32 event);
 static void acpi_video_bus_register_backlight_work(struct work_struct 
*ignored);
 static DECLARE_DELAYED_WORK(video_bus_register_backlight_work,
acpi_video_bus_register_backlight_work);
-void acpi_video_detect_exit(void);
 
 /*
  * Indices in the _BCL method response: the first two items are special,
@@ -2342,7 +2341,6 @@ static int __init acpi_video_init(void)
 
 static void __exit acpi_video_exit(void)
 {
-   acpi_video_detect_exit();
acpi_video_unregister();
 }
 
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 385eb49c763f..fb49b8f4523a 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -38,10 +38,6 @@
 
 void acpi_video_unregister_backlight(void);
 
-static bool backlight_notifier_registered;
-static struct notifier_block backlight_nb;
-static struct work_struct backlight_notify_work;
-
 static enum acpi_backlight_type acpi_backlight_cmdline = acpi_backlight_undef;
 static enum acpi_backlight_type acpi_backlight_dmi = acpi_backlight_undef;
 
@@ -538,26 +534,6 @@ static const struct dmi_system_id video_detect_dmi_table[] 
= {
{ },
 };
 
-/* This uses a workqueue to avoid various locking ordering issues */
-static void acpi_video_backlight_notify_work(struct work_struct *work)
-{
-   if (acpi_video_get_backlight_type() != acpi_backlight_video)
-   acpi_video_unregister_backlight();
-}
-
-static int acpi_video_backlight_notify(struct notifier_block *nb,
-  unsigned long val, void *bd)
-{
-   struct backlight_device *backlight = bd;
-
-   /* A raw bl registering may change video -> native */
-   if (backlight->props.type == BACKLIGHT_RAW &&
-   val == BACKLIGHT_REGISTERED)
-   schedule_work(_notify_work);
-
-   return NOTIFY_OK;
-}
-
 /*
  * Determine which type of backlight interface to use on this system,
  * First check cmdline, then dmi quirks, then do autodetect.
@@ -587,12 +563,6 @@ static enum acpi_backlight_type 
__acpi_video_get_backlight_type(bool native)
acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX, find_video, NULL,
_caps, NULL);
-   INIT_WORK(_notify_work,
- acpi_video_backlight_notify_work);
-   backlight_nb.notifier_call = acpi_video_backlight_notify;
-   backlight_nb.priority = 0;
-   if (backlight_register_notifier(_nb) == 0)
-   backlight_notifier_registered = true;
init_done = true;
}
if (native)
@@ -639,9 +609,3 @@ void acpi_video_set_dmi_backlight_type(enum 
acpi_backlight_type type)
acpi_video_unregister_backlight();
 }
 EXPORT_SYMBOL(acpi_video_set_dmi_backlight_type);
-
-void __exit acpi_video_detect_exit(void)
-{
-   if (backlight_notifier_registered)
-   backlight_unregister_notifier(_nb);
-}
-- 
2.37.2



[PATCH v5 00/31] drm/kms: Stop registering multiple /sys/class/backlight devs for a single display

2022-08-25 Thread Hans de Goede
Hi All,

As mentioned in my RFC titled "drm/kms: control display brightness through
drm_connector properties":
https://lore.kernel.org/dri-devel/0d188965-d809-81b5-74ce-7d30c49fe...@redhat.com/

The first step towards this is to deal with some existing technical debt
in backlight handling on x86/ACPI boards, specifically we need to stop
registering multiple /sys/class/backlight devs for a single display.

This series implements my RFC describing my plan for these cleanups:
https://lore.kernel.org/dri-devel/98519ba0-7f18-201a-ea34-652f50343...@redhat.com/

Changes in version 5:
- Use drm_info(drm_dev, ...) in patch 2/31
- Modify "drm/i915: Call acpi_video_register_backlight()", dropping
  the global has_panel flag, replacing it with a new
  intel_acpi_video_register() helper

Changes in version 4:
- Minor tweaks to nvidia-wmi-ec-backlight changes
- Add nouveau_acpi_* wrappers around used include/acpi/video.h functions to
  fix unresolved symbol errors on non X86

Changes in version 3:
- ACPI_VIDEO can now be enabled on non X86 too, adjust various Kconfig changes
- Make the delay before doing fallback acpi_video backlight registration
  a module option (patch 9)
- Move the nvidia-wmi-ec-backlight fw API definitions to a shared header
- Add a "acpi_video_get_backlight_type() == acpi_backlight_nvidia_wmi_ec"
  check to the nvidia-wmi-ec-backlight driver (patch 19)

Changes in version 2:
- Introduce acpi_video_backlight_use_native() helper
- Finishes the refactoring, addressing all the bits from the "Other issues"
  section of the refactor RFC

This series as submitted is based on drm-tip for CI purposes.

Assuming the last i915 patch also pass review now, I hope to push
out an immutable branch with this series on top of v6.0-rc1 and
send out a pull-request to all involved subsystems based on
this branch soon.

Regards,

Hans


Hans de Goede (31):
  ACPI: video: Add acpi_video_backlight_use_native() helper
  drm/i915: Don't register backlight when another backlight should be
used (v2)
  drm/amdgpu: Don't register backlight when another backlight should be
used (v3)
  drm/radeon: Don't register backlight when another backlight should be
used (v3)
  drm/nouveau: Don't register backlight when another backlight should be
used (v2)
  ACPI: video: Drop backlight_device_get_by_type() call from
acpi_video_get_backlight_type()
  ACPI: video: Remove acpi_video_bus from list before tearing it down
  ACPI: video: Simplify acpi_video_unregister_backlight()
  ACPI: video: Make backlight class device registration a separate step
(v2)
  ACPI: video: Remove code to unregister acpi_video backlight when a
native backlight registers
  drm/i915: Call acpi_video_register_backlight() (v3)
  drm/nouveau: Register ACPI video backlight when nv_backlight
registration fails (v2)
  drm/amdgpu: Register ACPI video backlight when skipping amdgpu
backlight registration
  drm/radeon: Register ACPI video backlight when skipping radeon
backlight registration
  platform/x86: nvidia-wmi-ec-backlight: Move fw interface definitions
to a header (v2)
  ACPI: video: Refactor acpi_video_get_backlight_type() a bit
  ACPI: video: Add Nvidia WMI EC brightness control detection (v3)
  ACPI: video: Add Apple GMUX brightness control detection
  platform/x86: nvidia-wmi-ec-backlight: Use
acpi_video_get_backlight_type()
  platform/x86: apple-gmux: Stop calling acpi/video.h functions
  platform/x86: toshiba_acpi: Stop using
acpi_video_set_dmi_backlight_type()
  platform/x86: acer-wmi: Move backlight DMI quirks to
acpi/video_detect.c
  platform/x86: asus-wmi: Drop DMI chassis-type check from backlight
handling
  platform/x86: asus-wmi: Move acpi_backlight=vendor quirks to ACPI
video_detect.c
  platform/x86: asus-wmi: Move acpi_backlight=native quirks to ACPI
video_detect.c
  platform/x86: samsung-laptop: Move acpi_backlight=[vendor|native]
quirks to ACPI video_detect.c
  ACPI: video: Remove acpi_video_set_dmi_backlight_type()
  ACPI: video: Drop "Samsung X360" acpi_backlight=native quirk
  ACPI: video: Drop NL5x?U, PF4NU1F and PF5?U?? acpi_backlight=native
quirks
  ACPI: video: Fix indentation of video_detect_dmi_table[] entries
  drm/todo: Add entry about dealing with brightness control on devices
with > 1 panel

 Documentation/gpu/todo.rst|  68 +++
 MAINTAINERS   |   1 +
 drivers/acpi/Kconfig  |   1 +
 drivers/acpi/acpi_video.c |  64 ++-
 drivers/acpi/video_detect.c   | 428 +++---
 drivers/gpu/drm/Kconfig   |  14 +
 .../gpu/drm/amd/amdgpu/atombios_encoders.c|  14 +-
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |   9 +
 drivers/gpu/drm/gma500/Kconfig|   2 +
 drivers/gpu/drm/i915/Kconfig  |   2 +
 drivers/gpu/drm/i915/display/intel_acpi.c |  27 ++

[PATCH v5 14/31] drm/radeon: Register ACPI video backlight when skipping radeon backlight registration

2022-08-25 Thread Hans de Goede
Typically the acpi_video driver will initialize before radeon, which
used to cause /sys/class/backlight/acpi_video0 to get registered and then
radeon would register its own radeon_bl# device later. After which
the drivers/acpi/video_detect.c code unregistered the acpi_video0 device
to avoid there being 2 backlight devices.

This means that userspace used to briefly see 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

To fix this the ACPI video code has been modified to make backlight class
device registration a separate step, relying on the drm/kms driver to
ask for the acpi_video backlight registration after it is done setting up
its native backlight device.

Add a call to the new acpi_video_register_backlight() when radeon skips
registering its own backlight device because of e.g. the firmware_flags
or the acpi_video_get_backlight_type() return value. This ensures that
if the acpi_video backlight device should be used, it will be available
before the radeon drm_device gets registered with userspace.

Acked-by: Alex Deucher 
Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/radeon/radeon_encoders.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c 
b/drivers/gpu/drm/radeon/radeon_encoders.c
index 35c535e48b8d..fbc0a2182318 100644
--- a/drivers/gpu/drm/radeon/radeon_encoders.c
+++ b/drivers/gpu/drm/radeon/radeon_encoders.c
@@ -30,6 +30,8 @@
 #include 
 #include 
 
+#include 
+
 #include "radeon.h"
 #include "radeon_atombios.h"
 #include "radeon_legacy_encoders.h"
@@ -167,7 +169,7 @@ static void radeon_encoder_add_backlight(struct 
radeon_encoder *radeon_encoder,
return;
 
if (radeon_backlight == 0) {
-   return;
+   use_bl = false;
} else if (radeon_backlight == 1) {
use_bl = true;
} else if (radeon_backlight == -1) {
@@ -193,6 +195,13 @@ static void radeon_encoder_add_backlight(struct 
radeon_encoder *radeon_encoder,
else
radeon_legacy_backlight_init(radeon_encoder, connector);
}
+
+   /*
+* If there is no native backlight device (which may happen even when
+* use_bl==true) try registering an ACPI video backlight device instead.
+*/
+   if (!rdev->mode_info.bl_encoder)
+   acpi_video_register_backlight();
 }
 
 void
-- 
2.37.2



[PATCH v5 06/31] ACPI: video: Drop backlight_device_get_by_type() call from acpi_video_get_backlight_type()

2022-08-25 Thread Hans de Goede
All x86/ACPI kms drivers which register native/BACKLIGHT_RAW type
backlight devices call acpi_video_backlight_use_native() now. This sets
__acpi_video_get_backlight_type()'s internal static native_available flag.

This makes the backlight_device_get_by_type(BACKLIGHT_RAW) check
unnecessary.

Relying on the cached native_available value not only is simpler, it will
also work correctly in cases where then native backlight registration was
skipped because of acpi_video_backlight_use_native() returning false.

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/video_detect.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 5f105eaa7d30..385eb49c763f 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -608,8 +608,7 @@ static enum acpi_backlight_type 
__acpi_video_get_backlight_type(bool native)
if (!(video_caps & ACPI_VIDEO_BACKLIGHT))
return acpi_backlight_vendor;
 
-   if (acpi_osi_is_win8() &&
-   (native_available || backlight_device_get_by_type(BACKLIGHT_RAW)))
+   if (acpi_osi_is_win8() && native_available)
return acpi_backlight_native;
 
return acpi_backlight_video;
-- 
2.37.2



[PATCH v5 01/31] ACPI: video: Add acpi_video_backlight_use_native() helper

2022-08-25 Thread Hans de Goede
ATM on x86 laptops where we want userspace to use the acpi_video backlight
device we often register both the GPU's native backlight device and
acpi_video's firmware acpi_video# backlight device. This relies on
userspace preferring firmware type backlight devices over native ones, but
registering 2 backlight devices for a single display really is undesirable.

On x86 laptops where the native GPU backlight device should be used,
the registering of other backlight devices is avoided by their drivers
using acpi_video_get_backlight_type() and only registering their backlight
if the return value matches their type.

acpi_video_get_backlight_type() uses
backlight_device_get_by_type(BACKLIGHT_RAW) to determine if a native
driver is available and will never return native if this returns
false. This means that the GPU's native backlight registering code
cannot just call acpi_video_get_backlight_type() to determine if it
should register its backlight, since acpi_video_get_backlight_type() will
never return native until the native backlight has already registered.

To fix this add a new internal native function parameter to
acpi_video_get_backlight_type(), which when set to true will make
acpi_video_get_backlight_type() behave as if a native backlight has
already been registered.

And add a new acpi_video_backlight_use_native() helper, which sets this
to true, for use in native GPU backlight code.

Changes in v2:
- Replace adding a native parameter to acpi_video_get_backlight_type() with
  adding a new acpi_video_backlight_use_native() helper.

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/video_detect.c | 24 
 include/acpi/video.h|  5 +
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 5d7f38016a24..5f105eaa7d30 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -17,8 +17,9 @@
  * Otherwise vendor specific drivers like thinkpad_acpi, asus-laptop,
  * sony_acpi,... can take care about backlight brightness.
  *
- * Backlight drivers can use acpi_video_get_backlight_type() to determine
- * which driver should handle the backlight.
+ * Backlight drivers can use acpi_video_get_backlight_type() to determine which
+ * driver should handle the backlight. RAW/GPU-driver backlight drivers must
+ * use the acpi_video_backlight_use_native() helper for this.
  *
  * If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m)
  * this file will not be compiled and acpi_video_get_backlight_type() will
@@ -571,9 +572,10 @@ static int acpi_video_backlight_notify(struct 
notifier_block *nb,
  * Arguably the native on win8 check should be done first, but that would
  * be a behavior change, which may causes issues.
  */
-enum acpi_backlight_type acpi_video_get_backlight_type(void)
+static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
 {
static DEFINE_MUTEX(init_mutex);
+   static bool native_available;
static bool init_done;
static long video_caps;
 
@@ -593,6 +595,8 @@ enum acpi_backlight_type acpi_video_get_backlight_type(void)
backlight_notifier_registered = true;
init_done = true;
}
+   if (native)
+   native_available = true;
mutex_unlock(_mutex);
 
if (acpi_backlight_cmdline != acpi_backlight_undef)
@@ -604,13 +608,25 @@ enum acpi_backlight_type 
acpi_video_get_backlight_type(void)
if (!(video_caps & ACPI_VIDEO_BACKLIGHT))
return acpi_backlight_vendor;
 
-   if (acpi_osi_is_win8() && backlight_device_get_by_type(BACKLIGHT_RAW))
+   if (acpi_osi_is_win8() &&
+   (native_available || backlight_device_get_by_type(BACKLIGHT_RAW)))
return acpi_backlight_native;
 
return acpi_backlight_video;
 }
+
+enum acpi_backlight_type acpi_video_get_backlight_type(void)
+{
+   return __acpi_video_get_backlight_type(false);
+}
 EXPORT_SYMBOL(acpi_video_get_backlight_type);
 
+bool acpi_video_backlight_use_native(void)
+{
+   return __acpi_video_get_backlight_type(true) == acpi_backlight_native;
+}
+EXPORT_SYMBOL(acpi_video_backlight_use_native);
+
 /*
  * Set the preferred backlight interface type based on DMI info.
  * This function allows DMI blacklists to be implemented by external
diff --git a/include/acpi/video.h b/include/acpi/video.h
index db8548ff03ce..4705e339c252 100644
--- a/include/acpi/video.h
+++ b/include/acpi/video.h
@@ -56,6 +56,7 @@ extern void acpi_video_unregister(void);
 extern int acpi_video_get_edid(struct acpi_device *device, int type,
   int device_id, void **edid);
 extern enum acpi_backlight_type acpi_video_get_backlight_type(void);
+extern bool acpi_video_backlight_use_native(void);
 extern void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type);
 /

[PATCH v5 18/31] ACPI: video: Add Apple GMUX brightness control detection

2022-08-25 Thread Hans de Goede
On Apple laptops with an Apple GMUX using this for brightness control,
should take precedence of any other brightness control methods.

Add apple-gmux detection to acpi_video_get_backlight_type() using
the already existing apple_gmux_present() helper function.

This will allow removig the (ab)use of:

acpi_video_set_dmi_backlight_type(acpi_backlight_vendor);

Inside the apple-gmux driver.

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/video_detect.c | 4 
 include/acpi/video.h| 1 +
 2 files changed, 5 insertions(+)

diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 4dc7fb865083..be2fc43418af 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -28,6 +28,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -607,6 +608,9 @@ static enum acpi_backlight_type 
__acpi_video_get_backlight_type(bool native)
if (nvidia_wmi_ec_present)
return acpi_backlight_nvidia_wmi_ec;
 
+   if (apple_gmux_present())
+   return acpi_backlight_apple_gmux;
+
/* On systems with ACPI video use either native or ACPI video. */
if (video_caps & ACPI_VIDEO_BACKLIGHT) {
/*
diff --git a/include/acpi/video.h b/include/acpi/video.h
index 91578e77ac4e..dbd48cb8bd23 100644
--- a/include/acpi/video.h
+++ b/include/acpi/video.h
@@ -49,6 +49,7 @@ enum acpi_backlight_type {
acpi_backlight_vendor,
acpi_backlight_native,
acpi_backlight_nvidia_wmi_ec,
+   acpi_backlight_apple_gmux,
 };
 
 #if IS_ENABLED(CONFIG_ACPI_VIDEO)
-- 
2.37.2



[PATCH v5 13/31] drm/amdgpu: Register ACPI video backlight when skipping amdgpu backlight registration

2022-08-25 Thread Hans de Goede
Typically the acpi_video driver will initialize before amdgpu, which
used to cause /sys/class/backlight/acpi_video0 to get registered and then
amdgpu would register its own amdgpu_bl# device later. After which
the drivers/acpi/video_detect.c code unregistered the acpi_video0 device
to avoid there being 2 backlight devices.

This means that userspace used to briefly see 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

To fix this the ACPI video code has been modified to make backlight class
device registration a separate step, relying on the drm/kms driver to
ask for the acpi_video backlight registration after it is done setting up
its native backlight device.

Add a call to the new acpi_video_register_backlight() when amdgpu skips
registering its own backlight device because of either the firmware_flags
or the acpi_video_get_backlight_type() return value. This ensures that
if the acpi_video backlight device should be used, it will be available
before the amdgpu drm_device gets registered with userspace.

Acked-by: Alex Deucher 
Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/amd/amdgpu/atombios_encoders.c| 9 +++--
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c 
b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
index b4e3cedceaf8..6be9ac2b9c5b 100644
--- a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
+++ b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
@@ -184,11 +184,11 @@ void amdgpu_atombios_encoder_init_backlight(struct 
amdgpu_encoder *amdgpu_encode
return;
 
if (!(adev->mode_info.firmware_flags & 
ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
-   return;
+   goto register_acpi_backlight;
 
if (!acpi_video_backlight_use_native()) {
drm_info(dev, "Skipping amdgpu atom DIG backlight 
registration\n");
-   return;
+   goto register_acpi_backlight;
}
 
pdata = kmalloc(sizeof(struct amdgpu_backlight_privdata), GFP_KERNEL);
@@ -225,6 +225,11 @@ void amdgpu_atombios_encoder_init_backlight(struct 
amdgpu_encoder *amdgpu_encode
 error:
kfree(pdata);
return;
+
+register_acpi_backlight:
+   /* Try registering an ACPI video backlight device instead. */
+   acpi_video_register_backlight();
+   return;
 }
 
 void
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 706c67f4bda8..c450964f84d4 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4037,6 +4037,8 @@ amdgpu_dm_register_backlight_device(struct 
amdgpu_display_manager *dm)
 
if (!acpi_video_backlight_use_native()) {
drm_info(adev_to_drm(dm->adev), "Skipping amdgpu DM backlight 
registration\n");
+   /* Try registering an ACPI video backlight device instead. */
+   acpi_video_register_backlight();
return;
}
 
-- 
2.37.2



[PATCH v5 03/31] drm/amdgpu: Don't register backlight when another backlight should be used (v3)

2022-08-25 Thread Hans de Goede
Before this commit when we want userspace to use the acpi_video backlight
device we register both the GPU's native backlight device and acpi_video's
firmware acpi_video# backlight device. This relies on userspace preferring
firmware type backlight devices over native ones.

Registering 2 backlight devices for a single display really is
undesirable, don't register the GPU's native backlight device when
another backlight device should be used.

Changes in v2:
- To avoid linker errors when amdgpu is builtin and video_detect.c is in
  a module, select ACPI_VIDEO and its deps if ACPI is enabled.
  When ACPI is disabled, ACPI_VIDEO is also always disabled, ensuring
  the stubs from acpi/video.h will be used.

Changes in v3:
- Use drm_info(drm_dev, "...") to log messages
- ACPI_VIDEO can now be enabled on non X86 too,
  adjust the Kconfig changes to match this.

Acked-by: Alex Deucher 
Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/Kconfig   | 7 +++
 drivers/gpu/drm/amd/amdgpu/atombios_encoders.c| 7 +++
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 7 +++
 3 files changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 0b2ad7212ee6..95ca33938b4a 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -259,6 +259,13 @@ config DRM_AMDGPU
select BACKLIGHT_CLASS_DEVICE
select INTERVAL_TREE
select DRM_BUDDY
+   # amdgpu depends on ACPI_VIDEO when ACPI is enabled, for select to work
+   # ACPI_VIDEO's dependencies must also be selected.
+   select INPUT if ACPI
+   select ACPI_VIDEO if ACPI
+   # On x86 ACPI_VIDEO also needs ACPI_WMI
+   select X86_PLATFORM_DEVICES if ACPI && X86
+   select ACPI_WMI if ACPI && X86
help
  Choose this option if you have a recent AMD Radeon graphics card.
 
diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c 
b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
index fa7421afb9a6..b4e3cedceaf8 100644
--- a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
+++ b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c
@@ -26,6 +26,8 @@
 
 #include 
 
+#include 
+
 #include 
 #include 
 #include "amdgpu.h"
@@ -184,6 +186,11 @@ void amdgpu_atombios_encoder_init_backlight(struct 
amdgpu_encoder *amdgpu_encode
if (!(adev->mode_info.firmware_flags & 
ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU))
return;
 
+   if (!acpi_video_backlight_use_native()) {
+   drm_info(dev, "Skipping amdgpu atom DIG backlight 
registration\n");
+   return;
+   }
+
pdata = kmalloc(sizeof(struct amdgpu_backlight_privdata), GFP_KERNEL);
if (!pdata) {
DRM_ERROR("Memory allocation failed\n");
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index e702f0d72d53..706c67f4bda8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -90,6 +90,8 @@
 #include 
 #include 
 
+#include 
+
 #include "ivsrcid/dcn/irqsrcs_dcn_1_0.h"
 
 #include "dcn/dcn_1_0_offset.h"
@@ -4033,6 +4035,11 @@ amdgpu_dm_register_backlight_device(struct 
amdgpu_display_manager *dm)
amdgpu_dm_update_backlight_caps(dm, dm->num_of_edps);
dm->brightness[dm->num_of_edps] = AMDGPU_MAX_BL_LEVEL;
 
+   if (!acpi_video_backlight_use_native()) {
+   drm_info(adev_to_drm(dm->adev), "Skipping amdgpu DM backlight 
registration\n");
+   return;
+   }
+
props.max_brightness = AMDGPU_MAX_BL_LEVEL;
props.brightness = AMDGPU_MAX_BL_LEVEL;
props.type = BACKLIGHT_RAW;
-- 
2.37.2



[PATCH v5 30/31] ACPI: video: Fix indentation of video_detect_dmi_table[] entries

2022-08-25 Thread Hans de Goede
The video_detect_dmi_table[] uses an unusual indentation for
before the ".name = ..." named struct initializers.

Instead of being indented with an extra tab compared to
the previous line's '{' these are indented to with only
a single space to allow for long DMI_MATCH() lines without
wrapping.

But over time some entries did not event have the single space
indent in front of the ".name = ..." lines.

Make things consistent by using a single space indent for these
lines everywhere.

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/video_detect.c | 48 ++---
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 789d5913c178..db2474fe58ac 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -142,17 +142,17 @@ static const struct dmi_system_id 
video_detect_dmi_table[] = {
},
},
{
-   .callback = video_detect_force_vendor,
-   /* Asus UL30VT */
-   .matches = {
+.callback = video_detect_force_vendor,
+/* Asus UL30VT */
+.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "UL30VT"),
},
},
{
-   .callback = video_detect_force_vendor,
-   /* Asus UL30A */
-   .matches = {
+.callback = video_detect_force_vendor,
+/* Asus UL30A */
+.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "UL30A"),
},
@@ -198,9 +198,9 @@ static const struct dmi_system_id video_detect_dmi_table[] 
= {
},
},
{
-   .callback = video_detect_force_vendor,
-   /* GIGABYTE GB-BXBT-2807 */
-   .matches = {
+.callback = video_detect_force_vendor,
+/* GIGABYTE GB-BXBT-2807 */
+.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"),
DMI_MATCH(DMI_PRODUCT_NAME, "GB-BXBT-2807"),
},
@@ -233,17 +233,17 @@ static const struct dmi_system_id 
video_detect_dmi_table[] = {
},
},
{
-   .callback = video_detect_force_vendor,
-   /* Sony VPCEH3U1E */
-   .matches = {
+.callback = video_detect_force_vendor,
+/* Sony VPCEH3U1E */
+.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, "VPCEH3U1E"),
},
},
{
-   .callback = video_detect_force_vendor,
-   /* Xiaomi Mi Pad 2 */
-   .matches = {
+.callback = video_detect_force_vendor,
+/* Xiaomi Mi Pad 2 */
+.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"),
DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"),
},
@@ -551,25 +551,25 @@ static const struct dmi_system_id 
video_detect_dmi_table[] = {
},
},
{
-   .callback = video_detect_force_native,
-   /* ASUSTeK COMPUTER INC. GA401 */
-   .matches = {
+.callback = video_detect_force_native,
+/* ASUSTeK COMPUTER INC. GA401 */
+.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "GA401"),
},
},
{
-   .callback = video_detect_force_native,
-   /* ASUSTeK COMPUTER INC. GA502 */
-   .matches = {
+.callback = video_detect_force_native,
+/* ASUSTeK COMPUTER INC. GA502 */
+.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "GA502"),
},
},
{
-   .callback = video_detect_force_native,
-   /* ASUSTeK COMPUTER INC. GA503 */
-   .matches = {
+.callback = video_detect_force_native,
+/* ASUSTeK COMPUTER INC. GA503 */
+.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "GA503"),
},
-- 
2.37.2



[PATCH v5 05/31] drm/nouveau: Don't register backlight when another backlight should be used (v2)

2022-08-25 Thread Hans de Goede
Before this commit when we want userspace to use the acpi_video backlight
device we register both the GPU's native backlight device and acpi_video's
firmware acpi_video# backlight device. This relies on userspace preferring
firmware type backlight devices over native ones.

Registering 2 backlight devices for a single display really is
undesirable, don't register the GPU's native backlight device when
another backlight device should be used.

Changes in v2:
- Add nouveau_acpi_video_backlight_use_native() wrapper to avoid unresolved
  symbol errors on non X86

Signed-off-by: Hans de Goede 
---
 drivers/gpu/drm/nouveau/nouveau_acpi.c  | 5 +
 drivers/gpu/drm/nouveau/nouveau_acpi.h  | 2 ++
 drivers/gpu/drm/nouveau/nouveau_backlight.c | 6 ++
 3 files changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c 
b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index 6140db756d06..1592c9cd7750 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -386,3 +386,8 @@ nouveau_acpi_edid(struct drm_device *dev, struct 
drm_connector *connector)
 
return kmemdup(edid, EDID_LENGTH, GFP_KERNEL);
 }
+
+bool nouveau_acpi_video_backlight_use_native(void)
+{
+   return acpi_video_backlight_use_native();
+}
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.h 
b/drivers/gpu/drm/nouveau/nouveau_acpi.h
index 330f9b837066..3c666c30dfca 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.h
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.h
@@ -11,6 +11,7 @@ void nouveau_register_dsm_handler(void);
 void nouveau_unregister_dsm_handler(void);
 void nouveau_switcheroo_optimus_dsm(void);
 void *nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
+bool nouveau_acpi_video_backlight_use_native(void);
 #else
 static inline bool nouveau_is_optimus(void) { return false; };
 static inline bool nouveau_is_v1_dsm(void) { return false; };
@@ -18,6 +19,7 @@ static inline void nouveau_register_dsm_handler(void) {}
 static inline void nouveau_unregister_dsm_handler(void) {}
 static inline void nouveau_switcheroo_optimus_dsm(void) {}
 static inline void *nouveau_acpi_edid(struct drm_device *dev, struct 
drm_connector *connector) { return NULL; }
+static inline bool nouveau_acpi_video_backlight_use_native(void) { return 
true; }
 #endif
 
 #endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c 
b/drivers/gpu/drm/nouveau/nouveau_backlight.c
index a2141d3d9b1d..d2b8f8c13db4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
+++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
@@ -38,6 +38,7 @@
 #include "nouveau_reg.h"
 #include "nouveau_encoder.h"
 #include "nouveau_connector.h"
+#include "nouveau_acpi.h"
 
 static struct ida bl_ida;
 #define BL_NAME_SIZE 15 // 12 for name + 2 for digits + 1 for '\0'
@@ -405,6 +406,11 @@ nouveau_backlight_init(struct drm_connector *connector)
goto fail_alloc;
}
 
+   if (!nouveau_acpi_video_backlight_use_native()) {
+   NV_INFO(drm, "Skipping nv_backlight registration\n");
+   goto fail_alloc;
+   }
+
if (!nouveau_get_backlight_name(backlight_name, bl)) {
NV_ERROR(drm, "Failed to retrieve a unique name for the 
backlight interface\n");
goto fail_alloc;
-- 
2.37.2



[PATCH v5 07/31] ACPI: video: Remove acpi_video_bus from list before tearing it down

2022-08-25 Thread Hans de Goede
Move the list_del removing an acpi_video_bus from video_bus_head
on teardown to before the teardown is done, to avoid code iterating
over the video_bus_head list seeing acpi_video_bus objects on there
which are (partly) torn down already.

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/acpi_video.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
index 5cbe2196176d..cde8ffa9f0b8 100644
--- a/drivers/acpi/acpi_video.c
+++ b/drivers/acpi/acpi_video.c
@@ -2111,14 +2111,14 @@ static int acpi_video_bus_remove(struct acpi_device 
*device)
 
video = acpi_driver_data(device);
 
-   acpi_video_bus_remove_notify_handler(video);
-   acpi_video_bus_unregister_backlight(video);
-   acpi_video_bus_put_devices(video);
-
mutex_lock(_list_lock);
list_del(>entry);
mutex_unlock(_list_lock);
 
+   acpi_video_bus_remove_notify_handler(video);
+   acpi_video_bus_unregister_backlight(video);
+   acpi_video_bus_put_devices(video);
+
kfree(video->attached_array);
kfree(video);
 
-- 
2.37.2



Re: [PATCH v4 05/31] drm/nouveau: Don't register backlight when another backlight should be used (v2)

2022-08-25 Thread Hans de Goede
Hi Lyude,

Thank you for the review.

On 8/24/22 19:41, Lyude Paul wrote:
> Just one tiny nitpick below:
> 
> On Wed, 2022-08-24 at 14:14 +0200, Hans de Goede wrote:
>> Before this commit when we want userspace to use the acpi_video backlight
>> device we register both the GPU's native backlight device and acpi_video's
>> firmware acpi_video# backlight device. This relies on userspace preferring
>> firmware type backlight devices over native ones.
>>
>> Registering 2 backlight devices for a single display really is
>> undesirable, don't register the GPU's native backlight device when
>> another backlight device should be used.
>>
>> Changes in v2:
>> - Add nouveau_acpi_video_backlight_use_native() wrapper to avoid unresolved
>>   symbol errors on non X86
>>
>> Signed-off-by: Hans de Goede 
>> ---
>>  drivers/gpu/drm/nouveau/nouveau_acpi.c  | 5 +
>>  drivers/gpu/drm/nouveau/nouveau_acpi.h  | 2 ++
>>  drivers/gpu/drm/nouveau/nouveau_backlight.c | 6 ++
>>  3 files changed, 13 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c 
>> b/drivers/gpu/drm/nouveau/nouveau_acpi.c
>> index 6140db756d06..1592c9cd7750 100644
>> --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
>> +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
>> @@ -386,3 +386,8 @@ nouveau_acpi_edid(struct drm_device *dev, struct 
>> drm_connector *connector)
>>  
>>  return kmemdup(edid, EDID_LENGTH, GFP_KERNEL);
>>  }
>> +
>> +bool nouveau_acpi_video_backlight_use_native(void)
>> +{
>> +return acpi_video_backlight_use_native();
>> +}
>> diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.h 
>> b/drivers/gpu/drm/nouveau/nouveau_acpi.h
>> index 330f9b837066..3c666c30dfca 100644
>> --- a/drivers/gpu/drm/nouveau/nouveau_acpi.h
>> +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.h
>> @@ -11,6 +11,7 @@ void nouveau_register_dsm_handler(void);
>>  void nouveau_unregister_dsm_handler(void);
>>  void nouveau_switcheroo_optimus_dsm(void);
>>  void *nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
>> +bool nouveau_acpi_video_backlight_use_native(void);
>>  #else
>>  static inline bool nouveau_is_optimus(void) { return false; };
>>  static inline bool nouveau_is_v1_dsm(void) { return false; };
>> @@ -18,6 +19,7 @@ static inline void nouveau_register_dsm_handler(void) {}
>>  static inline void nouveau_unregister_dsm_handler(void) {}
>>  static inline void nouveau_switcheroo_optimus_dsm(void) {}
>>  static inline void *nouveau_acpi_edid(struct drm_device *dev, struct 
>> drm_connector *connector) { return NULL; }
>> +static inline bool nouveau_acpi_video_backlight_use_native(void) { return 
>> true; }
>>  #endif
>>  
>>  #endif
>> diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c 
>> b/drivers/gpu/drm/nouveau/nouveau_backlight.c
>> index a2141d3d9b1d..d2b8f8c13db4 100644
>> --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c
>> +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c
>> @@ -38,6 +38,7 @@
>>  #include "nouveau_reg.h"
>>  #include "nouveau_encoder.h"
>>  #include "nouveau_connector.h"
>> +#include "nouveau_acpi.h"
>>  
>>  static struct ida bl_ida;
>>  #define BL_NAME_SIZE 15 // 12 for name + 2 for digits + 1 for '\0'
>> @@ -405,6 +406,11 @@ nouveau_backlight_init(struct drm_connector *connector)
>>  goto fail_alloc;
>>  }
>>  
>> +if (!nouveau_acpi_video_backlight_use_native()) {
>> +NV_INFO(drm, "Skipping nv_backlight registration\n");
>> +goto fail_alloc;
>> +}
> 
> We should probably make this say something like "No native backlight
> interface, using ACPI instead" instead. With that fixed

But that would not be correct. If we get to this point then before
the change we would continue with registering the native backlight
interface.

In other words, the native backlight interface is known to
be available at this point so saying "No native backlight interface"
would not be correct.

The reason the registration is being skipped is because the
drivers/acpi/video_detect.c heuristics (or DMI quirk or cmdline
override) say that another method to control the backlight is
preferred and we want to stop registering the native backlight
alltogether in that case so that there is only
1 /sys/class/backlight entry (on a 1 GPU 1 panel system).

Also "using ACPI instead" is not correct, on older systems
it might e.g. by a vendor specific control method such as
the one from dell-laptop. And on newer systems i

Re: [PATCH v4 02/31] drm/i915: Don't register backlight when another backlight should be used

2022-08-25 Thread Hans de Goede
Hi All,

On 8/24/22 14:50, Jani Nikula wrote:
> On Wed, 24 Aug 2022, Hans de Goede  wrote:
>> Before this commit when we want userspace to use the acpi_video backlight
>> device we register both the GPU's native backlight device and acpi_video's
>> firmware acpi_video# backlight device. This relies on userspace preferring
>> firmware type backlight devices over native ones.
>>
>> Registering 2 backlight devices for a single display really is
>> undesirable, don't register the GPU's native backlight device when
>> another backlight device should be used.
>>
>> Signed-off-by: Hans de Goede 
>> ---
>>  drivers/gpu/drm/i915/display/intel_backlight.c | 7 +++
>>  1 file changed, 7 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/display/intel_backlight.c 
>> b/drivers/gpu/drm/i915/display/intel_backlight.c
>> index 681ebcda97ad..a4dd7924e0c1 100644
>> --- a/drivers/gpu/drm/i915/display/intel_backlight.c
>> +++ b/drivers/gpu/drm/i915/display/intel_backlight.c
>> @@ -8,6 +8,8 @@
>>  #include 
>>  #include 
>>  
>> +#include 
>> +
>>  #include "intel_backlight.h"
>>  #include "intel_backlight_regs.h"
>>  #include "intel_connector.h"
>> @@ -952,6 +954,11 @@ int intel_backlight_device_register(struct 
>> intel_connector *connector)
>>  
>>  WARN_ON(panel->backlight.max == 0);
>>  
>> +if (!acpi_video_backlight_use_native()) {
>> +DRM_INFO("Skipping intel_backlight registration\n");
> 
> Could use drm_info with drm_device.

Ack, fixed for v5.

> Either way,
> 
> Reviewed-by: Jani Nikula 

Thank you.

> and ack for merging via whichever tree suits you best.

My plan is to create a branch with the series on top
of 6.0-rc1 and then send a pull-req to all involved trees.

So far there are no conflicts between this branch and drm-tip...

Regards,

Hans



>> +return 0;
>> +}
>> +
>>  memset(, 0, sizeof(props));
>>  props.type = BACKLIGHT_RAW;
> 



[PATCH v4 08/31] ACPI: video: Simplify acpi_video_unregister_backlight()

2022-08-25 Thread Hans de Goede
When acpi_video_register() has not run yet the video_bus_head will be
empty, so there is no need to check the register_count flag first.

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/acpi_video.c | 12 
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c
index cde8ffa9f0b8..8545bf94866f 100644
--- a/drivers/acpi/acpi_video.c
+++ b/drivers/acpi/acpi_video.c
@@ -2257,14 +2257,10 @@ void acpi_video_unregister_backlight(void)
 {
struct acpi_video_bus *video;
 
-   mutex_lock(_count_mutex);
-   if (register_count) {
-   mutex_lock(_list_lock);
-   list_for_each_entry(video, _bus_head, entry)
-   acpi_video_bus_unregister_backlight(video);
-   mutex_unlock(_list_lock);
-   }
-   mutex_unlock(_count_mutex);
+   mutex_lock(_list_lock);
+   list_for_each_entry(video, _bus_head, entry)
+   acpi_video_bus_unregister_backlight(video);
+   mutex_unlock(_list_lock);
 }
 
 bool acpi_video_handles_brightness_key_presses(void)
-- 
2.37.2



[PATCH v4 01/31] ACPI: video: Add acpi_video_backlight_use_native() helper

2022-08-25 Thread Hans de Goede
ATM on x86 laptops where we want userspace to use the acpi_video backlight
device we often register both the GPU's native backlight device and
acpi_video's firmware acpi_video# backlight device. This relies on
userspace preferring firmware type backlight devices over native ones, but
registering 2 backlight devices for a single display really is undesirable.

On x86 laptops where the native GPU backlight device should be used,
the registering of other backlight devices is avoided by their drivers
using acpi_video_get_backlight_type() and only registering their backlight
if the return value matches their type.

acpi_video_get_backlight_type() uses
backlight_device_get_by_type(BACKLIGHT_RAW) to determine if a native
driver is available and will never return native if this returns
false. This means that the GPU's native backlight registering code
cannot just call acpi_video_get_backlight_type() to determine if it
should register its backlight, since acpi_video_get_backlight_type() will
never return native until the native backlight has already registered.

To fix this add a new internal native function parameter to
acpi_video_get_backlight_type(), which when set to true will make
acpi_video_get_backlight_type() behave as if a native backlight has
already been registered.

And add a new acpi_video_backlight_use_native() helper, which sets this
to true, for use in native GPU backlight code.

Changes in v2:
- Replace adding a native parameter to acpi_video_get_backlight_type() with
  adding a new acpi_video_backlight_use_native() helper.

Acked-by: Rafael J. Wysocki 
Signed-off-by: Hans de Goede 
---
 drivers/acpi/video_detect.c | 24 
 include/acpi/video.h|  5 +
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 5d7f38016a24..5f105eaa7d30 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -17,8 +17,9 @@
  * Otherwise vendor specific drivers like thinkpad_acpi, asus-laptop,
  * sony_acpi,... can take care about backlight brightness.
  *
- * Backlight drivers can use acpi_video_get_backlight_type() to determine
- * which driver should handle the backlight.
+ * Backlight drivers can use acpi_video_get_backlight_type() to determine which
+ * driver should handle the backlight. RAW/GPU-driver backlight drivers must
+ * use the acpi_video_backlight_use_native() helper for this.
  *
  * If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m)
  * this file will not be compiled and acpi_video_get_backlight_type() will
@@ -571,9 +572,10 @@ static int acpi_video_backlight_notify(struct 
notifier_block *nb,
  * Arguably the native on win8 check should be done first, but that would
  * be a behavior change, which may causes issues.
  */
-enum acpi_backlight_type acpi_video_get_backlight_type(void)
+static enum acpi_backlight_type __acpi_video_get_backlight_type(bool native)
 {
static DEFINE_MUTEX(init_mutex);
+   static bool native_available;
static bool init_done;
static long video_caps;
 
@@ -593,6 +595,8 @@ enum acpi_backlight_type acpi_video_get_backlight_type(void)
backlight_notifier_registered = true;
init_done = true;
}
+   if (native)
+   native_available = true;
mutex_unlock(_mutex);
 
if (acpi_backlight_cmdline != acpi_backlight_undef)
@@ -604,13 +608,25 @@ enum acpi_backlight_type 
acpi_video_get_backlight_type(void)
if (!(video_caps & ACPI_VIDEO_BACKLIGHT))
return acpi_backlight_vendor;
 
-   if (acpi_osi_is_win8() && backlight_device_get_by_type(BACKLIGHT_RAW))
+   if (acpi_osi_is_win8() &&
+   (native_available || backlight_device_get_by_type(BACKLIGHT_RAW)))
return acpi_backlight_native;
 
return acpi_backlight_video;
 }
+
+enum acpi_backlight_type acpi_video_get_backlight_type(void)
+{
+   return __acpi_video_get_backlight_type(false);
+}
 EXPORT_SYMBOL(acpi_video_get_backlight_type);
 
+bool acpi_video_backlight_use_native(void)
+{
+   return __acpi_video_get_backlight_type(true) == acpi_backlight_native;
+}
+EXPORT_SYMBOL(acpi_video_backlight_use_native);
+
 /*
  * Set the preferred backlight interface type based on DMI info.
  * This function allows DMI blacklists to be implemented by external
diff --git a/include/acpi/video.h b/include/acpi/video.h
index db8548ff03ce..4705e339c252 100644
--- a/include/acpi/video.h
+++ b/include/acpi/video.h
@@ -56,6 +56,7 @@ extern void acpi_video_unregister(void);
 extern int acpi_video_get_edid(struct acpi_device *device, int type,
   int device_id, void **edid);
 extern enum acpi_backlight_type acpi_video_get_backlight_type(void);
+extern bool acpi_video_backlight_use_native(void);
 extern void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type);
 /

  1   2   3   >