aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/radeon/radeon_acpi.c
diff options
context:
space:
mode:
authorLuca Tettamanti <kronos.it@gmail.com>2012-07-30 21:16:06 +0200
committerAlex Deucher <alexander.deucher@amd.com>2012-09-20 13:10:35 -0400
commitce3cf821a31f9824eda788cbd3e710d8047e82df (patch)
treef619907dabc0db1a48f41f9b4bcc3eaf44e2f97a /drivers/gpu/drm/radeon/radeon_acpi.c
parentfd64ca8a9d9d7e92fc81fe0b23dcf324246fd356 (diff)
drm/radeon: implement wrapper for GET_SYSTEM_PARAMS
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>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_acpi.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_acpi.c85
1 files changed, 83 insertions, 2 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_acpi.c b/drivers/gpu/drm/radeon/radeon_acpi.c
index 2f6cef2acad..0454eccc9c0 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;
}