← Back to team overview

hybrid-graphics-linux team mailing list archive

Asus UL30VT

 

I've been trying to get hybrid graphics switching working on an Asus
UL30VT (i915/g210m).  With Dave's latest tree and the attached patch
(sorry, not used to sending patches via gmail), I can switch between
and power off either adapter.  The trouble is, the nvidia only
displays out the HDMI port.  I notice mxm_wmi_call_mxds() calls
function 0x5344584D, which I do not have.  I found a T410s DSDT that
shows this function doing this:

Method (WMMX, 3, NotSerialized) {
    ...
    If (LEqual (FUNC, 0x5344584D)) {
        If (LGreaterEqual (SizeOf (Arg2), 0x08)) {
            If (LEqual (Arg1, 0x10)) {
                Return (\_SB.PCI0.VID.MXDS (XARG))
            } Else {
                Return (\_SB.PCI0.PEG.VID.MXDS (XARG))
            }
        }
    }

So just a wrapper for the MXDS methods, which I do have (from my DSDT):

Scope (_SB.PCI0.P0P1.VGA) {
    ...
    Method (MXDS, 1, NotSerialized) {
        If (And (Arg0, Zero)) {
            Return (HLMX)
        } Else {
            Store (One, HLMX)
            Store (One, HCMX)
            SGPL (0x34, One, Zero)
            Sleep (0x64)
            ^^^SBRG.EC0.SPIN (0x1F, One)
        }
    }

And another reversed polarity version under _SB.PCI0.VGA.  There are
no obvious references to these methods elsewhere in the DSDT.  Are
these still part of the WMI interface (which I really don't
understand)?  I'm not sure if I should be attempting to call these
directly or dig deeper into WMI code.  Any guidance?

BTW, anyone with one of these laptops, backlight support works if you
boot with 'acpi_osi="Linux" acpi_osi="!Windows 2009"'.  I have yet to
debug that one.  Thanks,

Alex
nouveau/acpi: Fix _DSM parameter

The ACPI spec has always defined the last parameter for a _DSM call
to be a package.  Some ACPI implementations may do an Index()
operation on this field, which will fail for an integer (Asus UL30VT).
Other laptops currently only get by passing an integer because we
don't hit the code sections that use Index() (Lenovo T410s).  This
should be done for all the _DSM calls, but I don't have enough
DSDTs to look at to know if it will break anyone.

Based on git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-testing.git
(drm-nvidia-switch)

Signed-off-by: Alex Williamson <alex.williamson@xxxxxxxxxx>

diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index 04fa51a..6411a25 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -106,9 +106,9 @@ 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 params[4], elements[4];
 	union acpi_object *obj;
-	int err;
+	int i, err;
 
 	input.count = 4;
 	input.pointer = params;
@@ -119,8 +119,13 @@ static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result)
 	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;
+	params[3].type = ACPI_TYPE_PACKAGE;
+	params[3].package.count = 4;
+	params[3].package.elements = elements;
+	for (i = 0; i < 4; i++) {
+		elements[i].type = ACPI_TYPE_INTEGER;
+		elements[i].integer.value = (arg >> (i * 8)) & 0xff;
+	}
 
 	err = acpi_evaluate_object(handle, "_DSM", &input, &output);
 	if (err) {

Follow ups