[coreboot] Powersavings: 8W of difference between bios and coreboot

Charlotte Plusplus pluspluscharlotte at gmail.com
Sun Nov 20 00:45:23 CET 2016


Quick update: I tried experimenting on the w530 to find which ACPI call
turns off the dGPU.

bbswitch reported it was: \_SB.PCI0.LPC.EC.PUBS._OFF however, in tests with
powertop it failed to show any improvement. A lot of information was found
on https://github.com/Lekensteyn/acpi-stuff/blob/master/notes.txt, with
further discussion on
https://github.com/Bumblebee-Project/bbswitch/issues/112

The following acpi call takes the power consumption of a W530 in the
default bios from 20W to 13W, and is reported to also work on the W520 by
http://hybrid-graphics-linux.tuxfamily.org/index.php?title=ACPI_calls

\_SB.PCI0.PEG.VID._DSM
{0xF8,0xD8,0x86,0xA4,0xDA,0x0B,0x1B,0x47,0xA7,0x2B,0x60,0x42,0xA6,0xB5,0xBE,0xE0}
0x100 0x1A {0x1,0x0,0x0,0x3}

\_SB.PCI0.PEG.VID._PS3

 _PS3 puts the card in D3 mode (what I was trying to do with setpci before)
but not in totally off model. The card is truly off when lspci shows rev
ff, and that is done by the _DSM.

powertop then reports about 12W, so _PS3 shaves 7W and _DSM shaves 1W which
is just what I may need to fix by extra consumption of 8W

Apparently with the default bios some fields in the DSDT also change when
Optimus is enabled, cf
http://www.insanelymac.com/forum/topic/273621-guide-os-x-lion-on-thinkpad-w520/page-3
:

OperationRegion (MNVS, SystemMemory, 0xBAF9D018, 0x1000) //
optimusOperationRegion (GNVS, SystemMemory, 0xBAF3FE18, 0x01A6) //
optimus
OperationRegion (MNVS, SystemMemory, 0xBF79D018, 0x1000) //
discreteOperationRegion (GNVS, SystemMemory, 0xBF73FE18, 0x01A6)  //
discrete

I could confirm that on the extracted DSDT. I have yet to make sense of the
content of MVNS and GNVS, and the consequences of the field changes.

Switching between \_SB.PCI0.PEG.VID._PS3 and \_SB.PCI0.PEG.VID._PS0 ( with
echo $i > /proc/acpi/call) changes the power consumption reliably by 7W, so
I think this controls the Nvidia power

I am now trying to replicate these results on coreboot, by studying the EC
dump with ectool -d before and after switching the power. No success so
far. I tried acpi_debug but the logs were not helpful.

