From patchwork Thu Aug 1 14:41:37 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Wu X-Patchwork-Id: 2837524 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 28BB39F3B8 for ; Fri, 2 Aug 2013 05:55:34 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1835C2021F for ; Fri, 2 Aug 2013 05:55:33 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 12E4E20171 for ; Fri, 2 Aug 2013 05:55:32 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E3398E6410 for ; Thu, 1 Aug 2013 22:55:31 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-ee0-f54.google.com (mail-ee0-f54.google.com [74.125.83.54]) by gabe.freedesktop.org (Postfix) with ESMTP id 4E9B3E7B4B for ; Thu, 1 Aug 2013 07:41:42 -0700 (PDT) Received: by mail-ee0-f54.google.com with SMTP id e53so1062876eek.13 for ; Thu, 01 Aug 2013 07:41:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer; bh=2YKXPzPf/ixqzq07lci1h4qGATQudkDfqzoHgDxUXUw=; b=xB3hbNnGiGHtdeaIlTZZxZdlFPq4vfR17s8vt45Uh9DG3vGwIsiaf5FuM7MNsniSqv vMWgrGzhhQjQLfRaT5Ws/4cVEaZcJvmgu8WgSYeHG4TyH3MUi3cZDYKarb0Ow/wJlMwZ gxIoYwoSCvKhzCk3tQpjvo5+YNKtoLgYpE6fbmyT105e60e0feJy+JfaLvjoN+bxPJxg 8fjF4K6WXZVHcOmrlz6phzLvM19EGxGXgNnEtG1/5U+KV7NrIVpYCAMbzD/OZ0XwAT3M n+0M7e559c6XUsrsb8LT5XHeRrlaCU1ugk/GBItYhThJ+T7/hCYNIO/sdyG7qaxYqrjO TpDA== X-Received: by 10.14.69.206 with SMTP id n54mr1683133eed.118.1375368101565; Thu, 01 Aug 2013 07:41:41 -0700 (PDT) Received: from localhost.localdomain (ip4da018ae.direct-adsl.nl. [77.160.24.174]) by mx.google.com with ESMTPSA id n42sm4774820eeh.15.2013.08.01.07.41.39 for (version=TLSv1.2 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 01 Aug 2013 07:41:40 -0700 (PDT) From: Peter Wu To: Dave Airlie Subject: [PATCH] drm/nouveau/acpi: de-dup use of DSM methods Date: Thu, 1 Aug 2013 16:41:37 +0200 Message-Id: <1375368097-3223-1-git-send-email-lekensteyn@gmail.com> X-Mailer: git-send-email 1.8.3.4 X-Mailman-Approved-At: Thu, 01 Aug 2013 22:42:52 -0700 Cc: Peter Wu , dri-devel@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org X-Spam-Status: No, score=-5.5 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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): 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 --- 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 */