diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 1d6f8b2401..539a4f43bb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -786,6 +786,7 @@ struct amdgpu_device { int rio_rid; int rio_type; struct resource *rio_res; + eventhandler_tag power_evh; #endif struct amdgpu_doorbell doorbell; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c index 9fc1289692..62fbae1177 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c @@ -444,7 +444,6 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev, DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count); - /* todo: add DC handling */ if ((req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) && !amdgpu_device_has_dc_support(adev)) { struct amdgpu_encoder *enc = atif->encoder_for_bl; @@ -463,6 +462,34 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev, #endif } } +#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) + if ((req.pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST) && + amdgpu_device_has_dc_support(adev)) { + struct amdgpu_display_manager *dm = &adev->dm; + struct backlight_device *bd = dm->backlight_dev; + + if (bd) { + DRM_DEBUG_DRIVER("Changing brightness to %d\n", + req.backlight_level); + + /* + * Newer Linux has + * backlight_device_set_brightness, but it is + * hardwired to post BACKLIGHT_UPDATE_SYSFS. + */ + mutex_lock(&bd->ops_lock); + if (bd->ops && + req.backlight_level <= bd->props.max_brightness) { + bd->props.brightness = req.backlight_level; + backlight_update_status(bd); + } + mutex_unlock(&bd->ops_lock); +#if 0 + backlight_generate_event(bd, BACKLIGHT_UPDATE_HOTKEY); +#endif + } + } +#endif if (req.pending & ATIF_DGPU_DISPLAY_EVENT) { if ((adev->flags & AMD_IS_PX) && amdgpu_atpx_dgpu_req_power_for_displays()) { @@ -728,6 +755,7 @@ int amdgpu_acpi_pcie_performance_request(struct amdgpu_device *adev, return 0; } +#ifdef __linux__ /** * amdgpu_acpi_event - handle notify events * @@ -758,6 +786,32 @@ static int amdgpu_acpi_event(struct notifier_block *nb, /* Check for pending SBIOS requests */ return amdgpu_atif_handler(adev, entry); } +#else +static void amdgpu_acpi_event(acpi_handle handle, UINT32 notify, void *context) +{ + struct amdgpu_device *adev = context; + struct acpi_bus_event entry = { 0 }; + + DRM_DEBUG_DRIVER("notify 0x%02x\n", notify); + entry.type = notify; + strcpy(entry.device_class, ACPI_VIDEO_CLASS); + + /* Check for pending SBIOS requests */ + (void)amdgpu_atif_handler(adev, &entry); +} + +static void amdgpu_power_event(void *context) +{ + struct amdgpu_device *adev = context; + + if (power_supply_is_system_supplied() > 0) + DRM_DEBUG_DRIVER("pm: AC\n"); + else + DRM_DEBUG_DRIVER("pm: DC\n"); + + amdgpu_pm_acpi_event_handler(adev); +} +#endif /* Call all ACPI methods here */ /** @@ -858,8 +912,20 @@ int amdgpu_acpi_init(struct amdgpu_device *adev) } out: +#ifdef __linux__ adev->acpi_nb.notifier_call = amdgpu_acpi_event; register_acpi_notifier(&adev->acpi_nb); +#else + { + acpi_status status; + + status = AcpiInstallNotifyHandler(handle, ACPI_DEVICE_NOTIFY, + amdgpu_acpi_event, adev); + DRM_DEBUG_DRIVER("AcpiInstallNotifyHandler: %d\n", status); + adev->power_evh = EVENTHANDLER_REGISTER(power_profile_change, + amdgpu_power_event, adev, 0); + } +#endif return ret; } @@ -885,6 +951,20 @@ void amdgpu_acpi_get_backlight_caps(struct amdgpu_device *adev, */ void amdgpu_acpi_fini(struct amdgpu_device *adev) { +#ifdef __linux__ unregister_acpi_notifier(&adev->acpi_nb); +#else + acpi_handle handle; + + handle = ACPI_HANDLE(&adev->pdev->dev); + if (handle) { + AcpiRemoveNotifyHandler(handle, ACPI_DEVICE_NOTIFY, + amdgpu_acpi_event); + } + if (adev->power_evh) { + EVENTHANDLER_DEREGISTER(power_profile_change, + adev->power_evh); + } +#endif kfree(adev->atif); } diff --git a/linuxkpi/Makefile b/linuxkpi/Makefile index c5c12947a9..c316e819b8 100644 --- a/linuxkpi/Makefile +++ b/linuxkpi/Makefile @@ -33,11 +33,13 @@ SRCS= linux_kmod_gplv2.c \ .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "aarch64" SRCS+= linux_acpi.c \ + linux_bsd_acpi.c\ linux_video.c \ opt_acpi.h .endif -SRCS+= bus_if.h \ +SRCS+= acpi_if.h \ + bus_if.h \ device_if.h \ pci_if.h \ pci_iov_if.h \ diff --git a/linuxkpi/gplv2/include/acpi/acpi_bus.h b/linuxkpi/gplv2/include/acpi/acpi_bus.h index 617014f6b9..1f91021ec4 100644 --- a/linuxkpi/gplv2/include/acpi/acpi_bus.h +++ b/linuxkpi/gplv2/include/acpi/acpi_bus.h @@ -653,4 +653,6 @@ static inline int unregister_acpi_bus_type(void *bus) { return 0; } #endif /* CONFIG_ACPI */ +acpi_handle acpi_bsd_get_handle(struct device *dev); + #endif /*__ACPI_BUS_H__*/ diff --git a/linuxkpi/gplv2/include/linux/acpi.h b/linuxkpi/gplv2/include/linux/acpi.h index 6a8ed6b802..c918033c0d 100644 --- a/linuxkpi/gplv2/include/linux/acpi.h +++ b/linuxkpi/gplv2/include/linux/acpi.h @@ -40,8 +40,13 @@ static inline acpi_handle acpi_device_handle(struct acpi_device *adev) } #define ACPI_COMPANION(dev) to_acpi_device_node((dev)->fwnode) +#if 0 #define ACPI_HANDLE_GET(dev) acpi_device_handle(ACPI_COMPANION(dev)) #define ACPI_HANDLE(dev) acpi_device_handle(ACPI_COMPANION(dev)) +#else +#define ACPI_HANDLE_GET(dev) acpi_bsd_get_handle(dev) +#define ACPI_HANDLE(dev) acpi_bsd_get_handle(dev) +#endif #define ACPI_VIDEO_OUTPUT_SWITCHING 0x0001 #define ACPI_VIDEO_DEVICE_POSTING 0x0002 diff --git a/linuxkpi/gplv2/include/linux/power_supply.h b/linuxkpi/gplv2/include/linux/power_supply.h index a0cda78f52..71d8d5a7ee 100644 --- a/linuxkpi/gplv2/include/linux/power_supply.h +++ b/linuxkpi/gplv2/include/linux/power_supply.h @@ -1,8 +1,12 @@ #ifndef _LINUX_POWER_SUPPLY_H_ #define _LINUX_POWER_SUPPLY_H_ -#include +#include +#include -static inline int power_supply_is_system_supplied(void) { return -ENOSYS; } +static inline int power_supply_is_system_supplied(void) +{ + return (power_profile_get_state() == POWER_PROFILE_PERFORMANCE); +} #endif diff --git a/linuxkpi/gplv2/src/linux_bsd_acpi.c b/linuxkpi/gplv2/src/linux_bsd_acpi.c new file mode 100644 index 0000000000..7b4d94d011 --- /dev/null +++ b/linuxkpi/gplv2/src/linux_bsd_acpi.c @@ -0,0 +1,13 @@ + +#include +#include +#include + +extern ACPI_HANDLE acpi_bsd_get_handle(struct device *dev); + +ACPI_HANDLE +acpi_bsd_get_handle(struct device *dev) +{ + return (acpi_get_handle(dev->bsddev)); +} +