In case anyone is interested, here is the relevant part of the ACPI tables.
Please read https://github.com/Lekensteyn/acpi-stuff/blob/master/notes.txt
for a possible interpretation:

                Device(VID)
                {
                    Name(_ADR, 0x00)
                    OperationRegion(VPCG, PCI_Config, 0x00, 0x0100)
                    Field(VPCG, DWordAcc, NoLock, Preserve)
                    {
                        Offset(0x2C),    //Offset(44),
                        VSID, 32,
                        Offset(0x70),    //Offset(112),
                        VPWR, 8,
                    }
                    Name(_S3D, 0x03)
                    Name(DGOS, 0x00)
                    Method(_INI, 0, NotSerialized)
                    {
                        \VUPS(0x02)
                        Store(\VCDL, VQDL)
                        Store(\VCDC, VQDC)
                        Store(\VCDT, VQD0)
                        Store(\VCDD, VQD1)
                        If(ISOP())
                        {
                            \VHYB(0x04, 0x01)
                        }
                    }
                    Method(_PS0, 0, NotSerialized)
                    {
                        If(ISOP())
                        {
                            If(DGOS)
                            {
                                \VHYB(0x02, 0x00)
                                Sleep(0x64)
                                \VHYB(0x00, 0x01)
                                Sleep(0x0A)
                                Store(0x01, \_SB.PCI0.LPC.PCRS)
                                Store(0x01, \_SB.PCI0.LPC.PCRQ)
                                Sleep(0x64)
                                \VHYB(0x02, 0x01)
                                Sleep(0x01)
                                \VHYB(0x08, 0x01)
                                Store(0x0A, Local0)
                                Store(0x32, Local1)
                                While(Local1)
                                {
                                    Sleep(Local0)
                                    If(\LCHK(0x01))
                                    {
                                        Break
                                    }
                                    Decrement(Local1)
                                }
                                Store(0x00, \_SB.PCI0.LPC.PCRQ)
                                \VHYB(0x04, 0x00)
                                \SWTT(0x01)
                                Store(Zero, DGOS)
                            }
                            Else
                            {
                                If(LNotEqual(VSID, 0x21D117AA))
                                {
                                    \VHYB(0x04, 0x00)
                                }
                            }
                            \VHYB(0x09, \_SB.PCI0.PEG.VID.HDAS)
                        }
                    }
                    Method(_PS1, 0, NotSerialized)
                    {
                        NoOp
                    }
                    Method(_PS2, 0, NotSerialized)
                    {
                        NoOp
                    }
                    Method(_PS3, 0, NotSerialized)
                    {
                        If(ISOP())
                        {
                            If(LEqual(\_SB.PCI0.PEG.VID.OMPR, 0x03))
                            {
                                \SWTT(0x00)
                                \VHYB(0x08, 0x00)
                                Store(0x0A, Local0)
                                Store(0x32, Local1)
                                While(Local1)
                                {
                                    Sleep(Local0)
                                    If(\LCHK(0x00))
                                    {
                                        Break
                                    }
                                    Decrement(Local1)
                                }
                                \VHYB(0x02, 0x00)
                                Sleep(0x64)
                                \VHYB(0x00, 0x00)
                                Store(One, DGOS)
                                Store(0x02, \_SB.PCI0.PEG.VID.OMPR)
                            }
                        }
                    }
                    Method(_STA, 0, NotSerialized)
                    {
                        Return(0x0F)
                    }
                    Method(_DSM, 4, NotSerialized)
                    {
                        If(\CMPB(Arg0,
ToUUID("A486D8F8-0BDA471B-A72B6042A6B5BEE0")}))
                        {
                            Return(NVOP(Arg0, Arg1, Arg2, Arg3))
                        }
                    }
                    Name(_IRC, 0x00)
                    OperationRegion(ATRP, SystemMemory, \ATRB, 0x00010000)
                    Field(ATRP, AnyAcc, Lock, Preserve)
                    {
                        IDX0, 262144,
                        IDX1, 262144,
                    }
                    Method(_ROM, 2, Serialized)
                    {
                        If(LGreaterEqual(Arg0, 0x8000))
                        {
                            Return(GETB(Subtract(Arg0, 0x8000), Arg1, IDX1))
                        }
                        If(LGreater(Add(Arg0, Arg1), 0x8000))
                        {
                            Subtract(0x8000, Arg0, Local0)
                            Subtract(Arg1, Local0, Local1)
                            Store(GETB(Arg0, Local0, IDX0), Local3)
                            Store(GETB(0x00, Local1, IDX1), Local4)
                            Concatenate(Local3, Local4, Local5)
                            Return(Local5)
                        }
                        Return(GETB(Arg0, Arg1, IDX0))
                    }
                    Method(GETB, 3, Serialized)
                    {
                        Multiply(Arg0, 0x08, Local0)
                        Multiply(Arg1, 0x08, Local1)
                        CreateField(Arg2,Local0,Local1,TBF3)
                        Return(TBF3)
                    }
                    Method(VSWT, 0, NotSerialized)
                    {
                        If(\WVIS)
                        {
                            Store(\VEVT(0x07), Local0)
                        }
                        Else
                        {
                            Store(\VEVT(0x05), Local0)
                        }
                        And(0xFF, Local0, Local1)
                        If(Local1)
                        {
                            ASWT(Local1, 0x01)
                        }
                    }
                    Method(VLOC, 1, NotSerialized)
                    {
                        If(LEqual(Arg0, \_SB.LID._LID()))
                        {
                            \VSLD(Arg0)
                            Store(0x00, Local0)
                            If(LEqual(And(VPWR, 0x03), 0x00))
                            {
                                If(Arg0)
                                {
                                    If(LOr(\WIN7, \WVIS)) {}
                                    Else
                                    {
                                        Store(\VEVT(0x01), Local0)
                                    }
                                }
                                Else
                                {
                                    If(LOr(\WIN7, \WVIS)) {}
                                    Else
                                    {
                                        Store(\VEVT(0x02), Local0)
                                    }
                                }
                                And(0x0F, Local0, Local1)
                                If(Local1)
                                {
                                    ASWT(Local1, 0x00)
                                }
                            }
                        }
                    }
                    Method(_DOS, 1, NotSerialized)
                    {
                        If(LEqual(Arg0, 0x02))
                        {
                            Store(0x14, Local0)
                            While(Local0)
                            {
                                Decrement(Local0)
                                Acquire(MDGS, 0xFFFF)
                                If(LEqual(0x00, MSWT))
                                {
                                    Store(0x01, MSWT)
                                    Store(0x00, Local0)
                                    Store(Arg0, VDEE)
                                }
                                Release(MDGS)
                                Sleep(0xC8)
                            }
                        }
                        Else
                        {
                            Acquire(MDGS, 0xFFFF)
                            If(LEqual(VDEE, 0x02))
                            {
                                Store(0x00, MSWT)
                            }
                            If(LGreater(Arg0, 0x02))
                            {
                                Store(0x01, VDEE)
                            }
                            Else
                            {
                                Store(Arg0, VDEE)
                            }
                            Release(MDGS)
                        }
                    }
                    Method(_DOD, 0, NotSerialized)
                    {
                        Return(Package(8) {0x0100, 0x0114, 0x0111, 0x0115,
0x0112, 0x0116, 0x0113, 0x0110})
                    }
                    Method(ASWT, 2, NotSerialized)
                    {
                        If(LEqual(0x01, VDEE))
                        {
                            And(0x01, Arg1, Local1)
                            \VSDS(Arg0, Local1)
                        }
                        Else
                        {
                            Store(0x14, Local0)
                            While(Local0)
                            {
                                Decrement(Local0)
                                Acquire(MDGS, 0xFFFF)
                                If(LEqual(0x00, MSWT))
                                {
                                    Store(0x00, Local0)
                                    If(And(0x01, Arg1))
                                    {
                                        Store(0x01, VUPC)
                                    }
                                    Else
                                    {
                                        Store(0x00, VUPC)
                                    }
                                    If(And(0x01, Arg0))
                                    {
                                        Store(0x01, VQDL)
                                    }
                                    Else
                                    {
                                        Store(0x00, VQDL)
                                    }
                                    If(And(0x02, Arg0))
                                    {
                                        Store(0x01, VQDC)
                                    }
                                    Else
                                    {
                                        Store(0x00, VQDC)
                                    }
                                    If(And(0x04, Arg0))
                                    {
                                        Store(0x01, VQD0)
                                    }
                                    Else
                                    {
                                        Store(0x00, VQD0)
                                    }
                                    If(And(0x08, Arg0))
                                    {
                                        Store(0x01, VQD1)
                                    }
                                    Else
                                    {
                                        Store(0x00, VQD1)
                                    }
                                    If(And(0x10, Arg0))
                                    {
                                        Store(0x01, VQD2)
                                    }
                                    Else
                                    {
                                        Store(0x00, VQD2)
                                    }
                                    If(And(0x20, Arg0))
                                    {
                                        Store(0x01, VQD3)
                                    }
                                    Else
                                    {
                                        Store(0x00, VQD3)
                                    }
                                    If(And(0x40, Arg0))
                                    {
                                        Store(0x01, VQD4)
                                    }
                                    Else
                                    {
                                        Store(0x00, VQD4)
                                    }
                                    If(And(0x80, Arg0))
                                    {
                                        Store(0x01, VQD5)
                                    }
                                    Else
                                    {
                                        Store(0x00, VQD5)
                                    }
                                }
                                Release(MDGS)
                                Sleep(0xC8)
                            }
                            If(And(0x02, Arg1))
                            {
                                Notify(VID, 0x81)
                            }
                            Else
                            {
                                Notify(VID, 0x80)
                            }
                        }
                    }
                    Method(VDSW, 1, NotSerialized)
                    {
                        If(LEqual(VPWR, 0x00))
                        {
                            If(Arg0)
                            {
                                Store(\VEVT(0x03), Local0)
                            }
                            Else
                            {
                                Store(\VEVT(0x04), Local0)
                            }
                            And(0x0F, Local0, Local1)
                            If(Local1)
                            {
                                ASWT(Local1, 0x00)
                            }
                        }
                    }
                    Device(LCD0)
                    {
                        Method(_ADR, 0, NotSerialized)
                        {
                            Return(0x0110)
                        }
                        Method(_DCS, 0, NotSerialized)
                        {
                            \VUPS(0x00)
                            If(\VCDL)
                            {
                                Return(0x1F)
                            }
                            Else
                            {
                                Return(0x1D)
                            }
                        }
                        Method(_DGS, 0, NotSerialized)
                        {
                            Return(VQDL)
                        }
                        Method(_DSS, 1, NotSerialized)
                        {
                            And(Arg0, 0x01, VSDL)
                            If(And(Arg0, 0x80000000))
                            {
                                If(And(Arg0, 0x40000000))
                                {
                                    DSWT(0x02)
                                }
                                Else
                                {
                                    DSWT(0x01)
                                }
                            }
                        }
                        Method(_DDC, 1, NotSerialized)
                        {
                            If(ISOP())
                            {
                                Return(0x00)
                            }
                            If(LEqual(Arg0, 0x01))
                            {
                                Return(\VEDI)
                            }
                            Else
                            {
                                If(LEqual(Arg0, 0x02))
                                {
                                    Return(\VEDI)
                                }
                            }
                            Return(0x00)
                        }
                    }
                    Device(CRT0)
                    {
                        Method(_ADR, 0, NotSerialized)
                        {
                            Return(0x0100)
                        }
                        Method(_DCS, 0, NotSerialized)
                        {
                            \VUPS(0x01)
                            If(\VCSS)
                            {
                                If(\VCDC)
                                {
                                    Return(0x1F)
                                }
                                Else
                                {
                                    Return(0x1D)
                                }
                            }
                            Else
                            {
                                If(\VCDC)
                                {
                                    Return(0x0F)
                                }
                                Else
                                {
                                    Return(0x0D)
                                }
                            }
                        }
                        Method(_DGS, 0, NotSerialized)
                        {
                            Return(VQDC)
                        }
                        Method(_DSS, 1, NotSerialized)
                        {
                            And(Arg0, 0x01, VSDC)
                            If(And(Arg0, 0x80000000))
                            {
                                If(And(Arg0, 0x40000000))
                                {
                                    DSWT(0x02)
                                }
                                Else
                                {
                                    DSWT(0x01)
                                }
                            }
                        }
                    }
                    Device(DVI0)
                    {
                        Method(_ADR, 0, NotSerialized)
                        {
                            Return(0x0111)
                        }
                        Method(_DCS, 0, NotSerialized)
                        {
                            \VUPS(0x00)
                            If(\VCDD)
                            {
                                Return(0x1F)
                            }
                            Else
                            {
                                Return(0x1D)
                            }
                        }
                        Method(_DGS, 0, NotSerialized)
                        {
                            Return(VQD1)
                        }
                        Method(_DSS, 1, NotSerialized)
                        {
                            And(Arg0, 0x01, VSD1)
                            If(And(Arg0, 0x80000000))
                            {
                                If(And(Arg0, 0x40000000))
                                {
                                    DSWT(0x02)
                                }
                                Else
                                {
                                    DSWT(0x01)
                                }
                            }
                        }
                    }
                    Device(DP0)
                    {
                        Method(_ADR, 0, NotSerialized)
                        {
                            Return(0x0114)
                        }
                        Method(_DCS, 0, NotSerialized)
                        {
                            \VUPS(0x00)
                            If(\VCDT)
                            {
                                Return(0x1F)
                            }
                            Else
                            {
                                Return(0x1D)
                            }
                        }
                        Method(_DGS, 0, NotSerialized)
                        {
                            Return(VQD0)
                        }
                        Method(_DSS, 1, NotSerialized)
                        {
                            And(Arg0, 0x01, VSD0)
                            If(And(Arg0, 0x80000000))
                            {
                                If(And(Arg0, 0x40000000))
                                {
                                    DSWT(0x02)
                                }
                                Else
                                {
                                    DSWT(0x01)
                                }
                            }
                        }
                    }
                    Device(DVI1)
                    {
                        Method(_ADR, 0, NotSerialized)
                        {
                            Return(0x0112)
                        }
                        Method(_DCS, 0, NotSerialized)
                        {
                            \VUPS(0x00)
                            If(\VCDD)
                            {
                                Return(0x1F)
                            }
                            Else
                            {
                                Return(0x1D)
                            }
                        }
                        Method(_DGS, 0, NotSerialized)
                        {
                            Return(VQD3)
                        }
                        Method(_DSS, 1, NotSerialized)
                        {
                            And(Arg0, 0x01, VSD3)
                            If(And(Arg0, 0x80000000))
                            {
                                If(And(Arg0, 0x40000000))
                                {
                                    DSWT(0x02)
                                }
                                Else
                                {
                                    DSWT(0x01)
                                }
                            }
                        }
                    }
                    Device(DP1)
                    {
                        Method(_ADR, 0, NotSerialized)
                        {
                            Return(0x0115)
                        }
                        Method(_DCS, 0, NotSerialized)
                        {
                            \VUPS(0x00)
                            If(\VCDT)
                            {
                                Return(0x1F)
                            }
                            Else
                            {
                                Return(0x1D)
                            }
                        }
                        Method(_DGS, 0, NotSerialized)
                        {
                            Return(VQD2)
                        }
                        Method(_DSS, 1, NotSerialized)
                        {
                            And(Arg0, 0x01, VSD2)
                            If(And(Arg0, 0x80000000))
                            {
                                If(And(Arg0, 0x40000000))
                                {
                                    DSWT(0x02)
                                }
                                Else
                                {
                                    DSWT(0x01)
                                }
                            }
                        }
                    }
                    Device(DVI2)
                    {
                        Method(_ADR, 0, NotSerialized)
                        {
                            Return(0x0113)
                        }
                        Method(_DCS, 0, NotSerialized)
                        {
                            \VUPS(0x00)
                            If(\VCDD)
                            {
                                Return(0x1F)
                            }
                            Else
                            {
                                Return(0x1D)
                            }
                        }
                        Method(_DGS, 0, NotSerialized)
                        {
                            Return(VQD5)
                        }
                        Method(_DSS, 1, NotSerialized)
                        {
                            And(Arg0, 0x01, VSD5)
                            If(And(Arg0, 0x80000000))
                            {
                                If(And(Arg0, 0x40000000))
                                {
                                    DSWT(0x02)
                                }
                                Else
                                {
                                    DSWT(0x01)
                                }
                            }
                        }
                    }
                    Device(DP2)
                    {
                        Method(_ADR, 0, NotSerialized)
                        {
                            Return(0x0116)
                        }
                        Method(_DCS, 0, NotSerialized)
                        {
                            \VUPS(0x00)
                            If(\VCDT)
                            {
                                Return(0x1F)
                            }
                            Else
                            {
                                Return(0x1D)
                            }
                        }
                        Method(_DGS, 0, NotSerialized)
                        {
                            Return(VQD4)
                        }
                        Method(_DSS, 1, NotSerialized)
                        {
                            And(Arg0, 0x01, VSD4)
                            If(And(Arg0, 0x80000000))
                            {
                                If(And(Arg0, 0x40000000))
                                {
                                    DSWT(0x02)
                                }
                                Else
                                {
                                    DSWT(0x01)
                                }
                            }
                        }
                    }
                    Method(DSWT, 1, NotSerialized)
                    {
                        If(VSDL)
                        {
                            Store(0x01, Local0)
                        }
                        Else
                        {
                            Store(0x00, Local0)
                        }
                        If(VSDC)
                        {
                            Or(0x02, Local0, Local0)
                        }
                        If(VSD0)
                        {
                            Or(0x08, Local0, Local0)
                        }
                        If(Local0)
                        {
                            If(VUPC)
                            {
                                \VSDS(Local0, Arg0)
                            }
                        }
                        Else
                        {
                            NoOp
                        }
                    }
                }




