Patchwork [08/12] drm/radeon: implement wrapper for GET_SYSTEM_PARAMS

login
register
mail settings
Submitter Alex Hung
Date Feb. 5, 2013, 7:06 p.m.
Message ID <1360091193-12323-9-git-send-email-alex.hung@canonical.com>
Download mbox | patch
Permalink /patch/218565/
State New
Headers show

Comments

Alex Hung - Feb. 5, 2013, 7:06 p.m.
From: Luca Tettamanti <kronos.it@gmail.com>

Use GET_SYSTEM_PARAMS for retrieving the configuration for the system
BIOS notifications.
v2: packed struct (Lee, Chun-Yi <jlee@suse.com>)
v3: fix enable with device specific command code

Signed-off-by: Luca Tettamanti <kronos.it@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
 drivers/gpu/drm/radeon/radeon_acpi.c |   85 +++++++++++++++++++++++++++++++++-
 1 file changed, 83 insertions(+), 2 deletions(-)

Patch

diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c
index 2f6cef2..0454ecc 100644
--- a/drivers/gpu/drm/radeon/radeon_acpi.c
+++ b/drivers/gpu/drm/radeon/radeon_acpi.c
@@ -43,6 +43,18 @@  struct atif_verify_interface {
 	u32 function_bits;	/* supported functions bit vector */
 } __packed;
 
+struct atif_system_params {
+	u16 size;
+	u32 valid_mask;
+	u32 flags;
+	u8 command_code;
+} __packed;
+
+#define ATIF_NOTIFY_MASK	0x3
+#define ATIF_NOTIFY_NONE	0
+#define ATIF_NOTIFY_81		1
+#define ATIF_NOTIFY_N		2
+
 /* Call the ATIF method
  */
 static union acpi_object *radeon_atif_call(acpi_handle handle, int function,
@@ -144,10 +156,57 @@  out:
 	return err;
 }
 
+static int radeon_atif_get_notification_params(acpi_handle handle,
+		struct radeon_atif_notification_cfg *n)
+{
+	union acpi_object *info;
+	struct atif_system_params params;
+	size_t size;
+	int err = 0;
+
+	info = radeon_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL);
+	if (!info) {
+		err = -EIO;
+		goto out;
+	}
+
+	size = *(u16 *) info->buffer.pointer;
+	if (size < 10) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	memset(&params, 0, sizeof(params));
+	size = min(sizeof(params), size);
+	memcpy(&params, info->buffer.pointer, size);
+
+	params.flags = params.flags & params.valid_mask;
+
+	if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_NONE) {
+		n->enabled = false;
+		n->command_code = 0;
+	} else if ((params.flags & ATIF_NOTIFY_MASK) == ATIF_NOTIFY_81) {
+		n->enabled = true;
+		n->command_code = 0x81;
+	} else {
+		if (size < 11) {
+			err = -EINVAL;
+			goto out;
+		}
+		n->enabled = true;
+		n->command_code = params.command_code;
+	}
+
+out:
+	kfree(info);
+	return err;
+}
+
 /* Call all ACPI methods here */
 int radeon_acpi_init(struct radeon_device *rdev)
 {
 	acpi_handle handle;
+	struct radeon_atif *atif = &rdev->atif;
 	int ret;
 
 	/* Get the device handle */
@@ -158,10 +217,32 @@  int radeon_acpi_init(struct radeon_device *rdev)
 		return 0;
 
 	/* Call the ATIF method */
-	ret = radeon_atif_verify_interface(handle, &rdev->atif);
-	if (ret)
+	ret = radeon_atif_verify_interface(handle, atif);
+	if (ret) {
 		DRM_DEBUG_DRIVER("Call to verify_interface failed: %d\n", ret);
+		goto out;
+	}
+
+	if (atif->functions.sbios_requests && !atif->functions.system_params) {
+		/* XXX check this workraround, if sbios request function is
+		 * present we have to see how it's configured in the system
+		 * params
+		 */
+		atif->functions.system_params = true;
+	}
+
+	if (atif->functions.system_params) {
+		ret = radeon_atif_get_notification_params(handle,
+				&atif->notification_cfg);
+		if (ret) {
+			DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n",
+					ret);
+			/* Disable notification */
+			atif->notification_cfg.enabled = false;
+		}
+	}
 
+out:
 	return ret;
 }