From ce3cf821a31f9824eda788cbd3e710d8047e82df Mon Sep 17 00:00:00 2001 From: Luca Tettamanti Date: Mon, 30 Jul 2012 21:16:06 +0200 Subject: 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 ) v3: fix enable with device specific command code Signed-off-by: Luca Tettamanti Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_acpi.c | 85 +++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/radeon/radeon_acpi.c') 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(¶ms, 0, sizeof(params)); + size = min(sizeof(params), size); + memcpy(¶ms, 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; } -- cgit v1.1