<p>Evgeny Zinoviev has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/28380">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">[WIP] Nvidia Optimus support for ThinkPads<br><br>Based on siro's work #23041.<br>Tested on ThinkPad W530.<br><br>Enables dual graphics mode for T420, T420s, T530, T430, T430s, T530<br>mainboards, adds ACPI code for dGPU power management.<br><br>What works (tested on 4.16.13-gentoo kernel):<br>- power management via _PS0 and _DSM + _PS3 ACPI calls<br>- nouveau driver (with a workaround, see below)<br>- bumblebee (from the "develop" branch)<br>- bbswitch<br><br>Known problems:<br>- `lspci -s 01:00.0 -vv` turns dGPU on if it was off before. Not sure why it<br>  happens (probably it calls _PS0 at some point) or whether it should<br>  happen.<br><br>- nouveau driver unloading (`rmmod` or `modprobe -r`) does not work well: it<br>  crashes in nouveau_backlight_exit (invalid pointer). The current hack is<br>  to comment out these lines in drivers/gpu/drm/nouveau/nouveau_backlight.c,<br>  function  `nouveau_backlight_exit`:<br><br>  list_for_each_entry(connector, &drm->bl_connectors, head) {<br>    if (connector->id >= 0)<br>      ida_simple_remove(&bl_ida, connector->id);<br>    }<br><br>  Need to debug why it happens.<br><br>- VGA ROM for Nvidia GPU is not loaded from BIOS (i.e. coreboot). Need<br>  to debug and fix this too. The current workaround is to load it from<br>  a file.<br><br>  To do this automatically, create a new file in /etc/modprobe.d with this<br>  line:<br><br>  config=NvBios=pci10de-0ffc.rom<br><br>  where "pci10de-0ffc.rom" is a file in /lib/firmware directory<br>  (the path is relative to /lib/firmware). VGA ROM has to be extracted<br>  from vendor UEFI dump, GUID is 9781FA9D-5A3B-431A-AD59-2748C9A170EC.<br><br>Not tested yet:<br>- nvidia proprietary driver<br><br>Change-Id: I277808d6c1d8bd6e0a267a53f25471597698f8d5<br>Signed-off-by: Evgeny Zinoviev <me@ch1p.com><br>---<br>A src/drivers/lenovo/hybrid_graphics/acpi/gpu.asl<br>A src/drivers/nvidia/optimus/acpi/optimus.asl<br>A src/ec/lenovo/pmh7/acpi/pmh7.asl<br>M src/mainboard/lenovo/t420/acpi/ec.asl<br>M src/mainboard/lenovo/t420/cmos.layout<br>M src/mainboard/lenovo/t420/dsdt.asl<br>M src/mainboard/lenovo/t420/romstage.c<br>M src/mainboard/lenovo/t420s/acpi/ec.asl<br>M src/mainboard/lenovo/t420s/cmos.layout<br>M src/mainboard/lenovo/t420s/dsdt.asl<br>M src/mainboard/lenovo/t420s/romstage.c<br>M src/mainboard/lenovo/t430/acpi/ec.asl<br>M src/mainboard/lenovo/t430/cmos.layout<br>M src/mainboard/lenovo/t430/devicetree.cb<br>M src/mainboard/lenovo/t430/dsdt.asl<br>M src/mainboard/lenovo/t430/romstage.c<br>M src/mainboard/lenovo/t430s/Kconfig<br>M src/mainboard/lenovo/t430s/Makefile.inc<br>M src/mainboard/lenovo/t430s/acpi/ec.asl<br>M src/mainboard/lenovo/t430s/cmos.default<br>M src/mainboard/lenovo/t430s/cmos.layout<br>M src/mainboard/lenovo/t430s/devicetree.cb<br>M src/mainboard/lenovo/t430s/dsdt.asl<br>M src/mainboard/lenovo/t430s/romstage.c<br>M src/mainboard/lenovo/t520/acpi/ec.asl<br>M src/mainboard/lenovo/t520/dsdt.asl<br>M src/mainboard/lenovo/t520/romstage.c<br>M src/mainboard/lenovo/t530/acpi/ec.asl<br>M src/mainboard/lenovo/t530/cmos.layout<br>M src/mainboard/lenovo/t530/dsdt.asl<br>M src/mainboard/lenovo/t530/romstage.c<br>M src/mainboard/lenovo/t530/variants/t530/devicetree.cb<br>M src/mainboard/lenovo/t530/variants/w530/devicetree.cb<br>M src/northbridge/intel/sandybridge/acpi/peg.asl<br>34 files changed, 427 insertions(+), 4 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/80/28380/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/drivers/lenovo/hybrid_graphics/acpi/gpu.asl b/src/drivers/lenovo/hybrid_graphics/acpi/gpu.asl</span><br><span>new file mode 100644</span><br><span>index 0000000..feb9d5e</span><br><span>--- /dev/null</span><br><span>+++ b/src/drivers/lenovo/hybrid_graphics/acpi/gpu.asl</span><br><span>@@ -0,0 +1,34 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2017-2018 Patrick Rudolph <siro@das-labor.org></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or</span><br><span style="color: hsl(120, 100%, 40%);">+ * modify it under the terms of the GNU General Public License as</span><br><span style="color: hsl(120, 100%, 40%);">+ * published by the Free Software Foundation; version 2 of</span><br><span style="color: hsl(120, 100%, 40%);">+ * the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Scope (\_SB.PCI0.PEGP.DEV0) {</span><br><span style="color: hsl(120, 100%, 40%);">+  Method (_INI) {</span><br><span style="color: hsl(120, 100%, 40%);">+               // Tell peg.asl that we have _OFF and _ON</span><br><span style="color: hsl(120, 100%, 40%);">+             Store (One, DEVP)</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   Method (_OFF) {</span><br><span style="color: hsl(120, 100%, 40%);">+               \_SB.PCI0.LPCB.PMH7.GPUP(Zero)</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   Method (_ON) {</span><br><span style="color: hsl(120, 100%, 40%);">+                \_SB.PCI0.LPCB.PMH7.GPUP(One)</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   Method (_STA) {</span><br><span style="color: hsl(120, 100%, 40%);">+               Return (\_SB.PCI0.LPCB.PMH7.GPUS())</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/drivers/nvidia/optimus/acpi/optimus.asl b/src/drivers/nvidia/optimus/acpi/optimus.asl</span><br><span>new file mode 100644</span><br><span>index 0000000..feb2b5d</span><br><span>--- /dev/null</span><br><span>+++ b/src/drivers/nvidia/optimus/acpi/optimus.asl</span><br><span>@@ -0,0 +1,199 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (c) 2011 Sven Schnelle <svens@stackframe.org></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or</span><br><span style="color: hsl(120, 100%, 40%);">+ * modify it under the terms of the GNU General Public License as</span><br><span style="color: hsl(120, 100%, 40%);">+ * published by the Free Software Foundation; version 2 of</span><br><span style="color: hsl(120, 100%, 40%);">+ * the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ Scope (\_SB.PCI0.PEGP.DEV0) {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     Name (DGOS, 0x00)</span><br><span style="color: hsl(120, 100%, 40%);">+     Name (OMPR, 0x02)</span><br><span style="color: hsl(120, 100%, 40%);">+     Name (HDAS, 0x00)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   Method (NVOP, 4, Serialized)</span><br><span style="color: hsl(120, 100%, 40%);">+  {</span><br><span style="color: hsl(120, 100%, 40%);">+             If (LNotEqual (Arg1, 0x0100))</span><br><span style="color: hsl(120, 100%, 40%);">+         {</span><br><span style="color: hsl(120, 100%, 40%);">+                     Return (0x80000001)</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           Store (ToInteger (Arg2), Local0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            /* Supported Optimus functions advertisement */</span><br><span style="color: hsl(120, 100%, 40%);">+               If (LEqual (Local0, 0x00))</span><br><span style="color: hsl(120, 100%, 40%);">+            {</span><br><span style="color: hsl(120, 100%, 40%);">+                     Return (Buffer (0x04)</span><br><span style="color: hsl(120, 100%, 40%);">+                 {</span><br><span style="color: hsl(120, 100%, 40%);">+                             0x09, 0x00, 0x00, 0x06</span><br><span style="color: hsl(120, 100%, 40%);">+                        })</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+             /* NOUVEAU_DSM_OPTIMUS_CAPS */</span><br><span style="color: hsl(120, 100%, 40%);">+                If (LEqual (Local0, 0x1A))</span><br><span style="color: hsl(120, 100%, 40%);">+            {</span><br><span style="color: hsl(120, 100%, 40%);">+                     CreateField (Arg3, 0x18, 0x02, OPCE)</span><br><span style="color: hsl(120, 100%, 40%);">+                  CreateField (Arg3, 0x00, 0x01, FLCH)</span><br><span style="color: hsl(120, 100%, 40%);">+                  If (ToInteger (FLCH))</span><br><span style="color: hsl(120, 100%, 40%);">+                 {</span><br><span style="color: hsl(120, 100%, 40%);">+                             // NOUVEAU_DSM_OPTIMUS_SET_POWERDOWN</span><br><span style="color: hsl(120, 100%, 40%);">+                          // only called if no _PR3 in parent</span><br><span style="color: hsl(120, 100%, 40%);">+                           Store (OPCE, OMPR)</span><br><span style="color: hsl(120, 100%, 40%);">+                    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   Store (Buffer (0x04)</span><br><span style="color: hsl(120, 100%, 40%);">+                  {</span><br><span style="color: hsl(120, 100%, 40%);">+                              0x00, 0x00, 0x00, 0x00</span><br><span style="color: hsl(120, 100%, 40%);">+                       }, Local0)</span><br><span style="color: hsl(120, 100%, 40%);">+                    CreateField (Local0, 0x00, 0x01, OPEN)</span><br><span style="color: hsl(120, 100%, 40%);">+                        CreateField (Local0, 0x03, 0x02, CGCS)</span><br><span style="color: hsl(120, 100%, 40%);">+                        CreateField (Local0, 0x06, 0x01, SHPC)</span><br><span style="color: hsl(120, 100%, 40%);">+                        CreateField (Local0, 0x18, 0x03, DGPC)</span><br><span style="color: hsl(120, 100%, 40%);">+                        CreateField (Local0, 0x1B, 0x02, HDAC)</span><br><span style="color: hsl(120, 100%, 40%);">+                        Store (One, OPEN) // OPTIMUS_ENABLED</span><br><span style="color: hsl(120, 100%, 40%);">+                  Store (One, SHPC) // OPTIMUS_DISPLAY_HOTPLUG</span><br><span style="color: hsl(120, 100%, 40%);">+                  Store (One, DGPC) // OPTIMUS_DYNAMIC_PWR_CAP</span><br><span style="color: hsl(120, 100%, 40%);">+                  If (\_SB.PCI0.PEGP.DEV0._STA ())</span><br><span style="color: hsl(120, 100%, 40%);">+                      {</span><br><span style="color: hsl(120, 100%, 40%);">+                             Store (0x03, CGCS) // OPTIMUS_STATUS_PWR_STABLE</span><br><span style="color: hsl(120, 100%, 40%);">+                       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   Store (0x02, HDAC) // OPTIMUS_HDA_CODEC_MASK</span><br><span style="color: hsl(120, 100%, 40%);">+                  Return (Local0)</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+             /* NOUVEAU_DSM_OPTIMUS_FLAGS */</span><br><span style="color: hsl(120, 100%, 40%);">+               If (LEqual (Local0, 0x1B))</span><br><span style="color: hsl(120, 100%, 40%);">+            {</span><br><span style="color: hsl(120, 100%, 40%);">+                     CreateField (Arg3, 0x00, 0x01, HDAU)</span><br><span style="color: hsl(120, 100%, 40%);">+                  CreateField (Arg3, 0x01, 0x01, HDAR)</span><br><span style="color: hsl(120, 100%, 40%);">+                  Store (Buffer (0x04)</span><br><span style="color: hsl(120, 100%, 40%);">+                  {</span><br><span style="color: hsl(120, 100%, 40%);">+                              0x00, 0x00, 0x00, 0x00</span><br><span style="color: hsl(120, 100%, 40%);">+                       }, Local0)</span><br><span style="color: hsl(120, 100%, 40%);">+                    CreateField (Local0, 0x02, 0x02, RQGS)</span><br><span style="color: hsl(120, 100%, 40%);">+                        CreateField (Local0, 0x04, 0x01, PWST)</span><br><span style="color: hsl(120, 100%, 40%);">+                        Store (One, PWST)</span><br><span style="color: hsl(120, 100%, 40%);">+                     Store (Zero, RQGS)</span><br><span style="color: hsl(120, 100%, 40%);">+                    If (ToInteger (HDAR))</span><br><span style="color: hsl(120, 100%, 40%);">+                 {</span><br><span style="color: hsl(120, 100%, 40%);">+                             //VGA switcheroo: Called on card power off</span><br><span style="color: hsl(120, 100%, 40%);">+                            Store (ToInteger (HDAU), HDAS)</span><br><span style="color: hsl(120, 100%, 40%);">+                        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   Return (Local0)</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+             /* NOUVEAU_DSM_POWER */</span><br><span style="color: hsl(120, 100%, 40%);">+               If (LEqual (Local0, 3))</span><br><span style="color: hsl(120, 100%, 40%);">+               {</span><br><span style="color: hsl(120, 100%, 40%);">+                     // Unused if _PS0 and _PS3 is present ?</span><br><span style="color: hsl(120, 100%, 40%);">+                       If (ToInteger(Arg3)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                \_SB.PCI0.PEGP.DEV0._ON()</span><br><span style="color: hsl(120, 100%, 40%);">+                     } Else {</span><br><span style="color: hsl(120, 100%, 40%);">+                              \_SB.PCI0.PEGP.DEV0._OFF()</span><br><span style="color: hsl(120, 100%, 40%);">+                    }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           Return (0x80000002)</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   // helper function to compare two buffers</span><br><span style="color: hsl(120, 100%, 40%);">+     Method (CMP, 2, NotSerialized)</span><br><span style="color: hsl(120, 100%, 40%);">+        {</span><br><span style="color: hsl(120, 100%, 40%);">+             If (LNotEqual (0x10, SizeOf (Arg0)))</span><br><span style="color: hsl(120, 100%, 40%);">+          {</span><br><span style="color: hsl(120, 100%, 40%);">+                     Return (0x00)</span><br><span style="color: hsl(120, 100%, 40%);">+         }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           If (LNotEqual (0x10, SizeOf (Arg1)))</span><br><span style="color: hsl(120, 100%, 40%);">+          {</span><br><span style="color: hsl(120, 100%, 40%);">+                     Return (0x00)</span><br><span style="color: hsl(120, 100%, 40%);">+         }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           Store (0x00, Local0)</span><br><span style="color: hsl(120, 100%, 40%);">+          While (LLess (Local0, 0x10))</span><br><span style="color: hsl(120, 100%, 40%);">+          {</span><br><span style="color: hsl(120, 100%, 40%);">+                     If (LNotEqual (DerefOf (Index (Arg0, Local0)), DerefOf (Index (</span><br><span style="color: hsl(120, 100%, 40%);">+                               Arg1, Local0))))</span><br><span style="color: hsl(120, 100%, 40%);">+                      {</span><br><span style="color: hsl(120, 100%, 40%);">+                             Return (0x00)</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   Increment (Local0)</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           Return (0x01)</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   Method (_DSM, 4, NotSerialized)</span><br><span style="color: hsl(120, 100%, 40%);">+       {</span><br><span style="color: hsl(120, 100%, 40%);">+             /* NV DSM OPTIMUS */</span><br><span style="color: hsl(120, 100%, 40%);">+          If (CMP (Arg0, Buffer (0x10) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        0xF8, 0xD8, 0x86, 0xA4, 0xDA, 0x0B, 0x1B, 0x47,</span><br><span style="color: hsl(120, 100%, 40%);">+                       0xA7, 0x2B, 0x60, 0x42, 0xA6, 0xB5, 0xBE, 0xE0}))</span><br><span style="color: hsl(120, 100%, 40%);">+             {</span><br><span style="color: hsl(120, 100%, 40%);">+                     Return (NVOP (Arg0, Arg1, Arg2, Arg3))</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           Return (Buffer (0x04)</span><br><span style="color: hsl(120, 100%, 40%);">+         {</span><br><span style="color: hsl(120, 100%, 40%);">+                     0x01, 0x00, 0x00, 0x80</span><br><span style="color: hsl(120, 100%, 40%);">+                })</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   OperationRegion (RPCS, PCI_Config, 0x00, 0x100)</span><br><span style="color: hsl(120, 100%, 40%);">+       Field (RPCS, AnyAcc, NoLock, Preserve)</span><br><span style="color: hsl(120, 100%, 40%);">+        {</span><br><span style="color: hsl(120, 100%, 40%);">+             VID, 16,</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   Method (_PS0, 0, NotSerialized)</span><br><span style="color: hsl(120, 100%, 40%);">+       {</span><br><span style="color: hsl(120, 100%, 40%);">+             If (\_SB.PCI0.PEGP.DEV0.DGOS)</span><br><span style="color: hsl(120, 100%, 40%);">+         {</span><br><span style="color: hsl(120, 100%, 40%);">+                     \_SB.PCI0.PEGP.DEV0._ON ()</span><br><span style="color: hsl(120, 100%, 40%);">+                    Sleep(50)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   \_SB.PCI0.PEGP._ON ()</span><br><span style="color: hsl(120, 100%, 40%);">+                 Sleep(50)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   Store (0x32, Local0)</span><br><span style="color: hsl(120, 100%, 40%);">+                  While (Or(LEqual(VID, 0xffff), LEqual(VID, 0x0000)))</span><br><span style="color: hsl(120, 100%, 40%);">+                  {</span><br><span style="color: hsl(120, 100%, 40%);">+                             Sleep (10)</span><br><span style="color: hsl(120, 100%, 40%);">+                            Decrement (Local0)</span><br><span style="color: hsl(120, 100%, 40%);">+                    }</span><br><span style="color: hsl(120, 100%, 40%);">+                     Store (Zero, HDAS)</span><br><span style="color: hsl(120, 100%, 40%);">+                    Store (Zero, DGOS)</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   Method (_PS1, 0, NotSerialized)</span><br><span style="color: hsl(120, 100%, 40%);">+       {</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   Method (_PS2, 0, NotSerialized)</span><br><span style="color: hsl(120, 100%, 40%);">+       {</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   Method (_PS3, 0, NotSerialized)</span><br><span style="color: hsl(120, 100%, 40%);">+       {</span><br><span style="color: hsl(120, 100%, 40%);">+             If (LEqual (\_SB.PCI0.PEGP.DEV0.OMPR, 0x03))</span><br><span style="color: hsl(120, 100%, 40%);">+          {</span><br><span style="color: hsl(120, 100%, 40%);">+                     \_SB.PCI0.PEGP._OFF ()</span><br><span style="color: hsl(120, 100%, 40%);">+                        Sleep(50)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   \_SB.PCI0.PEGP.DEV0._OFF ()</span><br><span style="color: hsl(120, 100%, 40%);">+                   Sleep(50)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   Store (0x02, \_SB.PCI0.PEGP.DEV0.OMPR)</span><br><span style="color: hsl(120, 100%, 40%);">+                        Store (0x01, \_SB.PCI0.PEGP.DEV0.DGOS)</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/ec/lenovo/pmh7/acpi/pmh7.asl b/src/ec/lenovo/pmh7/acpi/pmh7.asl</span><br><span>new file mode 100644</span><br><span>index 0000000..1559209</span><br><span>--- /dev/null</span><br><span>+++ b/src/ec/lenovo/pmh7/acpi/pmh7.asl</span><br><span>@@ -0,0 +1,62 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Device(PMH7)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        Name (_HID, EISAID("PNP0C09"))</span><br><span style="color: hsl(120, 100%, 40%);">+      Name (_UID, 0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      OperationRegion (CREG, SystemIO, 0x15e0, 0x10)</span><br><span style="color: hsl(120, 100%, 40%);">+        Field (CREG, ByteAcc, NoLock, Preserve)</span><br><span style="color: hsl(120, 100%, 40%);">+       {</span><br><span style="color: hsl(120, 100%, 40%);">+             Offset(0x0c),</span><br><span style="color: hsl(120, 100%, 40%);">+         ADDR, 16, /* PMH7 has 9-bit address space, which is supported by</span><br><span style="color: hsl(120, 100%, 40%);">+                           pmh7tool, and if some register greater than 0xff was</span><br><span style="color: hsl(120, 100%, 40%);">+                          read before, then 0x0D port must be cleared, otherwise</span><br><span style="color: hsl(120, 100%, 40%);">+                        it won't work (as it contains the wrong address) */</span><br><span style="color: hsl(120, 100%, 40%);">+          DATA, 8</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   IndexField (ADDR, DATA, ByteAcc, NoLock, Preserve)</span><br><span style="color: hsl(120, 100%, 40%);">+    {</span><br><span style="color: hsl(120, 100%, 40%);">+             Offset (0x50),</span><br><span style="color: hsl(120, 100%, 40%);">+                , 3,</span><br><span style="color: hsl(120, 100%, 40%);">+          DPWR, 1,</span><br><span style="color: hsl(120, 100%, 40%);">+              , 3,</span><br><span style="color: hsl(120, 100%, 40%);">+          DRST, 1</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   // Control dGPU power</span><br><span style="color: hsl(120, 100%, 40%);">+ Method (GPUP, 1)</span><br><span style="color: hsl(120, 100%, 40%);">+      {</span><br><span style="color: hsl(120, 100%, 40%);">+             If (LNotEqual(Arg0, GPUS())) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        If (Arg0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                           Store (Zero, DRST)</span><br><span style="color: hsl(120, 100%, 40%);">+                            Store (One, DPWR)</span><br><span style="color: hsl(120, 100%, 40%);">+                             Sleep (50)</span><br><span style="color: hsl(120, 100%, 40%);">+                            Store (One, DRST)</span><br><span style="color: hsl(120, 100%, 40%);">+                             Sleep (100)</span><br><span style="color: hsl(120, 100%, 40%);">+                   } Else {</span><br><span style="color: hsl(120, 100%, 40%);">+                              Store (Zero, DRST)</span><br><span style="color: hsl(120, 100%, 40%);">+                            Sleep (10)</span><br><span style="color: hsl(120, 100%, 40%);">+                            Store (Zero, DPWR)</span><br><span style="color: hsl(120, 100%, 40%);">+                    }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   // Return dGPU power state</span><br><span style="color: hsl(120, 100%, 40%);">+    Method (GPUS)</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span style="color: hsl(120, 100%, 40%);">+             Return (DPWR)</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/mainboard/lenovo/t420/acpi/ec.asl b/src/mainboard/lenovo/t420/acpi/ec.asl</span><br><span>index d631f12..faf8f86 100644</span><br><span>--- a/src/mainboard/lenovo/t420/acpi/ec.asl</span><br><span>+++ b/src/mainboard/lenovo/t420/acpi/ec.asl</span><br><span>@@ -15,6 +15,7 @@</span><br><span>  */</span><br><span> </span><br><span> #include <ec/lenovo/h8/acpi/ec.asl></span><br><span style="color: hsl(120, 100%, 40%);">+#include <ec/lenovo/pmh7/acpi/pmh7.asl></span><br><span> </span><br><span> Scope(\_SB.PCI0.LPCB.EC)</span><br><span> {</span><br><span>diff --git a/src/mainboard/lenovo/t420/cmos.layout b/src/mainboard/lenovo/t420/cmos.layout</span><br><span>index 5a9e570..f55c203 100644</span><br><span>--- a/src/mainboard/lenovo/t420/cmos.layout</span><br><span>+++ b/src/mainboard/lenovo/t420/cmos.layout</span><br><span>@@ -129,6 +129,7 @@</span><br><span> 11    6     224M</span><br><span> 12    0     Integrated Only</span><br><span> 12    1     Discrete Only</span><br><span style="color: hsl(120, 100%, 40%);">+12    2     Dual Graphics</span><br><span> 13    0     Disable</span><br><span> 13    1     AC and battery</span><br><span> 13    2     AC only</span><br><span>diff --git a/src/mainboard/lenovo/t420/dsdt.asl b/src/mainboard/lenovo/t420/dsdt.asl</span><br><span>index 7db8344..a4af7cf 100644</span><br><span>--- a/src/mainboard/lenovo/t420/dsdt.asl</span><br><span>+++ b/src/mainboard/lenovo/t420/dsdt.asl</span><br><span>@@ -50,6 +50,9 @@</span><br><span>                 }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+  #include <drivers/lenovo/hybrid_graphics/acpi/gpu.asl></span><br><span style="color: hsl(120, 100%, 40%);">+ #include <drivers/nvidia/optimus/acpi/optimus.asl></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   /* Chipset specific sleep states */</span><br><span>  #include <southbridge/intel/bd82x6x/acpi/sleepstates.asl></span><br><span> }</span><br><span>diff --git a/src/mainboard/lenovo/t420/romstage.c b/src/mainboard/lenovo/t420/romstage.c</span><br><span>index 36e83a3..bef2562 100644</span><br><span>--- a/src/mainboard/lenovo/t420/romstage.c</span><br><span>+++ b/src/mainboard/lenovo/t420/romstage.c</span><br><span>@@ -30,6 +30,9 @@</span><br><span> </span><br><span>    early_hybrid_graphics(&igd, &peg);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        if (peg && igd)</span><br><span style="color: hsl(120, 100%, 40%);">+               return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    /* Hide disabled devices */</span><br><span>  reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);</span><br><span>  reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);</span><br><span>diff --git a/src/mainboard/lenovo/t420s/acpi/ec.asl b/src/mainboard/lenovo/t420s/acpi/ec.asl</span><br><span>index d631f12..faf8f86 100644</span><br><span>--- a/src/mainboard/lenovo/t420s/acpi/ec.asl</span><br><span>+++ b/src/mainboard/lenovo/t420s/acpi/ec.asl</span><br><span>@@ -15,6 +15,7 @@</span><br><span>  */</span><br><span> </span><br><span> #include <ec/lenovo/h8/acpi/ec.asl></span><br><span style="color: hsl(120, 100%, 40%);">+#include <ec/lenovo/pmh7/acpi/pmh7.asl></span><br><span> </span><br><span> Scope(\_SB.PCI0.LPCB.EC)</span><br><span> {</span><br><span>diff --git a/src/mainboard/lenovo/t420s/cmos.layout b/src/mainboard/lenovo/t420s/cmos.layout</span><br><span>index f395c0c..2be55f6 100644</span><br><span>--- a/src/mainboard/lenovo/t420s/cmos.layout</span><br><span>+++ b/src/mainboard/lenovo/t420s/cmos.layout</span><br><span>@@ -129,6 +129,7 @@</span><br><span> 11    6     224M</span><br><span> 12    0     Integrated Only</span><br><span> 12    1     Discrete Only</span><br><span style="color: hsl(120, 100%, 40%);">+12    2     Dual Graphics</span><br><span> 13    0     Disable</span><br><span> 13    1     AC and battery</span><br><span> 13    2     AC only</span><br><span>diff --git a/src/mainboard/lenovo/t420s/dsdt.asl b/src/mainboard/lenovo/t420s/dsdt.asl</span><br><span>index c549988..3893114 100644</span><br><span>--- a/src/mainboard/lenovo/t420s/dsdt.asl</span><br><span>+++ b/src/mainboard/lenovo/t420s/dsdt.asl</span><br><span>@@ -51,6 +51,9 @@</span><br><span>                 }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ #include <drivers/lenovo/hybrid_graphics/acpi/gpu.asl></span><br><span style="color: hsl(120, 100%, 40%);">+  #include <drivers/nvidia/optimus/acpi/optimus.asl></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   /* Chipset specific sleep states */</span><br><span>  #include <southbridge/intel/bd82x6x/acpi/sleepstates.asl></span><br><span> }</span><br><span>diff --git a/src/mainboard/lenovo/t420s/romstage.c b/src/mainboard/lenovo/t420s/romstage.c</span><br><span>index 55011cf2..be8052c 100644</span><br><span>--- a/src/mainboard/lenovo/t420s/romstage.c</span><br><span>+++ b/src/mainboard/lenovo/t420s/romstage.c</span><br><span>@@ -32,6 +32,9 @@</span><br><span> </span><br><span>       early_hybrid_graphics(&igd, &peg);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        if (peg && igd)</span><br><span style="color: hsl(120, 100%, 40%);">+               return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    /* Hide disabled devices */</span><br><span>  reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);</span><br><span>  reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);</span><br><span>diff --git a/src/mainboard/lenovo/t430/acpi/ec.asl b/src/mainboard/lenovo/t430/acpi/ec.asl</span><br><span>index 3c7f89d..924bd37 100644</span><br><span>--- a/src/mainboard/lenovo/t430/acpi/ec.asl</span><br><span>+++ b/src/mainboard/lenovo/t430/acpi/ec.asl</span><br><span>@@ -20,3 +20,4 @@</span><br><span> #define THINKPAD_EC_GPE 17</span><br><span> </span><br><span> #include <ec/lenovo/h8/acpi/ec.asl></span><br><span style="color: hsl(120, 100%, 40%);">+#include <ec/lenovo/pmh7/acpi/pmh7.asl></span><br><span>diff --git a/src/mainboard/lenovo/t430/cmos.layout b/src/mainboard/lenovo/t430/cmos.layout</span><br><span>index 2b687c2..1b50e7f 100644</span><br><span>--- a/src/mainboard/lenovo/t430/cmos.layout</span><br><span>+++ b/src/mainboard/lenovo/t430/cmos.layout</span><br><span>@@ -128,6 +128,7 @@</span><br><span> 11    6     224M</span><br><span> 12    0     Integrated Only</span><br><span> 12    1     Discrete Only</span><br><span style="color: hsl(120, 100%, 40%);">+12    2     Dual Graphics</span><br><span> 13    0     Disable</span><br><span> 13    1     AC and battery</span><br><span> 13    2     AC only</span><br><span>diff --git a/src/mainboard/lenovo/t430/devicetree.cb b/src/mainboard/lenovo/t430/devicetree.cb</span><br><span>index d466b36..5eb92bc 100644</span><br><span>--- a/src/mainboard/lenovo/t430/devicetree.cb</span><br><span>+++ b/src/mainboard/lenovo/t430/devicetree.cb</span><br><span>@@ -167,7 +167,7 @@</span><br><span>                                     register "has_backlight_gpio" = "0"</span><br><span>                                      register "has_dgpu_power_gpio" = "0"</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                                    register "has_thinker1" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                     register "has_thinker1" = "1"</span><br><span>                            end</span><br><span>                          chip drivers/pc80/tpm</span><br><span>                                        device pnp 0c31.0 on end</span><br><span>diff --git a/src/mainboard/lenovo/t430/dsdt.asl b/src/mainboard/lenovo/t430/dsdt.asl</span><br><span>index dff8dcd..ad817f0 100644</span><br><span>--- a/src/mainboard/lenovo/t430/dsdt.asl</span><br><span>+++ b/src/mainboard/lenovo/t430/dsdt.asl</span><br><span>@@ -40,4 +40,7 @@</span><br><span>                    #include <southbridge/intel/bd82x6x/acpi/pch.asl></span><br><span>              }</span><br><span>    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   #include <drivers/lenovo/hybrid_graphics/acpi/gpu.asl></span><br><span style="color: hsl(120, 100%, 40%);">+  #include <drivers/nvidia/optimus/acpi/optimus.asl></span><br><span> }</span><br><span>diff --git a/src/mainboard/lenovo/t430/romstage.c b/src/mainboard/lenovo/t430/romstage.c</span><br><span>index 94679df..90d0886 100644</span><br><span>--- a/src/mainboard/lenovo/t430/romstage.c</span><br><span>+++ b/src/mainboard/lenovo/t430/romstage.c</span><br><span>@@ -30,6 +30,9 @@</span><br><span> </span><br><span>   early_hybrid_graphics(&igd, &peg);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        if (peg && igd)</span><br><span style="color: hsl(120, 100%, 40%);">+               return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    /* Hide disabled devices */</span><br><span>  reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);</span><br><span>  reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);</span><br><span>diff --git a/src/mainboard/lenovo/t430s/Kconfig b/src/mainboard/lenovo/t430s/Kconfig</span><br><span>index 728dd5c..a86f9f5 100644</span><br><span>--- a/src/mainboard/lenovo/t430s/Kconfig</span><br><span>+++ b/src/mainboard/lenovo/t430s/Kconfig</span><br><span>@@ -23,6 +23,7 @@</span><br><span>    select MAINBOARD_HAS_LIBGFXINIT</span><br><span>      select GFX_GMA_INTERNAL_IS_LVDS</span><br><span>      select INTEL_GMA_HAVE_VBT</span><br><span style="color: hsl(120, 100%, 40%);">+     select DRIVERS_LENOVO_HYBRID_GRAPHICS</span><br><span> </span><br><span>    # Workaround for EC/KBC IRQ1.</span><br><span>        select SERIRQ_CONTINUOUS_MODE</span><br><span>diff --git a/src/mainboard/lenovo/t430s/Makefile.inc b/src/mainboard/lenovo/t430s/Makefile.inc</span><br><span>index cb01f1c..2dab950 100644</span><br><span>--- a/src/mainboard/lenovo/t430s/Makefile.inc</span><br><span>+++ b/src/mainboard/lenovo/t430s/Makefile.inc</span><br><span>@@ -15,4 +15,5 @@</span><br><span> </span><br><span> smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c</span><br><span> romstage-y += gpio.c</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads</span><br><span>diff --git a/src/mainboard/lenovo/t430s/acpi/ec.asl b/src/mainboard/lenovo/t430s/acpi/ec.asl</span><br><span>index d631f12..faf8f86 100644</span><br><span>--- a/src/mainboard/lenovo/t430s/acpi/ec.asl</span><br><span>+++ b/src/mainboard/lenovo/t430s/acpi/ec.asl</span><br><span>@@ -15,6 +15,7 @@</span><br><span>  */</span><br><span> </span><br><span> #include <ec/lenovo/h8/acpi/ec.asl></span><br><span style="color: hsl(120, 100%, 40%);">+#include <ec/lenovo/pmh7/acpi/pmh7.asl></span><br><span> </span><br><span> Scope(\_SB.PCI0.LPCB.EC)</span><br><span> {</span><br><span>diff --git a/src/mainboard/lenovo/t430s/cmos.default b/src/mainboard/lenovo/t430s/cmos.default</span><br><span>index 979f132..e65869b 100644</span><br><span>--- a/src/mainboard/lenovo/t430s/cmos.default</span><br><span>+++ b/src/mainboard/lenovo/t430s/cmos.default</span><br><span>@@ -14,3 +14,4 @@</span><br><span> trackpoint=Enable</span><br><span> backlight=Both</span><br><span> usb_always_on=Disable</span><br><span style="color: hsl(120, 100%, 40%);">+hybrid_graphics_mode=Integrated Only</span><br><span>diff --git a/src/mainboard/lenovo/t430s/cmos.layout b/src/mainboard/lenovo/t430s/cmos.layout</span><br><span>index 538e624..1689b64 100644</span><br><span>--- a/src/mainboard/lenovo/t430s/cmos.layout</span><br><span>+++ b/src/mainboard/lenovo/t430s/cmos.layout</span><br><span>@@ -76,7 +76,8 @@</span><br><span> </span><br><span> # coreboot config options: northbridge</span><br><span> 432          3       e       11       gfx_uma_size</span><br><span style="color: hsl(0, 100%, 40%);">-#435         5       r       0        unused</span><br><span style="color: hsl(120, 100%, 40%);">+435          2       e       12       hybrid_graphics_mode</span><br><span style="color: hsl(120, 100%, 40%);">+#437         3       r       0        unused</span><br><span> 440          8       h       0        volume</span><br><span> </span><br><span> # SandyBridge MRC Scrambler Seed values</span><br><span>diff --git a/src/mainboard/lenovo/t430s/devicetree.cb b/src/mainboard/lenovo/t430s/devicetree.cb</span><br><span>index b14d60c..376ea07 100644</span><br><span>--- a/src/mainboard/lenovo/t430s/devicetree.cb</span><br><span>+++ b/src/mainboard/lenovo/t430s/devicetree.cb</span><br><span>@@ -159,6 +159,20 @@</span><br><span>                                         register "bdc_gpio_num" = "54"</span><br><span>                                   register "bdc_gpio_lvl" = "0"</span><br><span>                            end</span><br><span style="color: hsl(120, 100%, 40%);">+                           chip drivers/lenovo/hybrid_graphics</span><br><span style="color: hsl(120, 100%, 40%);">+                                   device pnp ff.f on end # dummy</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                                      register "detect_gpio" = "21"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                                   register "has_panel_hybrid_gpio" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "panel_hybrid_gpio" = "52"</span><br><span style="color: hsl(120, 100%, 40%);">+                                       register "panel_integrated_lvl" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                                   register "has_backlight_gpio" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                       register "has_dgpu_power_gpio" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                                    register "has_thinker1" = "1"</span><br><span style="color: hsl(120, 100%, 40%);">+                             end</span><br><span>                  end # LPC Controller</span><br><span>                         device pci 1f.2 on</span><br><span>                           subsystemid 0x17aa 0x21fb</span><br><span>diff --git a/src/mainboard/lenovo/t430s/dsdt.asl b/src/mainboard/lenovo/t430s/dsdt.asl</span><br><span>index c549988..3893114 100644</span><br><span>--- a/src/mainboard/lenovo/t430s/dsdt.asl</span><br><span>+++ b/src/mainboard/lenovo/t430s/dsdt.asl</span><br><span>@@ -51,6 +51,9 @@</span><br><span>               }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ #include <drivers/lenovo/hybrid_graphics/acpi/gpu.asl></span><br><span style="color: hsl(120, 100%, 40%);">+  #include <drivers/nvidia/optimus/acpi/optimus.asl></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   /* Chipset specific sleep states */</span><br><span>  #include <southbridge/intel/bd82x6x/acpi/sleepstates.asl></span><br><span> }</span><br><span>diff --git a/src/mainboard/lenovo/t430s/romstage.c b/src/mainboard/lenovo/t430s/romstage.c</span><br><span>index 3f6d9f2..8b7e396 100644</span><br><span>--- a/src/mainboard/lenovo/t430s/romstage.c</span><br><span>+++ b/src/mainboard/lenovo/t430s/romstage.c</span><br><span>@@ -20,8 +20,35 @@</span><br><span> #include <device/pci_def.h></span><br><span> #include <console/console.h></span><br><span> #include <northbridge/intel/sandybridge/raminit_native.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <drivers/lenovo/hybrid_graphics/hybrid_graphics.h></span><br><span> #include <southbridge/intel/bd82x6x/pch.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void hybrid_graphics_init(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        bool peg, igd;</span><br><span style="color: hsl(120, 100%, 40%);">+        u32 reg32;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  early_hybrid_graphics(&igd, &peg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (peg && igd)</span><br><span style="color: hsl(120, 100%, 40%);">+               return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Hide disabled devices */</span><br><span style="color: hsl(120, 100%, 40%);">+   reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);</span><br><span style="color: hsl(120, 100%, 40%);">+   reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (peg)</span><br><span style="color: hsl(120, 100%, 40%);">+              reg32 |= DEVEN_PEG10;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (igd)</span><br><span style="color: hsl(120, 100%, 40%);">+              reg32 |= DEVEN_IGD;</span><br><span style="color: hsl(120, 100%, 40%);">+   else</span><br><span style="color: hsl(120, 100%, 40%);">+          /* Disable IGD VGA decode, no GTT or GFX stolen */</span><br><span style="color: hsl(120, 100%, 40%);">+            pci_write_config16(PCI_DEV(0, 0, 0), GGC, 2);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       pci_write_config32(PCI_DEV(0, 0, 0), DEVEN, reg32);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> void pch_enable_lpc(void)</span><br><span> {</span><br><span>   /* EC Decode Range Port60/64, Port62/66 */</span><br><span>@@ -64,6 +91,7 @@</span><br><span> }</span><br><span> </span><br><span> void mainboard_early_init(int s3resume) {</span><br><span style="color: hsl(120, 100%, 40%);">+  hybrid_graphics_init();</span><br><span> }</span><br><span> </span><br><span> void mainboard_config_superio(void)</span><br><span>diff --git a/src/mainboard/lenovo/t520/acpi/ec.asl b/src/mainboard/lenovo/t520/acpi/ec.asl</span><br><span>index d631f12..faf8f86 100644</span><br><span>--- a/src/mainboard/lenovo/t520/acpi/ec.asl</span><br><span>+++ b/src/mainboard/lenovo/t520/acpi/ec.asl</span><br><span>@@ -15,6 +15,7 @@</span><br><span>  */</span><br><span> </span><br><span> #include <ec/lenovo/h8/acpi/ec.asl></span><br><span style="color: hsl(120, 100%, 40%);">+#include <ec/lenovo/pmh7/acpi/pmh7.asl></span><br><span> </span><br><span> Scope(\_SB.PCI0.LPCB.EC)</span><br><span> {</span><br><span>diff --git a/src/mainboard/lenovo/t520/dsdt.asl b/src/mainboard/lenovo/t520/dsdt.asl</span><br><span>index 7db8344..39d6d29 100644</span><br><span>--- a/src/mainboard/lenovo/t520/dsdt.asl</span><br><span>+++ b/src/mainboard/lenovo/t520/dsdt.asl</span><br><span>@@ -50,6 +50,9 @@</span><br><span>            }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ #include <drivers/lenovo/hybrid_graphics/acpi/gpu.asl></span><br><span style="color: hsl(120, 100%, 40%);">+  #include <drivers/nvidia/optimus/acpi/optimus.asl></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   /* Chipset specific sleep states */</span><br><span>  #include <southbridge/intel/bd82x6x/acpi/sleepstates.asl></span><br><span> }</span><br><span>diff --git a/src/mainboard/lenovo/t520/romstage.c b/src/mainboard/lenovo/t520/romstage.c</span><br><span>index 328ae37..4fcd651 100644</span><br><span>--- a/src/mainboard/lenovo/t520/romstage.c</span><br><span>+++ b/src/mainboard/lenovo/t520/romstage.c</span><br><span>@@ -42,6 +42,9 @@</span><br><span> </span><br><span>    early_hybrid_graphics(&igd, &peg);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        if (peg && igd)</span><br><span style="color: hsl(120, 100%, 40%);">+               return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    /* Hide disabled devices */</span><br><span>  reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);</span><br><span>  reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);</span><br><span>diff --git a/src/mainboard/lenovo/t530/acpi/ec.asl b/src/mainboard/lenovo/t530/acpi/ec.asl</span><br><span>index d631f12..faf8f86 100644</span><br><span>--- a/src/mainboard/lenovo/t530/acpi/ec.asl</span><br><span>+++ b/src/mainboard/lenovo/t530/acpi/ec.asl</span><br><span>@@ -15,6 +15,7 @@</span><br><span>  */</span><br><span> </span><br><span> #include <ec/lenovo/h8/acpi/ec.asl></span><br><span style="color: hsl(120, 100%, 40%);">+#include <ec/lenovo/pmh7/acpi/pmh7.asl></span><br><span> </span><br><span> Scope(\_SB.PCI0.LPCB.EC)</span><br><span> {</span><br><span>diff --git a/src/mainboard/lenovo/t530/cmos.layout b/src/mainboard/lenovo/t530/cmos.layout</span><br><span>index 9a099f5..a47b7e8 100644</span><br><span>--- a/src/mainboard/lenovo/t530/cmos.layout</span><br><span>+++ b/src/mainboard/lenovo/t530/cmos.layout</span><br><span>@@ -3,6 +3,7 @@</span><br><span> ##</span><br><span> ## Copyright (C) 2007-2008 coresystems GmbH</span><br><span> ## Copyright (C) 2014 Vladimir Serbinenko</span><br><span style="color: hsl(120, 100%, 40%);">+## Copyright (C) 2018 Evgeny Zinoviev</span><br><span> ##</span><br><span> ## This program is free software; you can redistribute it and/or modify</span><br><span> ## it under the terms of the GNU General Public License as published by</span><br><span>@@ -129,6 +130,7 @@</span><br><span> 11    6     224M</span><br><span> 12    0     Integrated Only</span><br><span> 12    1     Discrete Only</span><br><span style="color: hsl(120, 100%, 40%);">+12    2     Dual Graphics</span><br><span> 13    0     Disable</span><br><span> 13    1     AC and battery</span><br><span> 13    2     AC only</span><br><span>diff --git a/src/mainboard/lenovo/t530/dsdt.asl b/src/mainboard/lenovo/t530/dsdt.asl</span><br><span>index 7db8344..39d6d29 100644</span><br><span>--- a/src/mainboard/lenovo/t530/dsdt.asl</span><br><span>+++ b/src/mainboard/lenovo/t530/dsdt.asl</span><br><span>@@ -50,6 +50,9 @@</span><br><span>              }</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ #include <drivers/lenovo/hybrid_graphics/acpi/gpu.asl></span><br><span style="color: hsl(120, 100%, 40%);">+  #include <drivers/nvidia/optimus/acpi/optimus.asl></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>   /* Chipset specific sleep states */</span><br><span>  #include <southbridge/intel/bd82x6x/acpi/sleepstates.asl></span><br><span> }</span><br><span>diff --git a/src/mainboard/lenovo/t530/romstage.c b/src/mainboard/lenovo/t530/romstage.c</span><br><span>index ba7a229..88e07c1 100644</span><br><span>--- a/src/mainboard/lenovo/t530/romstage.c</span><br><span>+++ b/src/mainboard/lenovo/t530/romstage.c</span><br><span>@@ -34,6 +34,9 @@</span><br><span> </span><br><span>    early_hybrid_graphics(&igd, &peg);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        if (peg && igd)</span><br><span style="color: hsl(120, 100%, 40%);">+               return;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    /* Hide disabled devices */</span><br><span>  reg32 = pci_read_config32(PCI_DEV(0, 0, 0), DEVEN);</span><br><span>  reg32 &= ~(DEVEN_PEG10 | DEVEN_IGD);</span><br><span>diff --git a/src/mainboard/lenovo/t530/variants/t530/devicetree.cb b/src/mainboard/lenovo/t530/variants/t530/devicetree.cb</span><br><span>index 0da05e0..4dcdc9d 100644</span><br><span>--- a/src/mainboard/lenovo/t530/variants/t530/devicetree.cb</span><br><span>+++ b/src/mainboard/lenovo/t530/variants/t530/devicetree.cb</span><br><span>@@ -157,7 +157,7 @@</span><br><span>                                      register "has_backlight_gpio" = "0"</span><br><span>                                      register "has_dgpu_power_gpio" = "0"</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                                    register "has_thinker1" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                     register "has_thinker1" = "1"</span><br><span>                            end</span><br><span>                  end # LPC bridge</span><br><span>                     device pci 1f.2 on end # SATA Controller 1</span><br><span>diff --git a/src/mainboard/lenovo/t530/variants/w530/devicetree.cb b/src/mainboard/lenovo/t530/variants/w530/devicetree.cb</span><br><span>index d9d9df5..7a72b26 100644</span><br><span>--- a/src/mainboard/lenovo/t530/variants/w530/devicetree.cb</span><br><span>+++ b/src/mainboard/lenovo/t530/variants/w530/devicetree.cb</span><br><span>@@ -179,7 +179,7 @@</span><br><span>                                    register "has_backlight_gpio" = "0"</span><br><span>                                      register "has_dgpu_power_gpio" = "0"</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                                    register "has_thinker1" = "0"</span><br><span style="color: hsl(120, 100%, 40%);">+                                     register "has_thinker1" = "1"</span><br><span>                            end</span><br><span>                  end</span><br><span>                  device pci 1f.2 on # SATA Controller 1</span><br><span>diff --git a/src/northbridge/intel/sandybridge/acpi/peg.asl b/src/northbridge/intel/sandybridge/acpi/peg.asl</span><br><span>index f98a4ce..89c2e25 100644</span><br><span>--- a/src/northbridge/intel/sandybridge/acpi/peg.asl</span><br><span>+++ b/src/northbridge/intel/sandybridge/acpi/peg.asl</span><br><span>@@ -28,6 +28,44 @@</span><br><span>     {</span><br><span>            Name(_ADR, 0x00000000)</span><br><span>       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   OperationRegion (RPCS, PCI_Config, 0x00, 0x100)</span><br><span style="color: hsl(120, 100%, 40%);">+       Field (RPCS, AnyAcc, NoLock, Preserve)</span><br><span style="color: hsl(120, 100%, 40%);">+        {</span><br><span style="color: hsl(120, 100%, 40%);">+             Offset (0xb0),  // Link Capabilities</span><br><span style="color: hsl(120, 100%, 40%);">+          , 4,</span><br><span style="color: hsl(120, 100%, 40%);">+          LNKD, 1,        // Link Disable</span><br><span style="color: hsl(120, 100%, 40%);">+               RTRL, 1,        // Retrain Link</span><br><span style="color: hsl(120, 100%, 40%);">+               Offset (0xb2),  // Link Status</span><br><span style="color: hsl(120, 100%, 40%);">+                , 10,</span><br><span style="color: hsl(120, 100%, 40%);">+         LNKT, 1,        // Link Training</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   Name (DEVP, 0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      Method (_ON)</span><br><span style="color: hsl(120, 100%, 40%);">+  {</span><br><span style="color: hsl(120, 100%, 40%);">+             Store(Zero, LNKD)</span><br><span style="color: hsl(120, 100%, 40%);">+             Store(One, RTRL)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            Store (0x32, Local1)</span><br><span style="color: hsl(120, 100%, 40%);">+          While (Local1)</span><br><span style="color: hsl(120, 100%, 40%);">+                {</span><br><span style="color: hsl(120, 100%, 40%);">+                     Sleep (10)</span><br><span style="color: hsl(120, 100%, 40%);">+                    If (LEqual(LNKT, 0))</span><br><span style="color: hsl(120, 100%, 40%);">+                  {</span><br><span style="color: hsl(120, 100%, 40%);">+                             Break</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   Decrement (Local1)</span><br><span style="color: hsl(120, 100%, 40%);">+            }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   Method (_OFF)</span><br><span style="color: hsl(120, 100%, 40%);">+ {</span><br><span style="color: hsl(120, 100%, 40%);">+             Store(One, LNKD)</span><br><span style="color: hsl(120, 100%, 40%);">+              Sleep (10)</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span> }</span><br><span> </span><br><span> Device (PEG1)</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/28380">change 28380</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/28380"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I277808d6c1d8bd6e0a267a53f25471597698f8d5 </div>
<div style="display:none"> Gerrit-Change-Number: 28380 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Evgeny Zinoviev <me@ch1p.com> </div>