On Sat, Nov 19, 2016 at 1:57 AM, Charlotte Plusplus <
pluspluscharlotte at gmail.com> wrote:

> Quick update:
>
> Just having "device pci 01.0 on end" in the devicetree results in the
> following powertop measurements:
> 26W after boot, 21W with power savings applied, 20W at maximum power
> savings
>
> So just declaring the nvidia makes things much worse, even without really
> using the dGPU for anything. (there are no nvidia modules, to make sure it
> would not interfere with the measurements)
>
> Since it was in D0, I tried setting the Nvidia gpu in D3 state
> setpci -s 01:00.0 CAP_PM+4.b
> 08
> setpci -s 01:00.0 CAP_PM+4.b=0b
>
> It didn't help with the power. To confirm whether disabling the Nvidia
> pcie interface results in this +4W in maximal power savings, I completed
> src/drivers/lenovo/hybrid_graphics.c with the PCI ID from my card. I
> could return to 17W with all power savings applied.
>
> So I'm back to trying to find a way to turn off the power completely with
> the EC, and hoping this is where the extra 8W come from.
>
> After some googling I found ec_access, but I don't know which register to
> write to.
>
> In case anyone is interested, here are the pci devices, of course ASPM is
> already enabled (root: 0xB0 : 0x43, peripheral: 0x88 : 0x4B) and I am not
> using the dGPU for anything at all.
>
> $ cat /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/power/runt
> ime_status
> suspended
> $ cat /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.1/power/runt
> ime_status
> active
>
> $ lspci -s  00:01.0 -xxx
>
> 00:01.0 PCI bridge: Intel Corporation Xeon E3-1200 v2/3rd Gen Core
> processor PCI Express Root Port (rev 09
> )
> 00: 86 80 51 01 07 04 10 00 09 00 04 06 10 00 81 00
> 10: 00 00 00 00 00 00 00 00 00 01 01 00 20 20 00 20
> 20: 00 f0 00 f1 01 c0 f1 d1 00 00 00 00 00 00 00 00
> 30: 00 00 00 00 88 00 00 00 00 00 00 00 0b 01 03 00
> 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0a
> 80: 01 90 03 c8 08 00 00 00 0d 80 00 00 86 80 00 00
> 90: 05 a0 01 00 d8 02 e0 fe 00 00 00 00 00 00 00 00
> a0: 10 00 42 01 01 80 00 00 00 00 00 00 03 ad 61 02
> b0: 43 00 02 51 00 00 04 00 00 00 48 00 08 00 00 00
> c0: 00 00 00 00 00 00 00 00 00 00 00 00 0e 00 00 00
> d0: 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> f0: 00 00 00 00 00 00 01 00 00 00 00 00 01 00 10 00
>
> #    0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
>
> $ lspci -d 10de:0dfa -xxx
> 01:00.0 VGA compatible controller: NVIDIA Corporation GF108GLM [Quadro
> 1000M] (rev a1)
> 00: de 10 fa 0d 03 00 10 00 a1 00 00 03 10 00 80 00
> 10: 00 00 00 f0 0c 00 00 c0 00 00 00 00 0c 00 00 d0
> 20: 00 00 00 00 01 20 00 00 00 00 00 00 00 00 00 00
> 30: 00 00 00 f1 60 00 00 00 00 00 00 00 0b 01 00 00
> 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 50: 00 00 00 00 01 00 00 00 ce d6 23 00 00 00 00 00
> 60: 01 68 03 00 08 00 00 00 05 78 80 00 00 00 00 00
> 70: 00 00 00 00 00 00 00 00 10 b4 02 00 a0 8d 00 00
> 80: 10 28 00 00 02 2d 05 00 4b 01 02 11 00 00 00 00
> 90: 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00
> a0: 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00
> b0: 00 00 00 00 09 00 14 01 00 00 00 00 00 00 00 00
> c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>
> #    0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
>
> # 78 contains 10, on 88 : 4b
>
> $ lspci -d 10de:0bea -xxx
>
> 01:00.1 Audio device: NVIDIA Corporation GF108 High Definition Audio
> Controller (rev a1)
> 00: de 10 ea 0b 06 00 18 00 a1 00 03 04 10 00 80 00
> 10: 00 00 08 f1 00 00 00 00 00 00 00 00 00 00 00 00
> 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 30: 00 00 00 00 60 00 00 00 00 00 00 00 0b 02 00 00
> 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 50: 00 00 00 00 00 00 00 00 ce d6 23 00 00 00 00 00
> 60: 01 68 03 00 08 00 00 00 05 78 80 00 00 00 00 00
> 70: 00 00 00 00 00 00 00 00 10 00 02 00 a0 8d 00 00
> 80: 10 28 00 00 02 2d 05 00 4b 01 02 11 00 00 00 00
> 90: 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00
> a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>
> Charlotte
>
>
> On Fri, Nov 18, 2016 at 4:04 PM, Charlotte Plusplus <
> pluspluscharlotte at gmail.com> wrote:
>
>> Hello
>>
>> Super interesting, I didn't know all that!
>>
>> Currently, I have only set in devicetree:
>>
>> device pci 00.0 on end # host bridge
>> device pci 01.0 off end # NVidia
>> device pci 02.0 on end # Intel
>>
>> and in my nvram options I have:
>> hybrid_graphics_mode = Integrated Only
>>
>> I assumed that would be sufficient to turn off the power for the dGPU
>> until I figure out a way to make it work. I will enable the NVidia and do
>> more power tests.
>>
>> After reading hybrid_graphics.c, I understand a bit more, but I also have
>> more questions:
>>  - can I add register "pcie_hotplug_map" = "{ 0, 1, 0}" to make the
>> NVidia removable?
>> (so that the operating system will not freak out when the NVidia
>> disappears from the PCI bus if I find a way to control the power by talking
>> to the EC and send
>> GFXCORE_ON_D + the other signal for the VRAM)
>>
>>  - can you change the connection of the displayport? Based on the
>> specsheets, it is connected to the dGPU, while the internal display is
>> connected to the iGPU. If is it possible to control the muxes for the
>> internal display, I suppose it is possible for the other displays as well.
>> (I have just tested and I do not have any video on the displayport, and
>> xrandr does not detect anything)
>>
>>  - there seem to be some missing IDs in pci_device_ids_nvidia : cf
>> http://envytools.readthedocs.io/en/latest/hw/pciid.html which agrees
>> with the W530 : 0x0ffb, so I will  propose a patch:
>>                 0x0dfa, /* Nvidia NVS Quadro 1000m Lenovo W520 */
>>                 0x0ffb, /* Nvidia NVS Quadro K1000m Lenovo W530
>> */
>>                 0x0ffc, /* Nvidia NVS Quadro K2000m Lenovo W530 */
>>
>> It may also be the reason why the Nvidia is still getting power, as Iru
>> noted that hybrid_graphics should turn off the power. I will test that
>> separately.
>>
>> - until I can find a better solution, I am thinking of letting the Nvidia
>> show on on the PCIe bus and then sending commands to get in into advanced
>> sleep - like on https://wireless.wiki.kernel.o
>> rg/en/users/documentation/aspm
>>
>> It should be possible as the w530 lspci -v shows:
>>         Capabilities: [60] Power Management version 3
>>                 Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA
>> PME(D0-,D1-,D2-,D3hot-,D3cold-)
>>                 Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
>>
>> Would you have a better idea?
>>
>> Thanks
>> Charlotte
>>
>> On Fri, Nov 18, 2016 at 4:52 AM, Felix Held <felix-coreboot at felixheld.de>
>> wrote:
>>
>>> Hi!
>>>
>>> I don't know if Charlotte has added the ID of the dGPU to
>>>> src/drivers/lenovo/hybrid_graphics.c. Does the dGPU consume power
>>>> after hybrid_graphics.c disable the dGPU?
>>>>
>>> OPTIMUS_ENABLE is a PCH GPIO and controls the muxes that select if the
>>> internal display is connected to the iGPU or the dGPU; that's done in
>>> hybrid_graphics.c.
>>> GFXCORE_ON_D (and another signal that controls the power supply of the
>>> VRAM) are driven by the Thinker-1 chip; those switch on/off the power
>>> supply of the GPU. So to really disable the GPU you probably have to ask
>>> the EC to make that chip turn off the voltage for the GPU and VRAM.
>>>
>>>
>>> Regards
>>> Felix
>>>
>>> --
>>> coreboot mailing list: coreboot at coreboot.org
>>> https://www.coreboot.org/mailman/listinfo/coreboot
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.coreboot.org/pipermail/coreboot/attachments/20161119/64bca688/attachment-0001.html>


More information about the coreboot mailing list