On Fri, Aug 16, 2019 at 10:21:33PM +0200, Mark Kettenis wrote:
> The diff below provides a minimal implementation of some of the Linux
> ACPI iterfaces. Enough to allow us to compile the ACPI code for
> radeon(4) and amdgpu(4). With this diff the brightness keys on my HP
> laptop with:
>
> cpu0: AMD A4-4355M APU with Radeon(tm) HD Graphics, 1897.56 MHz, 15-10-01
> ...
> radeondrm0 at pci0 dev 1 function 0 "ATI Radeon HD 7400G" rev 0x00
>
> now work. I'd like to see some more tests, especially on laptops with
> amdgpu(4). Diff has some debug printing enabled. Feel free to share
> the dmesg output with me.
>
On my HP 735G5, this does not enable the brightness controls, but it does not
seem to regress anything, either. dmesg contains the following:
initializing kernel modesetting (RAVEN 0x1002:0x15DD 0x103C:0x83DA 0xD0).
[drm] ATCS version 1
[drm] Found ATIF handle \\_SB_.PCI0.BUSA.GFX0.ATIF
[drm] ATIF version 1
[drm] SYSTEM_PARAMS: mask = 0x106, flags = 0x107
[drm] Notification enabled, command code = 0xd0
amdgpu0: 1920x1080, 32bpp
wsdisplay0 at amdgpu0 mux 1: console (std, vt100 emulation), using wskbd0
wsdisplay0: screen 1-5 added (std, vt100 emulation)
xbacklight still reports:
No outputs have backlight property
-ml
>
> Index: dev/pci/drm/drm_drv.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/drm_drv.c,v
> retrieving revision 1.164
> diff -u -p -r1.164 drm_drv.c
> --- dev/pci/drm/drm_drv.c 30 Jul 2019 05:50:20 -0000 1.164
> +++ dev/pci/drm/drm_drv.c 16 Aug 2019 20:05:55 -0000
> @@ -55,6 +55,14 @@
> #include <uvm/uvm.h>
> #include <uvm/uvm_device.h>
>
> +#include <machine/bus.h>
> +
> +#ifdef __HAVE_ACPI
> +#include <dev/acpi/acpidev.h>
> +#include <dev/acpi/acpivar.h>
> +#include <dev/acpi/dsdt.h>
> +#endif
> +
> #include <drm/drmP.h>
> #include <drm/drm_gem.h>
> #include <uapi/drm/drm.h>
> @@ -76,7 +84,7 @@ struct drm_softc {
> #ifdef DRMDEBUG
> unsigned int drm_debug = DRM_UT_DRIVER | DRM_UT_KMS;
> #else
> -unsigned int drm_debug = 0;
> +unsigned int drm_debug = DRM_UT_DRIVER;
> #endif
>
> int drm_firstopen(struct drm_device *);
> @@ -256,6 +264,12 @@ drm_attach(struct device *parent, struct
> dev->bridgetag = da->bridgetag;
> dev->pdev->tag = da->tag;
> dev->pdev->pci = (struct pci_softc *)parent->dv_parent;
> +
> +#ifdef CONFIG_ACPI
> + dev->pdev->dev.node = acpi_find_pci(da->pc, da->tag);
> + aml_register_notify(dev->pdev->dev.node, NULL,
> + drm_linux_acpi_notify, NULL, ACPIDEV_NOPOLL);
> +#endif
>
> rw_init(&dev->struct_mutex, "drmdevlk");
> mtx_init(&dev->event_lock, IPL_TTY);
> Index: dev/pci/drm/drm_linux.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/drm_linux.c,v
> retrieving revision 1.47
> diff -u -p -r1.47 drm_linux.c
> --- dev/pci/drm/drm_linux.c 5 Aug 2019 08:35:59 -0000 1.47
> +++ dev/pci/drm/drm_linux.c 16 Aug 2019 20:05:55 -0000
> @@ -987,6 +987,8 @@ vga_put(struct pci_dev *pdev, int rsrc)
>
> #include <dev/acpi/acpireg.h>
> #include <dev/acpi/acpivar.h>
> +#include <dev/acpi/amltypes.h>
> +#include <dev/acpi/dsdt.h>
>
> acpi_status
> acpi_get_table(const char *sig, int instance,
> @@ -1008,6 +1010,131 @@ acpi_get_table(const char *sig, int inst
> }
>
> return AE_NOT_FOUND;
> +}
> +
> +acpi_status
> +acpi_get_handle(acpi_handle node, const char *name, acpi_handle *rnode)
> +{
> + node = aml_searchname(node, name);
> + if (node == NULL)
> + return AE_NOT_FOUND;
> +
> + *rnode = node;
> + return 0;
> +}
> +
> +acpi_status
> +acpi_get_name(acpi_handle node, int type, struct acpi_buffer *buffer)
> +{
> + KASSERT(buffer->length != ACPI_ALLOCATE_BUFFER);
> + KASSERT(type == ACPI_FULL_PATHNAME);
> + strlcpy(buffer->pointer, aml_nodename(node), buffer->length);
> + return 0;
> +}
> +
> +acpi_status
> +acpi_evaluate_object(acpi_handle node, const char *name,
> + struct acpi_object_list *params, struct acpi_buffer *result)
> +{
> + struct aml_value args[4], res;
> + union acpi_object *obj;
> + uint8_t *data;
> + int i;
> +
> + KASSERT(params->count <= nitems(args));
> +
> + for (i = 0; i < params->count; i++) {
> + args[i].type = params->pointer[i].type;
> + switch (args[i].type) {
> + case AML_OBJTYPE_INTEGER:
> + args[i].v_integer = params->pointer[i].integer.value;
> + break;
> + case AML_OBJTYPE_BUFFER:
> + args[i].length = params->pointer[i].buffer.length;
> + args[i].v_buffer = params->pointer[i].buffer.pointer;
> + break;
> + default:
> + printf("%s: arg type 0x%02x", __func__, args[i].type);
> + return AE_BAD_PARAMETER;
> + }
> + }
> +
> + if (name) {
> + node = aml_searchname(node, name);
> + if (node == NULL)
> + return AE_NOT_FOUND;
> + }
> + if (aml_evalnode(acpi_softc, node, params->count, args, &res)) {
> + aml_freevalue(&res);
> + return AE_ERROR;
> + }
> +
> + KASSERT(result->length == ACPI_ALLOCATE_BUFFER);
> +
> + result->length = sizeof(union acpi_object);
> + switch (res.type) {
> + case AML_OBJTYPE_BUFFER:
> + result->length += res.length;
> + result->pointer = malloc(result->length, M_DRM, M_WAITOK);
> + obj = (union acpi_object *)result->pointer;
> + data = (uint8_t *)(obj + 1);
> + obj->type = res.type;
> + obj->buffer.length = res.length;
> + obj->buffer.pointer = data;
> + memcpy(data, res.v_buffer, res.length);
> + break;
> + default:
> + printf("%s: return type 0x%02x", __func__, res.type);
> + aml_freevalue(&res);
> + return AE_ERROR;
> + }
> +
> + aml_freevalue(&res);
> + return 0;
> +}
> +
> +SLIST_HEAD(, notifier_block) drm_linux_acpi_notify_list =
> + SLIST_HEAD_INITIALIZER(drm_linux_acpi_notify_list);
> +
> +int
> +drm_linux_acpi_notify(struct aml_node *node, int notify, void *arg)
> +{
> + struct acpi_bus_event event;
> + struct notifier_block *nb;
> +
> + event.device_class = ACPI_VIDEO_CLASS;
> + event.type = notify;
> +
> + SLIST_FOREACH(nb, &drm_linux_acpi_notify_list, link)
> + nb->notifier_call(nb, 0, &event);
> + return 0;
> +}
> +
> +int
> +register_acpi_notifier(struct notifier_block *nb)
> +{
> + SLIST_INSERT_HEAD(&drm_linux_acpi_notify_list, nb, link);
> + return 0;
> +}
> +
> +int
> +unregister_acpi_notifier(struct notifier_block *nb)
> +{
> + SLIST_REMOVE(&drm_linux_acpi_notify_list, nb, notifier_block, link);
> + return 0;
> +}
> +
> +const char *
> +acpi_format_exception(acpi_status status)
> +{
> + switch (status) {
> + case AE_NOT_FOUND:
> + return "not found";
> + case AE_BAD_PARAMETER:
> + return "bad parameter";
> + default:
> + return "unknown";
> + }
> }
>
> #endif
> Index: dev/pci/drm/files.drm
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/files.drm,v
> retrieving revision 1.45
> diff -u -p -r1.45 files.drm
> --- dev/pci/drm/files.drm 21 May 2019 22:40:06 -0000 1.45
> +++ dev/pci/drm/files.drm 16 Aug 2019 20:05:55 -0000
> @@ -235,7 +235,7 @@ file dev/pci/drm/radeon/r600_cs.c
> rade
> file dev/pci/drm/radeon/r600_dma.c radeondrm
> file dev/pci/drm/radeon/r600_dpm.c radeondrm
> file dev/pci/drm/radeon/r600_hdmi.c radeondrm
> -#file dev/pci/drm/radeon/radeon_acpi.c radeondrm
> +file dev/pci/drm/radeon/radeon_acpi.c radeondrm
> file dev/pci/drm/radeon/radeon_agp.c radeondrm
> file dev/pci/drm/radeon/radeon_asic.c radeondrm
> file dev/pci/drm/radeon/radeon_atombios.c radeondrm
> @@ -518,7 +518,7 @@ file dev/pci/drm/amd/amdgpu/amdgpu_vce_v
>
> device amdgpu: drmbase, ttm, wsemuldisplaydev, rasops8, rasops32,
> i2cbus, i2c_bitbang, drm_sched, chash, powerplay, amddal
> attach amdgpu at pci
> -#file dev/pci/drm/amd/amdgpu/amdgpu_acpi.c amdgpu
> +file dev/pci/drm/amd/amdgpu/amdgpu_acpi.c amdgpu
> file dev/pci/drm/amd/amdgpu/amdgpu_afmt.c amdgpu
> file dev/pci/drm/amd/amdgpu/amdgpu_amdkfd.c amdgpu
> file dev/pci/drm/amd/amdgpu/amdgpu_atombios.c amdgpu
> Index: dev/pci/drm/amd/amdgpu/amdgpu_acpi.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/amd/amdgpu/amdgpu_acpi.c,v
> retrieving revision 1.2
> diff -u -p -r1.2 amdgpu_acpi.c
> --- dev/pci/drm/amd/amdgpu/amdgpu_acpi.c 11 Jun 2019 11:47:24 -0000
> 1.2
> +++ dev/pci/drm/amd/amdgpu/amdgpu_acpi.c 16 Aug 2019 20:05:55 -0000
> @@ -1,3 +1,4 @@
> +#define DRMDEBUG
> /*
> * Copyright 2012 Advanced Micro Devices, Inc.
> *
> Index: dev/pci/drm/amd/amdgpu/amdgpu_bios.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/amd/amdgpu/amdgpu_bios.c,v
> retrieving revision 1.1
> diff -u -p -r1.1 amdgpu_bios.c
> --- dev/pci/drm/amd/amdgpu/amdgpu_bios.c 21 May 2019 22:40:06 -0000
> 1.1
> +++ dev/pci/drm/amd/amdgpu/amdgpu_bios.c 16 Aug 2019 20:05:55 -0000
> @@ -37,10 +37,6 @@
> #include <dev/isa/isavar.h>
> #endif
>
> -#ifdef __HAVE_ACPI
> -#include "acpi.h"
> -#endif
> -
> /*
> * BIOS.
> */
> @@ -476,10 +472,6 @@ static bool amdgpu_read_disabled_bios(st
> else
> return amdgpu_asic_read_disabled_bios(adev);
> }
> -
> -#if NACPI > 0
> -#define CONFIG_ACPI
> -#endif
>
> #ifdef CONFIG_ACPI
> static bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
> Index: dev/pci/drm/i915/i915_drv.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/i915/i915_drv.h,v
> retrieving revision 1.82
> diff -u -p -r1.82 i915_drv.h
> --- dev/pci/drm/i915/i915_drv.h 4 May 2019 11:34:47 -0000 1.82
> +++ dev/pci/drm/i915/i915_drv.h 16 Aug 2019 20:05:56 -0000
> @@ -55,11 +55,6 @@
> #include <drm/drm_gem.h>
> #include <drm/drm_cache.h>
>
> -#include "acpi.h"
> -#if NACPI > 0
> -#define CONFIG_ACPI
> -#endif
> -
> #include "drm.h"
> #include "vga.h"
>
> Index: dev/pci/drm/include/drm/drmP.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/include/drm/drmP.h,v
> retrieving revision 1.4
> diff -u -p -r1.4 drmP.h
> --- dev/pci/drm/include/drm/drmP.h 14 Aug 2019 05:32:56 -0000 1.4
> +++ dev/pci/drm/include/drm/drmP.h 16 Aug 2019 20:05:56 -0000
> @@ -242,6 +242,7 @@ struct drm_attach_args {
> #define DRMDEVCF_PRIMARY_UNK -1
>
> void drm_linux_init(void);
> +int drm_linux_acpi_notify(struct aml_node *, int, void *);
>
> /* Device setup support (drm_drv.c) */
> int drm_pciprobe(struct pci_attach_args *, const struct drm_pcidev * );
> Index: dev/pci/drm/include/linux/acpi.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/include/linux/acpi.h,v
> retrieving revision 1.1
> diff -u -p -r1.1 acpi.h
> --- dev/pci/drm/include/linux/acpi.h 14 Apr 2019 10:14:53 -0000 1.1
> +++ dev/pci/drm/include/linux/acpi.h 16 Aug 2019 20:05:56 -0000
> @@ -13,13 +13,71 @@
>
> typedef size_t acpi_size;
> typedef int acpi_status;
> +typedef struct aml_node *acpi_handle;
> +
> +struct acpi_bus_event {
> + const char *device_class;
> + int type;
> +};
> +
> +struct acpi_buffer {
> + size_t length;
> + void *pointer;
> +};
> +
> +#define ACPI_ALLOCATE_BUFFER (size_t)-1
> +
> +union acpi_object {
> + int type;
> + struct {
> + int type;
> + uint64_t value;
> + } integer;
> + struct {
> + int type;
> + size_t length;
> + void *pointer;
> + } buffer;
> +};
> +
> +#define ACPI_TYPE_INTEGER 1
> +#define ACPI_TYPE_BUFFER 3
> +
> +struct acpi_object_list {
> + int count;
> + union acpi_object *pointer;
> +};
>
> struct acpi_table_header;
>
> #define ACPI_SUCCESS(x) ((x) == 0)
> +#define ACPI_FAILURE(x) ((x) != 0)
>
> -#define AE_NOT_FOUND 0x0005
> +#define AE_ERROR 1
> +#define AE_NOT_FOUND 2
> +#define AE_BAD_PARAMETER 3
>
> acpi_status acpi_get_table(const char *, int, struct acpi_table_header **);
> +
> +acpi_status acpi_evaluate_object(acpi_handle, const char *,
> + struct acpi_object_list *, struct acpi_buffer *);
> +
> +acpi_status acpi_get_handle(acpi_handle, const char *, acpi_handle *);
> +acpi_status acpi_get_name(acpi_handle, int, struct acpi_buffer *);
> +
> +#define ACPI_FULL_PATHNAME 1
> +
> +#define ACPI_VIDEO_CLASS "video"
> +
> +#define ACPI_VIDEO_NOTIFY_PROBE 0x81
> +
> +#define ACPI_HANDLE(x) ((x)->node)
> +
> +const char *acpi_format_exception(acpi_status);
> +
> +struct notifier_block;
> +
> +int register_acpi_notifier(struct notifier_block *);
> +int unregister_acpi_notifier(struct notifier_block *);
>
> #endif
> Index: dev/pci/drm/include/linux/backlight.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/include/linux/backlight.h,v
> retrieving revision 1.1
> diff -u -p -r1.1 backlight.h
> --- dev/pci/drm/include/linux/backlight.h 14 Apr 2019 10:14:53 -0000
> 1.1
> +++ dev/pci/drm/include/linux/backlight.h 16 Aug 2019 20:05:56 -0000
> @@ -31,6 +31,8 @@ struct backlight_device {
> #define BACKLIGHT_RAW 0
> #define BACKLIGHT_FIRMWARE 1
>
> +#define BACKLIGHT_UPDATE_HOTKEY 0
> +
> struct backlight_device *backlight_device_register(const char *, void *,
> void *, const struct backlight_ops *, struct backlight_properties *);
> void backlight_device_unregister(struct backlight_device *);
> @@ -39,6 +41,12 @@ static inline void
> backlight_update_status(struct backlight_device *bd)
> {
> bd->ops->update_status(bd);
> +}
> +
> +static inline void
> +backlight_force_update(struct backlight_device *bd, int reason)
> +{
> + bd->props.brightness = bd->ops->get_brightness(bd);
> }
>
> void backlight_schedule_update_status(struct backlight_device *);
> Index: dev/pci/drm/include/linux/kconfig.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/include/linux/kconfig.h,v
> retrieving revision 1.4
> diff -u -p -r1.4 kconfig.h
> --- dev/pci/drm/include/linux/kconfig.h 14 Aug 2019 05:32:56 -0000
> 1.4
> +++ dev/pci/drm/include/linux/kconfig.h 16 Aug 2019 20:05:56 -0000
> @@ -3,8 +3,7 @@
> #ifndef _LINUX_KCONFIG_H
> #define _LINUX_KCONFIG_H
>
> -#include "agp.h"
> -
> +#include <sys/param.h>
> #include <sys/endian.h>
>
> #define IS_ENABLED(x) x - 0
> @@ -34,6 +33,14 @@
> #define __LITTLE_ENDIAN
> #endif
>
> +#ifdef __HAVE_ACPI
> +#include <acpi.h>
> +#if NACPI > 0
> +#define CONFIG_ACPI 1
> +#endif
> +#endif
> +
> +#include <agp.h>
> #if NAGP > 0
> #define CONFIG_AGP 1
> #endif
> Index: dev/pci/drm/include/linux/notifier.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/include/linux/notifier.h,v
> retrieving revision 1.1
> diff -u -p -r1.1 notifier.h
> --- dev/pci/drm/include/linux/notifier.h 14 Apr 2019 10:14:53 -0000
> 1.1
> +++ dev/pci/drm/include/linux/notifier.h 16 Aug 2019 20:05:56 -0000
> @@ -4,7 +4,8 @@
> #define _LINUX_NOTIFIER_H
>
> struct notifier_block {
> - void *notifier_call;
> + int (*notifier_call)(struct notifier_block *, unsigned long, void *);
> + SLIST_ENTRY(notifier_block) link;
> };
>
> #define ATOMIC_INIT_NOTIFIER_HEAD(x)
> Index: dev/pci/drm/include/linux/pci.h
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/include/linux/pci.h,v
> retrieving revision 1.2
> diff -u -p -r1.2 pci.h
> --- dev/pci/drm/include/linux/pci.h 15 Jul 2019 03:35:23 -0000 1.2
> +++ dev/pci/drm/include/linux/pci.h 16 Aug 2019 20:05:56 -0000
> @@ -39,6 +39,10 @@ struct pci_bus {
> struct pci_dev *self;
> };
>
> +struct pci_acpi {
> + struct aml_node *node;
> +};
> +
> struct pci_dev {
> struct pci_bus _bus;
> struct pci_bus *bus;
> @@ -57,6 +61,8 @@ struct pci_dev {
> int irq;
> int msi_enabled;
> uint8_t no_64bit_msi;
> +
> + struct pci_acpi dev;
> };
> #define PCI_ANY_ID (uint16_t) (~0U)
>
> @@ -296,6 +302,17 @@ pci_dma_mapping_error(struct pci_dev *pd
>
> #define pci_set_dma_mask(x, y) 0
> #define pci_set_consistent_dma_mask(x, y) 0
> +
> +static inline struct pci_dev *
> +pci_get_class(pcireg_t class, struct pci_dev *pdev)
> +{
> + return NULL;
> +}
> +
> +#define PCI_CLASS_DISPLAY_VGA \
> + (PCI_CLASS_DISPLAY | PCI_SUBCLASS_DISPLAY_VGA)
> +#define PCI_CLASS_DISPLAY_OTHER \
> + (PCI_CLASS_DISPLAY | PCI_SUBCLASS_DISPLAY_MISC)
>
> #endif /* defined(__amd64__) || defined(__i386__) */
>
> Index: dev/pci/drm/radeon/radeon_acpi.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/radeon/radeon_acpi.c,v
> retrieving revision 1.6
> diff -u -p -r1.6 radeon_acpi.c
> --- dev/pci/drm/radeon/radeon_acpi.c 14 Apr 2019 10:14:54 -0000 1.6
> +++ dev/pci/drm/radeon/radeon_acpi.c 16 Aug 2019 20:05:56 -0000
> @@ -1,3 +1,4 @@
> +#define DRMDEBUG
> /*
> * Copyright 2012 Advanced Micro Devices, Inc.
> *
> Index: dev/pci/drm/radeon/radeon_bios.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/pci/drm/radeon/radeon_bios.c,v
> retrieving revision 1.15
> diff -u -p -r1.15 radeon_bios.c
> --- dev/pci/drm/radeon/radeon_bios.c 14 Apr 2019 10:14:54 -0000 1.15
> +++ dev/pci/drm/radeon/radeon_bios.c 16 Aug 2019 20:05:56 -0000
> @@ -42,10 +42,6 @@
> #include <machine/autoconf.h>
> #endif
>
> -#ifdef __HAVE_ACPI
> -#include "acpi.h"
> -#endif
> -
> /*
> * BIOS.
> */
> @@ -737,10 +733,6 @@ static bool radeon_read_disabled_bios(st
> else
> return legacy_read_disabled_bios(rdev);
> }
> -
> -#if NACPI > 0
> -#define CONFIG_ACPI
> -#endif
>
> #ifdef CONFIG_ACPI
> static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
>