[PATCH] drm/nouveau/acpi: de-dup use of DSM methods
Dave Airlie
airlied at gmail.com
Thu Aug 1 22:58:38 PDT 2013
On Fri, Aug 2, 2013 at 12:41 AM, Peter Wu <lekensteyn at gmail.com> wrote:
> Observe that nouveau_optimus_dsm and nouveau_dsm are equal except for
> the parameters handling (UUID, revision ID and function arguments). The
> function arguments are passed as Buffer in the "optimus dsm" and Integer
> in "nvidia dsm". As buffers are implicitly converted to integers, merge
> both functions.
>
> The ACPI spec defines the fourth parameter (Arg3 a.k.a. "function
> arguments") as Package, but many BIOSes expect a Buffer instead. For
> instance, for the "nvidia DSM", the Lenovo T410s uses CreateByteField on
> Arg3 which does not work with a package. The Clevo B7130 does something
> similar for the "Optimus DSM". Unfortunately, this means that the
> following ACPI warning (introduced with 29a241c) cannot be fixed (when
> toggling power or muxing):
By cannot be fixed, why is it there then? maybe ask the ACPI folks to
drop this error, since as far as I can see all optimus dsm want a
buffer here.
Dave.
>
> ACPI Warning: \_SB_.PCI0.GFX0._DSM: Argument #4 type mismatch - Found [Buffer], ACPI requires [Package] (20130517/nsarguments-95)
> ACPI Warning: \_SB_.PCI0.GFX0._DSM: Argument #4 type mismatch - Found [Buffer], ACPI requires [Package] (20130517/nsarguments-95)
> ACPI Warning: \_SB_.PCI0.P0P2.PEGP._DSM: Argument #4 type mismatch - Found [Buffer], ACPI requires [Package] (20130517/nsarguments-95)
> ACPI Warning: \_SB_.PCI0.P0P2.PEGP._DSM: Argument #4 type mismatch - Found [Buffer], ACPI requires [Package] (20130517/nsarguments-95)
>
> Signed-off-by: Peter Wu <lekensteyn at gmail.com>
> ---
> drivers/gpu/drm/nouveau/nouveau_acpi.c | 67 ++++++++++------------------------
> 1 file changed, 20 insertions(+), 47 deletions(-)
>
> diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
> index d97f200..a75684f 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
> @@ -46,6 +46,9 @@ bool nouveau_is_v1_dsm(void) {
> #define NOUVEAU_DSM_HAS_MUX 0x1
> #define NOUVEAU_DSM_HAS_OPT 0x2
>
> +#define NOUVEAU_DSM_REVID_NVIDIA 0x102
> +#define NOUVEAU_DSM_REVID_OPTIMUS 0x100
> +
> static const char nouveau_dsm_muid[] = {
> 0xA0, 0xA0, 0x95, 0x9D, 0x60, 0x00, 0x48, 0x4D,
> 0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4,
> @@ -56,7 +59,8 @@ static const char nouveau_op_dsm_muid[] = {
> 0xA7, 0x2B, 0x60, 0x42, 0xA6, 0xB5, 0xBE, 0xE0,
> };
>
> -static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *result)
> +static int nouveau_call_dsm(acpi_handle handle, const char *uuid, int revid,
> + int func, int arg, uint32_t *result)
> {
> struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
> struct acpi_object_list input;
> @@ -68,12 +72,15 @@ static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *
> input.count = 4;
> input.pointer = params;
> params[0].type = ACPI_TYPE_BUFFER;
> - params[0].buffer.length = sizeof(nouveau_op_dsm_muid);
> - params[0].buffer.pointer = (char *)nouveau_op_dsm_muid;
> + params[0].buffer.length = 16;
> + params[0].buffer.pointer = (char *)uuid;
> params[1].type = ACPI_TYPE_INTEGER;
> - params[1].integer.value = 0x00000100;
> + params[1].integer.value = revid;
> params[2].type = ACPI_TYPE_INTEGER;
> params[2].integer.value = func;
> + /* Although the ACPI spec defines Arg3 as a Package, in practise
> + * implementations expect a Buffer (CreateWordField and Index functions
> + * are applied to it). */
> params[3].type = ACPI_TYPE_BUFFER;
> params[3].buffer.length = 4;
> /* ACPI is little endian, AABBCCDD becomes {DD,CC,BB,AA} */
> @@ -108,50 +115,16 @@ static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *
> return 0;
> }
>
> -static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result)
> -{
> - struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
> - struct acpi_object_list input;
> - union acpi_object params[4];
> - union acpi_object *obj;
> - int err;
> -
> - input.count = 4;
> - input.pointer = params;
> - params[0].type = ACPI_TYPE_BUFFER;
> - params[0].buffer.length = sizeof(nouveau_dsm_muid);
> - params[0].buffer.pointer = (char *)nouveau_dsm_muid;
> - params[1].type = ACPI_TYPE_INTEGER;
> - params[1].integer.value = 0x00000102;
> - params[2].type = ACPI_TYPE_INTEGER;
> - params[2].integer.value = func;
> - params[3].type = ACPI_TYPE_INTEGER;
> - params[3].integer.value = arg;
> -
> - err = acpi_evaluate_object(handle, "_DSM", &input, &output);
> - if (err) {
> - printk(KERN_INFO "failed to evaluate _DSM: %d\n", err);
> - return err;
> - }
> -
> - obj = (union acpi_object *)output.pointer;
> -
> - if (obj->type == ACPI_TYPE_INTEGER)
> - if (obj->integer.value == 0x80000002)
> - return -ENODEV;
> -
> - if (obj->type == ACPI_TYPE_BUFFER) {
> - if (obj->buffer.length == 4 && result) {
> - *result = 0;
> - *result |= obj->buffer.pointer[0];
> - *result |= (obj->buffer.pointer[1] << 8);
> - *result |= (obj->buffer.pointer[2] << 16);
> - *result |= (obj->buffer.pointer[3] << 24);
> - }
> - }
> +static int nouveau_optimus_dsm(acpi_handle handle, int func,
> + int arg, uint32_t *result) {
> + return nouveau_call_dsm(handle, nouveau_op_dsm_muid,
> + NOUVEAU_DSM_REVID_OPTIMUS, func, arg, result);
> +}
>
> - kfree(output.pointer);
> - return 0;
> +static int nouveau_dsm(acpi_handle handle, int func,
> + int arg, uint32_t *result) {
> + return nouveau_call_dsm(handle, nouveau_dsm_muid,
> + NOUVEAU_DSM_REVID_NVIDIA, func, arg, result);
> }
>
> /* Returns 1 if a DSM function is usable and 0 otherwise */
> --
> 1.8.3.4
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
More information about the dri-devel
mailing list