diff mbox

drm/radeon: add new AMD ACPI header and update relevant code

Message ID 20120729193307.GA5512@growl (mailing list archive)
State New, archived
Headers show

Commit Message

Luca Tettamanti July 29, 2012, 7:33 p.m. UTC
Hi,
I'm attaching a first draft of my work. The first 3 patches are
infrastructure work, the fourth wires the notification handler and
retrieves the requests from the system BIOS, but it does not actually
change brightness yet.

The problem here is how to get the correct encoder: should I just scan
encoder_list checking for ATOM_DEVICE_LCD_SUPPORT and see if it has a
backlight device attached?
Hopefully there is only one encoder with it, right?

I'm also toying with the idea of creating structures matching the output
of the various ACPI methods, this would remove some ugly pointer
arithmetics, but it _might_ make it easier to read past the buffer if
one does not check the size before using the struct. What do you think?

Luca

Comments

Alex Deucher July 30, 2012, 2:29 p.m. UTC | #1
On Sun, Jul 29, 2012 at 3:33 PM, Luca Tettamanti <kronos.it@gmail.com> wrote:
> Hi,
> I'm attaching a first draft of my work. The first 3 patches are
> infrastructure work, the fourth wires the notification handler and
> retrieves the requests from the system BIOS, but it does not actually
> change brightness yet.
>
> The problem here is how to get the correct encoder: should I just scan
> encoder_list checking for ATOM_DEVICE_LCD_SUPPORT and see if it has a
> backlight device attached?

Yeah, that should work.

> Hopefully there is only one encoder with it, right?

There's only one backlight controller and there should only be one
encoder with it enabled on it.

>
> I'm also toying with the idea of creating structures matching the output
> of the various ACPI methods, this would remove some ugly pointer
> arithmetics, but it _might_ make it easier to read past the buffer if
> one does not check the size before using the struct. What do you think?

That's fine with me.  We do something similar with atombios structs.
Also, feel free to add stuff to radeon_acpi.h if you think it's
useful.

Alex
diff mbox

Patch

From 29937c81f1449d136c85145ceeeb7de24bfcc4c8 Mon Sep 17 00:00:00 2001
From: Luca Tettamanti <kronos.it@gmail.com>
Date: Sun, 29 Jul 2012 21:00:51 +0200
Subject: [PATCH 4/4] drm/radeon: implement skeleton handler for ACPI events

Signed-off-by: Luca Tettamanti <kronos.it@gmail.com>
---
 drivers/gpu/drm/radeon/radeon_acpi.c |   72 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/radeon/radeon_acpi.h |    5 +++
 drivers/gpu/drm/radeon/radeon_pm.c   |    4 +-
 3 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c
index 94f8255..8b1fed7 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.c
+++ b/drivers/gpu/drm/radeon/radeon_acpi.c
@@ -18,6 +18,11 @@ 
 #define ATIF_NOTIFICATION_81	1
 #define ATIF_NOTIFICATION_N	2
 
+struct radeon_atif_sbios_requests {
+	bool brightness_change;
+	int brightness_target;
+};
+
 /* Call the ATIF method
  */
 static union acpi_object* radeon_atif_call(acpi_handle handle, int function)
@@ -152,6 +157,73 @@  out:
 	return err;
 }
 
+static int radeon_atif_get_sbios_requests(acpi_handle handle,
+		struct radeon_atif_sbios_requests *req)
+{
+	union acpi_object *info;
+	void *buffer;
+	u16 size;
+	u32 pending;
+	int count = 0;
+
+	memset(req, 0, sizeof(*req));
+
+	info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS);
+	if (!info)
+		return -EIO;
+
+	buffer = info->buffer.pointer;
+
+	size = *(u16 *)buffer;
+	if (size < 0xd) {
+		count = -EINVAL;
+		goto out;
+	}
+
+	pending = *(u32 *)(buffer + 2);
+
+	if (pending & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED) {
+		count++;
+		req->brightness_change = true;
+		req->brightness_target = *(u8 *)(buffer + 12);
+	}
+
+	/* TODO check other requests */
+
+out:
+	kfree(info);
+	return count;
+}
+
+int radeon_atif_handler(struct radeon_device *rdev, struct acpi_bus_event *event)
+{
+	struct radeon_atif *atif = &rdev->atif;
+	struct radeon_atif_sbios_requests req;
+	acpi_handle handle;
+	int count;
+
+	if (!atif->notification_cfg.enabled ||
+			event->type != atif->notification_cfg.command_code)
+		/* Not our event */
+		return NOTIFY_DONE;
+
+	/* Check pending SBIOS requests */
+	handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev);
+	count = radeon_atif_get_sbios_requests(handle, &req);
+
+	if (count <= 0)
+		return NOTIFY_DONE;
+
+	DRM_DEBUG_DRIVER("ATIF: %d pending SBIOS requests\n", count);
+
+	if (req.brightness_change) {
+		/* TODO */
+		printk(KERN_INFO "Changing brightness to %d\n", req.brightness_target);
+	}
+
+	return NOTIFY_OK;
+}
+
 /* Call all ACPI methods here */
 int radeon_acpi_init(struct radeon_device *rdev)
 {
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.h b/drivers/gpu/drm/radeon/radeon_acpi.h
index a42288d..513894e 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.h
+++ b/drivers/gpu/drm/radeon/radeon_acpi.h
@@ -24,6 +24,11 @@ 
 #ifndef RADEON_ACPI_H
 #define RADEON_ACPI_H
 
+struct radeon_device;
+struct acpi_bus_event;
+
+int radeon_atif_handler(struct radeon_device *rdev, struct acpi_bus_event *event);
+
 /* AMD hw uses four ACPI control methods:
  * 1. ATIF
  * ARG0: (ACPI_INTEGER) function code
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 5b37e28..8621748 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -22,6 +22,7 @@ 
  */
 #include "drmP.h"
 #include "radeon.h"
+#include "radeon_acpi.h"
 #include "avivod.h"
 #include "atom.h"
 #ifdef CONFIG_ACPI
@@ -95,7 +96,8 @@  static int radeon_acpi_event(struct notifier_block *nb,
 		}
 	}
 
-	return NOTIFY_OK;
+	/* Check for pending SBIOS requests */
+	return radeon_atif_handler(rdev, entry);
 }
 #endif
 
-- 
1.7.10.4