<div dir="ltr"><div><div><div>Quick update: I tried experimenting on the w530 to find which ACPI call turns off the dGPU. <br><br></div>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 <a href="https://github.com/Lekensteyn/acpi-stuff/blob/master/notes.txt">https://github.com/Lekensteyn/acpi-stuff/blob/master/notes.txt</a>, with further discussion on <a href="https://github.com/Bumblebee-Project/bbswitch/issues/112">https://github.com/Bumblebee-Project/bbswitch/issues/112</a><br></div><br>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 <a href="http://hybrid-graphics-linux.tuxfamily.org/index.php?title=ACPI_calls">http://hybrid-graphics-linux.tuxfamily.org/index.php?title=ACPI_calls</a><br></div><p>\_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}
</p><p>\_SB.PCI0.PEG.VID._PS3 <br></p><p> _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.</p><p>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<br></p><p>Apparently with the default bios some fields in the DSDT also change when Optimus is enabled, cf <a href="http://www.insanelymac.com/forum/topic/273621-guide-os-x-lion-on-thinkpad-w520/page-3">http://www.insanelymac.com/forum/topic/273621-guide-os-x-lion-on-thinkpad-w520/page-3</a> :</p><pre class="gmail-prettyprint gmail-lang-auto gmail-linenums:0 gmail-prettyprinted"><span class="gmail-typ">OperationRegion</span><span class="gmail-pln"> </span><span class="gmail-pun">(</span><span class="gmail-pln">MNVS</span><span class="gmail-pun">,</span><span class="gmail-pln"> </span><span class="gmail-typ">SystemMemory</span><span class="gmail-pun">,</span><span class="gmail-pln"> </span><span class="gmail-lit">0xBAF9D018</span><span class="gmail-pun">,</span><span class="gmail-pln"> </span><span class="gmail-lit">0x1000</span><span class="gmail-pun">)</span><span class="gmail-pln"> </span><span class="gmail-com">// optimus</span><span class="gmail-pln">
</span><span class="gmail-typ"><span class="gmail-typ">OperationRegion</span><span class="gmail-pln"> </span><span class="gmail-pun">(</span><span class="gmail-pln">GNVS</span><span class="gmail-pun">,</span><span class="gmail-pln"> </span><span class="gmail-typ">SystemMemory</span><span class="gmail-pun">,</span><span class="gmail-pln"> </span><span class="gmail-lit">0xBAF3FE18</span><span class="gmail-pun">,</span><span class="gmail-pln"> </span><span class="gmail-lit">0x01A6</span><span class="gmail-pun">)</span><span class="gmail-pln"> </span><span class="gmail-com">// optimus</span><span class="gmail-pln">
</span><span class="gmail-typ"><br></span>OperationRegion</span><span class="gmail-pln"> </span><span class="gmail-pun">(</span><span class="gmail-pln">MNVS</span><span class="gmail-pun">,</span><span class="gmail-pln"> </span><span class="gmail-typ">SystemMemory</span><span class="gmail-pun">,</span><span class="gmail-pln"> </span><span class="gmail-lit">0xBF79D018</span><span class="gmail-pun">,</span><span class="gmail-pln"> </span><span class="gmail-lit">0x1000</span><span class="gmail-pun">)</span><span class="gmail-pln"> </span><span class="gmail-com">// discrete</span><span class="gmail-pln">
</span><span class="gmail-typ">OperationRegion</span><span class="gmail-pln"> </span><span class="gmail-pun">(</span><span class="gmail-pln">GNVS</span><span class="gmail-pun">,</span><span class="gmail-pln"> </span><span class="gmail-typ">SystemMemory</span><span class="gmail-pun">,</span><span class="gmail-pln"> </span><span class="gmail-lit">0xBF73FE18</span><span class="gmail-pun">,</span><span class="gmail-pln"> </span><span class="gmail-lit">0x01A6</span><span class="gmail-pun">)</span><span class="gmail-pln">  </span><span class="gmail-com">// discrete</span></pre><p>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.<br></p><p>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<br></p><p>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.<br></p><p>In case anyone is interested, here is the relevant part of the ACPI tables. Please read  <a href="https://github.com/Lekensteyn/acpi-stuff/blob/master/notes.txt">https://github.com/Lekensteyn/acpi-stuff/blob/master/notes.txt</a> for a possible interpretation:<br></p><p>                Device(VID)<br>                {<br>                    Name(_ADR, 0x00)<br>                    OperationRegion(VPCG, PCI_Config, 0x00, 0x0100)<br>                    Field(VPCG, DWordAcc, NoLock, Preserve)<br>                    {<br>                        Offset(0x2C),    //Offset(44),<br>                        VSID, 32,<br>                        Offset(0x70),    //Offset(112),<br>                        VPWR, 8,<br>                    }<br>                    Name(_S3D, 0x03)<br>                    Name(DGOS, 0x00)<br>                    Method(_INI, 0, NotSerialized)<br>                    {<br>                        \VUPS(0x02)<br>                        Store(\VCDL, VQDL)<br>                        Store(\VCDC, VQDC)<br>                        Store(\VCDT, VQD0)<br>                        Store(\VCDD, VQD1)<br>                        If(ISOP())<br>                        {<br>                            \VHYB(0x04, 0x01)<br>                        }<br>                    }<br>                    Method(_PS0, 0, NotSerialized)<br>                    {<br>                        If(ISOP())<br>                        {<br>                            If(DGOS)<br>                            {<br>                                \VHYB(0x02, 0x00)<br>                                Sleep(0x64)<br>                                \VHYB(0x00, 0x01)<br>                                Sleep(0x0A)<br>                                Store(0x01, \_SB.PCI0.LPC.PCRS)<br>                                Store(0x01, \_SB.PCI0.LPC.PCRQ)<br>                                Sleep(0x64)<br>                                \VHYB(0x02, 0x01)<br>                                Sleep(0x01)<br>                                \VHYB(0x08, 0x01)<br>                                Store(0x0A, Local0)<br>                                Store(0x32, Local1)<br>                                While(Local1)<br>                                {<br>                                    Sleep(Local0)<br>                                    If(\LCHK(0x01))<br>                                    {<br>                                        Break<br>                                    }<br>                                    Decrement(Local1)<br>                                }<br>                                Store(0x00, \_SB.PCI0.LPC.PCRQ)<br>                                \VHYB(0x04, 0x00)<br>                                \SWTT(0x01)<br>                                Store(Zero, DGOS)<br>                            }<br>                            Else<br>                            {<br>                                If(LNotEqual(VSID, 0x21D117AA))<br>                                {<br>                                    \VHYB(0x04, 0x00)<br>                                }<br>                            }<br>                            \VHYB(0x09, \_SB.PCI0.PEG.VID.HDAS)<br>                        }<br>                    }<br>                    Method(_PS1, 0, NotSerialized)<br>                    {<br>                        NoOp<br>                    }<br>                    Method(_PS2, 0, NotSerialized)<br>                    {<br>                        NoOp<br>                    }<br>                    Method(_PS3, 0, NotSerialized)<br>                    {<br>                        If(ISOP())<br>                        {<br>                            If(LEqual(\_SB.PCI0.PEG.VID.OMPR, 0x03))<br>                            {<br>                                \SWTT(0x00)<br>                                \VHYB(0x08, 0x00)<br>                                Store(0x0A, Local0)<br>                                Store(0x32, Local1)<br>                                While(Local1)<br>                                {<br>                                    Sleep(Local0)<br>                                    If(\LCHK(0x00))<br>                                    {<br>                                        Break<br>                                    }<br>                                    Decrement(Local1)<br>                                }<br>                                \VHYB(0x02, 0x00)<br>                                Sleep(0x64)<br>                                \VHYB(0x00, 0x00)<br>                                Store(One, DGOS)<br>                                Store(0x02, \_SB.PCI0.PEG.VID.OMPR)<br>                            }<br>                        }<br>                    }<br>                    Method(_STA, 0, NotSerialized)<br>                    {<br>                        Return(0x0F)<br>                    }<br>                    Method(_DSM, 4, NotSerialized)<br>                    {<br>                        If(\CMPB(Arg0, ToUUID("A486D8F8-0BDA471B-A72B6042A6B5BEE0")}))<br>                        {<br>                            Return(NVOP(Arg0, Arg1, Arg2, Arg3))<br>                        }<br>                    }<br>                    Name(_IRC, 0x00)<br>                    OperationRegion(ATRP, SystemMemory, \ATRB, 0x00010000)<br>                    Field(ATRP, AnyAcc, Lock, Preserve)<br>                    {<br>                        IDX0, 262144,<br>                        IDX1, 262144,<br>                    }<br>                    Method(_ROM, 2, Serialized)<br>                    {<br>                        If(LGreaterEqual(Arg0, 0x8000))<br>                        {<br>                            Return(GETB(Subtract(Arg0, 0x8000), Arg1, IDX1))<br>                        }<br>                        If(LGreater(Add(Arg0, Arg1), 0x8000))<br>                        {<br>                            Subtract(0x8000, Arg0, Local0)<br>                            Subtract(Arg1, Local0, Local1)<br>                            Store(GETB(Arg0, Local0, IDX0), Local3)<br>                            Store(GETB(0x00, Local1, IDX1), Local4)<br>                            Concatenate(Local3, Local4, Local5)<br>                            Return(Local5)<br>                        }<br>                        Return(GETB(Arg0, Arg1, IDX0))<br>                    }<br>                    Method(GETB, 3, Serialized)<br>                    {<br>                        Multiply(Arg0, 0x08, Local0)<br>                        Multiply(Arg1, 0x08, Local1)<br>                        CreateField(Arg2,Local0,Local1,TBF3)<br>                        Return(TBF3)<br>                    }<br>                    Method(VSWT, 0, NotSerialized)<br>                    {<br>                        If(\WVIS)<br>                        {<br>                            Store(\VEVT(0x07), Local0)<br>                        }<br>                        Else<br>                        {<br>                            Store(\VEVT(0x05), Local0)<br>                        }<br>                        And(0xFF, Local0, Local1)<br>                        If(Local1)<br>                        {<br>                            ASWT(Local1, 0x01)<br>                        }<br>                    }<br>                    Method(VLOC, 1, NotSerialized)<br>                    {<br>                        If(LEqual(Arg0, \_SB.LID._LID()))<br>                        {<br>                            \VSLD(Arg0)<br>                            Store(0x00, Local0)<br>                            If(LEqual(And(VPWR, 0x03), 0x00))<br>                            {<br>                                If(Arg0)<br>                                {<br>                                    If(LOr(\WIN7, \WVIS)) {}<br>                                    Else<br>                                    {<br>                                        Store(\VEVT(0x01), Local0)<br>                                    }<br>                                }<br>                                Else<br>                                {<br>                                    If(LOr(\WIN7, \WVIS)) {}<br>                                    Else<br>                                    {<br>                                        Store(\VEVT(0x02), Local0)<br>                                    }<br>                                }<br>                                And(0x0F, Local0, Local1)<br>                                If(Local1)<br>                                {<br>                                    ASWT(Local1, 0x00)<br>                                }<br>                            }<br>                        }<br>                    }<br>                    Method(_DOS, 1, NotSerialized)<br>                    {<br>                        If(LEqual(Arg0, 0x02))<br>                        {<br>                            Store(0x14, Local0)<br>                            While(Local0)<br>                            {<br>                                Decrement(Local0)<br>                                Acquire(MDGS, 0xFFFF)<br>                                If(LEqual(0x00, MSWT))<br>                                {<br>                                    Store(0x01, MSWT)<br>                                    Store(0x00, Local0)<br>                                    Store(Arg0, VDEE)<br>                                }<br>                                Release(MDGS)<br>                                Sleep(0xC8)<br>                            }<br>                        }<br>                        Else<br>                        {<br>                            Acquire(MDGS, 0xFFFF)<br>                            If(LEqual(VDEE, 0x02))<br>                            {<br>                                Store(0x00, MSWT)<br>                            }<br>                            If(LGreater(Arg0, 0x02))<br>                            {<br>                                Store(0x01, VDEE)<br>                            }<br>                            Else<br>                            {<br>                                Store(Arg0, VDEE)<br>                            }<br>                            Release(MDGS)<br>                        }<br>                    }<br>                    Method(_DOD, 0, NotSerialized)<br>                    {<br>                        Return(Package(8) {0x0100, 0x0114, 0x0111, 0x0115, 0x0112, 0x0116, 0x0113, 0x0110})<br>                    }<br>                    Method(ASWT, 2, NotSerialized)<br>                    {<br>                        If(LEqual(0x01, VDEE))<br>                        {<br>                            And(0x01, Arg1, Local1)<br>                            \VSDS(Arg0, Local1)<br>                        }<br>                        Else<br>                        {<br>                            Store(0x14, Local0)<br>                            While(Local0)<br>                            {<br>                                Decrement(Local0)<br>                                Acquire(MDGS, 0xFFFF)<br>                                If(LEqual(0x00, MSWT))<br>                                {<br>                                    Store(0x00, Local0)<br>                                    If(And(0x01, Arg1))<br>                                    {<br>                                        Store(0x01, VUPC)<br>                                    }<br>                                    Else<br>                                    {<br>                                        Store(0x00, VUPC)<br>                                    }<br>                                    If(And(0x01, Arg0))<br>                                    {<br>                                        Store(0x01, VQDL)<br>                                    }<br>                                    Else<br>                                    {<br>                                        Store(0x00, VQDL)<br>                                    }<br>                                    If(And(0x02, Arg0))<br>                                    {<br>                                        Store(0x01, VQDC)<br>                                    }<br>                                    Else<br>                                    {<br>                                        Store(0x00, VQDC)<br>                                    }<br>                                    If(And(0x04, Arg0))<br>                                    {<br>                                        Store(0x01, VQD0)<br>                                    }<br>                                    Else<br>                                    {<br>                                        Store(0x00, VQD0)<br>                                    }<br>                                    If(And(0x08, Arg0))<br>                                    {<br>                                        Store(0x01, VQD1)<br>                                    }<br>                                    Else<br>                                    {<br>                                        Store(0x00, VQD1)<br>                                    }<br>                                    If(And(0x10, Arg0))<br>                                    {<br>                                        Store(0x01, VQD2)<br>                                    }<br>                                    Else<br>                                    {<br>                                        Store(0x00, VQD2)<br>                                    }<br>                                    If(And(0x20, Arg0))<br>                                    {<br>                                        Store(0x01, VQD3)<br>                                    }<br>                                    Else<br>                                    {<br>                                        Store(0x00, VQD3)<br>                                    }<br>                                    If(And(0x40, Arg0))<br>                                    {<br>                                        Store(0x01, VQD4)<br>                                    }<br>                                    Else<br>                                    {<br>                                        Store(0x00, VQD4)<br>                                    }<br>                                    If(And(0x80, Arg0))<br>                                    {<br>                                        Store(0x01, VQD5)<br>                                    }<br>                                    Else<br>                                    {<br>                                        Store(0x00, VQD5)<br>                                    }<br>                                }<br>                                Release(MDGS)<br>                                Sleep(0xC8)<br>                            }<br>                            If(And(0x02, Arg1))<br>                            {<br>                                Notify(VID, 0x81)<br>                            }<br>                            Else<br>                            {<br>                                Notify(VID, 0x80)<br>                            }<br>                        }<br>                    }<br>                    Method(VDSW, 1, NotSerialized)<br>                    {<br>                        If(LEqual(VPWR, 0x00))<br>                        {<br>                            If(Arg0)<br>                            {<br>                                Store(\VEVT(0x03), Local0)<br>                            }<br>                            Else<br>                            {<br>                                Store(\VEVT(0x04), Local0)<br>                            }<br>                            And(0x0F, Local0, Local1)<br>                            If(Local1)<br>                            {<br>                                ASWT(Local1, 0x00)<br>                            }<br>                        }<br>                    }<br>                    Device(LCD0)<br>                    {<br>                        Method(_ADR, 0, NotSerialized)<br>                        {<br>                            Return(0x0110)<br>                        }<br>                        Method(_DCS, 0, NotSerialized)<br>                        {<br>                            \VUPS(0x00)<br>                            If(\VCDL)<br>                            {<br>                                Return(0x1F)<br>                            }<br>                            Else<br>                            {<br>                                Return(0x1D)<br>                            }<br>                        }<br>                        Method(_DGS, 0, NotSerialized)<br>                        {<br>                            Return(VQDL)<br>                        }<br>                        Method(_DSS, 1, NotSerialized)<br>                        {<br>                            And(Arg0, 0x01, VSDL)<br>                            If(And(Arg0, 0x80000000))<br>                            {<br>                                If(And(Arg0, 0x40000000))<br>                                {<br>                                    DSWT(0x02)<br>                                }<br>                                Else<br>                                {<br>                                    DSWT(0x01)<br>                                }<br>                            }<br>                        }<br>                        Method(_DDC, 1, NotSerialized)<br>                        {<br>                            If(ISOP())<br>                            {<br>                                Return(0x00)<br>                            }<br>                            If(LEqual(Arg0, 0x01))<br>                            {<br>                                Return(\VEDI)<br>                            }<br>                            Else<br>                            {<br>                                If(LEqual(Arg0, 0x02))<br>                                {<br>                                    Return(\VEDI)<br>                                }<br>                            }<br>                            Return(0x00)<br>                        }<br>                    }<br>                    Device(CRT0)<br>                    {<br>                        Method(_ADR, 0, NotSerialized)<br>                        {<br>                            Return(0x0100)<br>                        }<br>                        Method(_DCS, 0, NotSerialized)<br>                        {<br>                            \VUPS(0x01)<br>                            If(\VCSS)<br>                            {<br>                                If(\VCDC)<br>                                {<br>                                    Return(0x1F)<br>                                }<br>                                Else<br>                                {<br>                                    Return(0x1D)<br>                                }<br>                            }<br>                            Else<br>                            {<br>                                If(\VCDC)<br>                                {<br>                                    Return(0x0F)<br>                                }<br>                                Else<br>                                {<br>                                    Return(0x0D)<br>                                }<br>                            }<br>                        }<br>                        Method(_DGS, 0, NotSerialized)<br>                        {<br>                            Return(VQDC)<br>                        }<br>                        Method(_DSS, 1, NotSerialized)<br>                        {<br>                            And(Arg0, 0x01, VSDC)<br>                            If(And(Arg0, 0x80000000))<br>                            {<br>                                If(And(Arg0, 0x40000000))<br>                                {<br>                                    DSWT(0x02)<br>                                }<br>                                Else<br>                                {<br>                                    DSWT(0x01)<br>                                }<br>                            }<br>                        }<br>                    }<br>                    Device(DVI0)<br>                    {<br>                        Method(_ADR, 0, NotSerialized)<br>                        {<br>                            Return(0x0111)<br>                        }<br>                        Method(_DCS, 0, NotSerialized)<br>                        {<br>                            \VUPS(0x00)<br>                            If(\VCDD)<br>                            {<br>                                Return(0x1F)<br>                            }<br>                            Else<br>                            {<br>                                Return(0x1D)<br>                            }<br>                        }<br>                        Method(_DGS, 0, NotSerialized)<br>                        {<br>                            Return(VQD1)<br>                        }<br>                        Method(_DSS, 1, NotSerialized)<br>                        {<br>                            And(Arg0, 0x01, VSD1)<br>                            If(And(Arg0, 0x80000000))<br>                            {<br>                                If(And(Arg0, 0x40000000))<br>                                {<br>                                    DSWT(0x02)<br>                                }<br>                                Else<br>                                {<br>                                    DSWT(0x01)<br>                                }<br>                            }<br>                        }<br>                    }<br>                    Device(DP0)<br>                    {<br>                        Method(_ADR, 0, NotSerialized)<br>                        {<br>                            Return(0x0114)<br>                        }<br>                        Method(_DCS, 0, NotSerialized)<br>                        {<br>                            \VUPS(0x00)<br>                            If(\VCDT)<br>                            {<br>                                Return(0x1F)<br>                            }<br>                            Else<br>                            {<br>                                Return(0x1D)<br>                            }<br>                        }<br>                        Method(_DGS, 0, NotSerialized)<br>                        {<br>                            Return(VQD0)<br>                        }<br>                        Method(_DSS, 1, NotSerialized)<br>                        {<br>                            And(Arg0, 0x01, VSD0)<br>                            If(And(Arg0, 0x80000000))<br>                            {<br>                                If(And(Arg0, 0x40000000))<br>                                {<br>                                    DSWT(0x02)<br>                                }<br>                                Else<br>                                {<br>                                    DSWT(0x01)<br>                                }<br>                            }<br>                        }<br>                    }<br>                    Device(DVI1)<br>                    {<br>                        Method(_ADR, 0, NotSerialized)<br>                        {<br>                            Return(0x0112)<br>                        }<br>                        Method(_DCS, 0, NotSerialized)<br>                        {<br>                            \VUPS(0x00)<br>                            If(\VCDD)<br>                            {<br>                                Return(0x1F)<br>                            }<br>                            Else<br>                            {<br>                                Return(0x1D)<br>                            }<br>                        }<br>                        Method(_DGS, 0, NotSerialized)<br>                        {<br>                            Return(VQD3)<br>                        }<br>                        Method(_DSS, 1, NotSerialized)<br>                        {<br>                            And(Arg0, 0x01, VSD3)<br>                            If(And(Arg0, 0x80000000))<br>                            {<br>                                If(And(Arg0, 0x40000000))<br>                                {<br>                                    DSWT(0x02)<br>                                }<br>                                Else<br>                                {<br>                                    DSWT(0x01)<br>                                }<br>                            }<br>                        }<br>                    }<br>                    Device(DP1)<br>                    {<br>                        Method(_ADR, 0, NotSerialized)<br>                        {<br>                            Return(0x0115)<br>                        }<br>                        Method(_DCS, 0, NotSerialized)<br>                        {<br>                            \VUPS(0x00)<br>                            If(\VCDT)<br>                            {<br>                                Return(0x1F)<br>                            }<br>                            Else<br>                            {<br>                                Return(0x1D)<br>                            }<br>                        }<br>                        Method(_DGS, 0, NotSerialized)<br>                        {<br>                            Return(VQD2)<br>                        }<br>                        Method(_DSS, 1, NotSerialized)<br>                        {<br>                            And(Arg0, 0x01, VSD2)<br>                            If(And(Arg0, 0x80000000))<br>                            {<br>                                If(And(Arg0, 0x40000000))<br>                                {<br>                                    DSWT(0x02)<br>                                }<br>                                Else<br>                                {<br>                                    DSWT(0x01)<br>                                }<br>                            }<br>                        }<br>                    }<br>                    Device(DVI2)<br>                    {<br>                        Method(_ADR, 0, NotSerialized)<br>                        {<br>                            Return(0x0113)<br>                        }<br>                        Method(_DCS, 0, NotSerialized)<br>                        {<br>                            \VUPS(0x00)<br>                            If(\VCDD)<br>                            {<br>                                Return(0x1F)<br>                            }<br>                            Else<br>                            {<br>                                Return(0x1D)<br>                            }<br>                        }<br>                        Method(_DGS, 0, NotSerialized)<br>                        {<br>                            Return(VQD5)<br>                        }<br>                        Method(_DSS, 1, NotSerialized)<br>                        {<br>                            And(Arg0, 0x01, VSD5)<br>                            If(And(Arg0, 0x80000000))<br>                            {<br>                                If(And(Arg0, 0x40000000))<br>                                {<br>                                    DSWT(0x02)<br>                                }<br>                                Else<br>                                {<br>                                    DSWT(0x01)<br>                                }<br>                            }<br>                        }<br>                    }<br>                    Device(DP2)<br>                    {<br>                        Method(_ADR, 0, NotSerialized)<br>                        {<br>                            Return(0x0116)<br>                        }<br>                        Method(_DCS, 0, NotSerialized)<br>                        {<br>                            \VUPS(0x00)<br>                            If(\VCDT)<br>                            {<br>                                Return(0x1F)<br>                            }<br>                            Else<br>                            {<br>                                Return(0x1D)<br>                            }<br>                        }<br>                        Method(_DGS, 0, NotSerialized)<br>                        {<br>                            Return(VQD4)<br>                        }<br>                        Method(_DSS, 1, NotSerialized)<br>                        {<br>                            And(Arg0, 0x01, VSD4)<br>                            If(And(Arg0, 0x80000000))<br>                            {<br>                                If(And(Arg0, 0x40000000))<br>                                {<br>                                    DSWT(0x02)<br>                                }<br>                                Else<br>                                {<br>                                    DSWT(0x01)<br>                                }<br>                            }<br>                        }<br>                    }<br>                    Method(DSWT, 1, NotSerialized)<br>                    {<br>                        If(VSDL)<br>                        {<br>                            Store(0x01, Local0)<br>                        }<br>                        Else<br>                        {<br>                            Store(0x00, Local0)<br>                        }<br>                        If(VSDC)<br>                        {<br>                            Or(0x02, Local0, Local0)<br>                        }<br>                        If(VSD0)<br>                        {<br>                            Or(0x08, Local0, Local0)<br>                        }<br>                        If(Local0)<br>                        {<br>                            If(VUPC)<br>                            {<br>                                \VSDS(Local0, Arg0)<br>                            }<br>                        }<br>                        Else<br>                        {<br>                            NoOp<br>                        }<br>                    }<br>                }<br><br></p><br><div><div><div><div><br></div></div></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Nov 19, 2016 at 1:57 AM, Charlotte Plusplus <span dir="ltr"><<a href="mailto:pluspluscharlotte@gmail.com" target="_blank">pluspluscharlotte@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div>Quick update:<br><br></div>Just having "device pci 01.0 on end" in the devicetree results in the following powertop measurements:<br></div>26W after boot, 21W with power savings applied, 20W at maximum power savings<br><br>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)<br><br></div><div>Since it was in D0, I tried setting the Nvidia gpu in D3 state</div><div>setpci -s 01:00.0 CAP_PM+4.b<br>08<br>setpci -s 01:00.0 CAP_PM+4.b=0b<br><br></div><div>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_<wbr>graphics.c with the PCI ID from my card. I could return to 17W with all power savings applied.<br><br></div><div>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.<br><br>After some googling I found ec_access, but I don't know which register to write to.</div></div><div><br></div>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.<br><br>$ cat /sys/devices/pci0000:00/0000:0<wbr>0:01.0/0000:01:00.0/power/runt<wbr>ime_status<br>suspended<br>$ cat /sys/devices/pci0000:00/0000:0<wbr>0:01.0/0000:01:00.1/power/runt<wbr>ime_status<br>active<br><br>$ lspci -s  00:01.0 -xxx<br><br>00:01.0 PCI bridge: Intel Corporation Xeon E3-1200 v2/3rd Gen Core processor PCI Express Root Port (rev 09<br>)<br>00: 86 80 51 01 07 04 10 00 09 00 04 06 10 00 81 00<br>10: 00 00 00 00 00 00 00 00 00 01 01 00 20 20 00 20<br>20: 00 f0 00 f1 01 c0 f1 d1 00 00 00 00 00 00 00 00<br>30: 00 00 00 00 88 00 00 00 00 00 00 00 0b 01 03 00<br>40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0a<br>80: 01 90 03 c8 08 00 00 00 0d 80 00 00 86 80 00 00<br>90: 05 a0 01 00 d8 02 e0 fe 00 00 00 00 00 00 00 00<br>a0: 10 00 42 01 01 80 00 00 00 00 00 00 03 ad 61 02<br>b0: 43 00 02 51 00 00 04 00 00 00 48 00 08 00 00 00<br>c0: 00 00 00 00 00 00 00 00 00 00 00 00 0e 00 00 00<br>d0: 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>f0: 00 00 00 00 00 00 01 00 00 00 00 00 01 00 10 00<br> <br>#    0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f<br><br>$ lspci -d 10de:0dfa -xxx <br>01:00.0 VGA compatible controller: NVIDIA Corporation GF108GLM [Quadro 1000M] (rev a1)<br>00: de 10 fa 0d 03 00 10 00 a1 00 00 03 10 00 80 00<br>10: 00 00 00 f0 0c 00 00 c0 00 00 00 00 0c 00 00 d0<br>20: 00 00 00 00 01 20 00 00 00 00 00 00 00 00 00 00<br>30: 00 00 00 f1 60 00 00 00 00 00 00 00 0b 01 00 00<br>40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>50: 00 00 00 00 01 00 00 00 ce d6 23 00 00 00 00 00<br>60: 01 68 03 00 08 00 00 00 05 78 80 00 00 00 00 00<br>70: 00 00 00 00 00 00 00 00 10 b4 02 00 a0 8d 00 00<br>80: 10 28 00 00 02 2d 05 00 4b 01 02 11 00 00 00 00<br>90: 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00<br>a0: 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00<br>b0: 00 00 00 00 09 00 14 01 00 00 00 00 00 00 00 00<br>c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br><br>#    0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f<br><br># 78 contains 10, on 88 : 4b<br><br>$ lspci -d 10de:0bea -xxx <br><br>01:00.1 Audio device: NVIDIA Corporation GF108 High Definition Audio Controller (rev a1)<br>00: de 10 ea 0b 06 00 18 00 a1 00 03 04 10 00 80 00<br>10: 00 00 08 f1 00 00 00 00 00 00 00 00 00 00 00 00<br>20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>30: 00 00 00 00 60 00 00 00 00 00 00 00 0b 02 00 00<br>40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>50: 00 00 00 00 00 00 00 00 ce d6 23 00 00 00 00 00<br>60: 01 68 03 00 08 00 00 00 05 78 80 00 00 00 00 00<br>70: 00 00 00 00 00 00 00 00 10 00 02 00 a0 8d 00 00<br>80: 10 28 00 00 02 2d 05 00 4b 01 02 11 00 00 00 00<br>90: 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00<br>a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<br>f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00<span class="HOEnZb"><font color="#888888"><br><br></font></span></div><span class="HOEnZb"><font color="#888888">Charlotte<br><div><div><div><br></div></div></div></font></span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Nov 18, 2016 at 4:04 PM, Charlotte Plusplus <span dir="ltr"><<a href="mailto:pluspluscharlotte@gmail.com" target="_blank">pluspluscharlotte@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div>Hello<br><br></div>Super interesting, I didn't know all that!<br><br>Currently, I have only set in devicetree:<br><br>device pci 00.0 on end # host bridge<br>device pci 01.0 off end # NVidia<br>device pci 02.0 on end # Intel<br></div><div><br></div><div>and in my nvram options I have:<br>hybrid_graphics_mode = Integrated Only<br><br></div>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.<br><br></div>After reading hybrid_graphics.c, I understand a bit more, but I also have more questions:<br></div><div> - can I add register "pcie_hotplug_map" = "{ 0, 1, 0}" to make the NVidia removable?<br>(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 <br>
GFXCORE_ON_D + the other signal for the VRAM)<br></div><div><br></div> - 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)<br><br> - there seem to be some missing IDs in pci_device_ids_nvidia : cf <a href="http://envytools.readthedocs.io/en/latest/hw/pciid.html" target="_blank">http://envytools.readthedocs.i<wbr>o/en/latest/hw/pciid.html</a> which agrees with the W530 : 0x0ffb, so I will  propose a patch:<br>                0x0dfa, /* Nvidia NVS Quadro 1000m Lenovo W520 */<br>                0x0ffb, /* Nvidia NVS Quadro K1000m Lenovo W530 */                           <br>                0x0ffc, /* Nvidia NVS Quadro K2000m Lenovo W530 */<br><br></div><div>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.<br><br><div>- 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 <a href="https://wireless.wiki.kernel.org/en/users/documentation/aspm" target="_blank">https://wireless.wiki.kernel.o<wbr>rg/en/users/documentation/aspm</a><br><br></div><div>It should be possible as the w530 lspci -v shows:<br></div><div>        Capabilities: [60] Power Management version 3<br>                Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-<wbr>)<br>                Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-<br></div><div><br></div><div>Would you have a better idea?<br><br></div>Thanks<span class="m_4598014332941919015HOEnZb"><font color="#888888"><br></font></span></div><span class="m_4598014332941919015HOEnZb"><font color="#888888"><div>Charlotte<br></div></font></span></div><div class="m_4598014332941919015HOEnZb"><div class="m_4598014332941919015h5"><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Nov 18, 2016 at 4:52 AM, Felix Held <span dir="ltr"><<a href="mailto:felix-coreboot@felixheld.de" target="_blank">felix-coreboot@felixheld.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi!<span><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I don't know if Charlotte has added the ID of the dGPU to src/drivers/lenovo/hybrid_grap<wbr>hics.c. Does the dGPU consume power after hybrid_graphics.c disable the dGPU?<br>
</blockquote></span>
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.<br>
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.<div class="m_4598014332941919015m_716253321887735877HOEnZb"><div class="m_4598014332941919015m_716253321887735877h5"><br>
<br>
Regards<br>
Felix<br>
<br>
-- <br>
coreboot mailing list: <a href="mailto:coreboot@coreboot.org" target="_blank">coreboot@coreboot.org</a><br>
<a href="https://www.coreboot.org/mailman/listinfo/coreboot" rel="noreferrer" target="_blank">https://www.coreboot.org/mailm<wbr>an/listinfo/coreboot</a><br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>