[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