<p>Patrick Rudolph has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/27510">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">superio/nuvoton/npcd378: Add ACPI code for S3 resume<br><br>Configure SuperIO on shutdown to keep devices enabled, set green LED<br>to fading on sleep and normal on wake.<br>Add SSDT to write LDN4 IOBASE addresses stored in devicetree.cb.<br><br>Tested on HP8200:<br>* Wakes from power button or USB keyboard.<br>* LED is fading<br><br>Change-Id: I2035249a39616aa2d87bd93f9e49c70d231546cc<br>Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com><br>---<br>M src/superio/nuvoton/npcd378/acpi/superio.asl<br>M src/superio/nuvoton/npcd378/superio.c<br>2 files changed, 206 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/10/27510/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/superio/nuvoton/npcd378/acpi/superio.asl b/src/superio/nuvoton/npcd378/acpi/superio.asl</span><br><span>index 963704e..295ac2b 100644</span><br><span>--- a/src/superio/nuvoton/npcd378/acpi/superio.asl</span><br><span>+++ b/src/superio/nuvoton/npcd378/acpi/superio.asl</span><br><span>@@ -165,4 +165,156 @@</span><br><span>         #define SUPERIO_PNP_IO0 0x08, 0x08</span><br><span>   #include <superio/acpi/pnp_generic.asl></span><br><span> #endif</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    // generated by SSDT</span><br><span style="color: hsl(120, 100%, 40%);">+  External(SWB, IntObj)</span><br><span style="color: hsl(120, 100%, 40%);">+ External(SWL, IntObj)</span><br><span style="color: hsl(120, 100%, 40%);">+ OperationRegion (SWCR, SystemIO, SWB, SWL)</span><br><span style="color: hsl(120, 100%, 40%);">+    Field (SWCR, ByteAcc, NoLock, Preserve)</span><br><span style="color: hsl(120, 100%, 40%);">+       {</span><br><span style="color: hsl(120, 100%, 40%);">+             LEDC,   8,</span><br><span style="color: hsl(120, 100%, 40%);">+            SWCC,   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%);">+   // generated by SSDT</span><br><span style="color: hsl(120, 100%, 40%);">+  External(RNB, IntObj)</span><br><span style="color: hsl(120, 100%, 40%);">+ External(RNL, IntObj)</span><br><span style="color: hsl(120, 100%, 40%);">+ OperationRegion (RNTR, SystemIO, RNB, RNL)</span><br><span style="color: hsl(120, 100%, 40%);">+    Field (RNTR, ByteAcc, NoLock, Preserve)</span><br><span style="color: hsl(120, 100%, 40%);">+       {</span><br><span style="color: hsl(120, 100%, 40%);">+             GPES,   8,</span><br><span style="color: hsl(120, 100%, 40%);">+            GPEE,   8,</span><br><span style="color: hsl(120, 100%, 40%);">+            Offset (0x08),</span><br><span style="color: hsl(120, 100%, 40%);">+                GPS0,   8,</span><br><span style="color: hsl(120, 100%, 40%);">+            GPS1,   8,</span><br><span style="color: hsl(120, 100%, 40%);">+            GPS2,   8,</span><br><span style="color: hsl(120, 100%, 40%);">+            GPS3,   8,</span><br><span style="color: hsl(120, 100%, 40%);">+            GPE0,   8,</span><br><span style="color: hsl(120, 100%, 40%);">+            GPE1,   8,</span><br><span style="color: hsl(120, 100%, 40%);">+            GPE2,   8,</span><br><span style="color: hsl(120, 100%, 40%);">+            GPE3,   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%);">+   Name (MSFG, One)</span><br><span style="color: hsl(120, 100%, 40%);">+      Name (KBFG, One)</span><br><span style="color: hsl(120, 100%, 40%);">+      Name (PMFG, Zero) // Wake event backup</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef SUPERIO_SHOW_KBC</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#if defined(SUPERIO_KBC_LDN)</span><br><span style="color: hsl(120, 100%, 40%);">+#define _PS2_KB SUPERIO_ID(KBD, SUPERIO_KBC_LDN)</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+#define _PS2_KB PS2K</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+      Scope (_PS2_KB)</span><br><span style="color: hsl(120, 100%, 40%);">+       {</span><br><span style="color: hsl(120, 100%, 40%);">+             Method (_PSW, 1, NotSerialized)</span><br><span style="color: hsl(120, 100%, 40%);">+               {</span><br><span style="color: hsl(120, 100%, 40%);">+                     KBFG = Arg0</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 (_PRW, 0, NotSerialized)</span><br><span style="color: hsl(120, 100%, 40%);">+               {</span><br><span style="color: hsl(120, 100%, 40%);">+                     Return (Package (0x02) {0x08, 0x03})</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%);">+#if defined(SUPERIO_KBC_PS2M)</span><br><span style="color: hsl(120, 100%, 40%);">+#define _PS2_M SUPERIO_ID(PS2, SUPERIO_KBC_PS2M)</span><br><span style="color: hsl(120, 100%, 40%);">+#elif defined(SUPERIO_KBC_PS2LDN)</span><br><span style="color: hsl(120, 100%, 40%);">+#define _PS2_M SUPERIO_ID(PS2, SUPERIO_KBC_PS2LDN)</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+#define _PS2_M PS2M</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+       Scope (_PS2_M)</span><br><span style="color: hsl(120, 100%, 40%);">+        {</span><br><span style="color: hsl(120, 100%, 40%);">+             Method (_PSW, 1, NotSerialized)</span><br><span style="color: hsl(120, 100%, 40%);">+               {</span><br><span style="color: hsl(120, 100%, 40%);">+                     MSFG = Arg0</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 (_PRW, 0, NotSerialized)</span><br><span style="color: hsl(120, 100%, 40%);">+               {</span><br><span style="color: hsl(120, 100%, 40%);">+                     Return (Package (0x02) {0x08, 0x03})</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 (SIOH, 0, NotSerialized)</span><br><span style="color: hsl(120, 100%, 40%);">+       {</span><br><span style="color: hsl(120, 100%, 40%);">+             If ((PMFG & 0xE8))</span><br><span style="color: hsl(120, 100%, 40%);">+                {</span><br><span style="color: hsl(120, 100%, 40%);">+                     Notify (_PS2_KB, 0x02)</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 ((PMFG & 0x10))</span><br><span style="color: hsl(120, 100%, 40%);">+                {</span><br><span style="color: hsl(120, 100%, 40%);">+                     Notify (_PS2_M, 0x02)</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%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+      Method (SIOH, 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%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* SuperIO sleep method */</span><br><span style="color: hsl(120, 100%, 40%);">+    Method (SIOS, 1, NotSerialized)</span><br><span style="color: hsl(120, 100%, 40%);">+       {</span><br><span style="color: hsl(120, 100%, 40%);">+             If ((0x05 != Arg0))</span><br><span style="color: hsl(120, 100%, 40%);">+           {</span><br><span style="color: hsl(120, 100%, 40%);">+                     /* Set PS/2 powerstate in S3 */</span><br><span style="color: hsl(120, 100%, 40%);">+                       If (KBFG)</span><br><span style="color: hsl(120, 100%, 40%);">+                     {</span><br><span style="color: hsl(120, 100%, 40%);">+                             GPE2 |= 0xE8</span><br><span style="color: hsl(120, 100%, 40%);">+                  }</span><br><span style="color: hsl(120, 100%, 40%);">+                     Else</span><br><span style="color: hsl(120, 100%, 40%);">+                  {</span><br><span style="color: hsl(120, 100%, 40%);">+                             GPE2 &= 0x17</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 (MSFG)</span><br><span style="color: hsl(120, 100%, 40%);">+                     {</span><br><span style="color: hsl(120, 100%, 40%);">+                             GPE2 |= 0x10</span><br><span style="color: hsl(120, 100%, 40%);">+                  }</span><br><span style="color: hsl(120, 100%, 40%);">+                     Else</span><br><span style="color: hsl(120, 100%, 40%);">+                  {</span><br><span style="color: hsl(120, 100%, 40%);">+                             GPE2 &= 0xEF</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%);">+                   /* Enable wake on GPE */</span><br><span style="color: hsl(120, 100%, 40%);">+                      GPEE = One</span><br><span style="color: hsl(120, 100%, 40%);">+                    If ((0x03 == Arg0))</span><br><span style="color: hsl(120, 100%, 40%);">+                   {</span><br><span style="color: hsl(120, 100%, 40%);">+                             /* green LED fading */</span><br><span style="color: hsl(120, 100%, 40%);">+                                Local1 = LEDC</span><br><span style="color: hsl(120, 100%, 40%);">+                         Local1 &= 0xE0</span><br><span style="color: hsl(120, 100%, 40%);">+                            LEDC = (Local1 | 0x1C)</span><br><span style="color: hsl(120, 100%, 40%);">+                                Local1 = SWCC</span><br><span style="color: hsl(120, 100%, 40%);">+                         Local1 &= 0xBF</span><br><span style="color: hsl(120, 100%, 40%);">+                            SWCC = (Local1 | 0x40)</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%);">+           GPE0 = 0x10</span><br><span style="color: hsl(120, 100%, 40%);">+           GPE1 = 0x20</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%);">+   /* SuperIO wake method */</span><br><span style="color: hsl(120, 100%, 40%);">+     Method (SIOW, 1, NotSerialized)</span><br><span style="color: hsl(120, 100%, 40%);">+       {</span><br><span style="color: hsl(120, 100%, 40%);">+             /* Store wake status */</span><br><span style="color: hsl(120, 100%, 40%);">+               PMFG = GPS2</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         /* Disable wake on GPE */</span><br><span style="color: hsl(120, 100%, 40%);">+             GPEE = Zero</span><br><span style="color: hsl(120, 100%, 40%);">+           GPE0 = Zero</span><br><span style="color: hsl(120, 100%, 40%);">+           GPE1 = Zero</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         /* green LED normal */</span><br><span style="color: hsl(120, 100%, 40%);">+                Local1 = LEDC</span><br><span style="color: hsl(120, 100%, 40%);">+         Local1 &= 0xE0</span><br><span style="color: hsl(120, 100%, 40%);">+            LEDC = (Local1 | 0x1E)</span><br><span style="color: hsl(120, 100%, 40%);">+                Local1 = SWCC</span><br><span style="color: hsl(120, 100%, 40%);">+         SWCC = (Local1 & 0xBF)</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>\ No newline at end of file</span><br><span>diff --git a/src/superio/nuvoton/npcd378/superio.c b/src/superio/nuvoton/npcd378/superio.c</span><br><span>index 85b02d3..bed138c 100644</span><br><span>--- a/src/superio/nuvoton/npcd378/superio.c</span><br><span>+++ b/src/superio/nuvoton/npcd378/superio.c</span><br><span>@@ -25,6 +25,8 @@</span><br><span> #include <pc80/keyboard.h></span><br><span> #include <stdlib.h></span><br><span> #include <superio/conf_mode.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/acpi.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/acpigen.h></span><br><span> </span><br><span> #include "npcd378.h"</span><br><span> </span><br><span>@@ -101,6 +103,53 @@</span><br><span>     }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)</span><br><span style="color: hsl(120, 100%, 40%);">+static void npcd378_ssdt(struct device *dev)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct resource *res;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *scope = acpi_device_path(dev);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!scope) {</span><br><span style="color: hsl(120, 100%, 40%);">+         printk(BIOS_ERR, "%s: Missing ACPI scope\n", dev_path(dev));</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (dev->path.pnp.device) {</span><br><span style="color: hsl(120, 100%, 40%);">+    case NPCD378_PWR: {</span><br><span style="color: hsl(120, 100%, 40%);">+           res = find_resource(dev, PNP_IDX_IO0);</span><br><span style="color: hsl(120, 100%, 40%);">+                if (!res || !res->base) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  printk(BIOS_ERR, "NPCD378: LDN%u IOBASE not set.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                               NPCD378_PWR);</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%);">+           acpigen_write_scope(scope);</span><br><span style="color: hsl(120, 100%, 40%);">+           acpigen_write_name_integer("SWB", res->base);</span><br><span style="color: hsl(120, 100%, 40%);">+            acpigen_write_name_integer("SWL", res->size);</span><br><span style="color: hsl(120, 100%, 40%);">+            acpigen_pop_len(); /* pop scope */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          res = find_resource(dev, PNP_IDX_IO1);</span><br><span style="color: hsl(120, 100%, 40%);">+                if (!res || !res->base) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  printk(BIOS_ERR, "NPCD378: LDN%u IOBASE2 not set.\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                              NPCD378_PWR);</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%);">+           acpigen_write_scope(scope);</span><br><span style="color: hsl(120, 100%, 40%);">+           acpigen_write_name_integer("RNB", res->base);</span><br><span style="color: hsl(120, 100%, 40%);">+            acpigen_write_name_integer("RNL", res->size);</span><br><span style="color: hsl(120, 100%, 40%);">+            acpigen_pop_len(); /* pop scope */</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%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const char *npcd378_acpi_name(const struct device *dev)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     return "SIO0";</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static struct device_operations ops = {</span><br><span>     .read_resources   = pnp_read_resources,</span><br><span>      .set_resources    = pnp_set_resources,</span><br><span>@@ -108,6 +157,10 @@</span><br><span>        .enable           = pnp_alt_enable,</span><br><span>  .init             = npcd378_init,</span><br><span>    .ops_pnp_mode     = &pnp_conf_mode_8787_aa,</span><br><span style="color: hsl(120, 100%, 40%);">+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)</span><br><span style="color: hsl(120, 100%, 40%);">+      .acpi_fill_ssdt_generator = npcd378_ssdt,</span><br><span style="color: hsl(120, 100%, 40%);">+     .acpi_name = npcd378_acpi_name,</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span> };</span><br><span> </span><br><span> static struct pnp_info pnp_dev_info[] = {</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/27510">change 27510</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/27510"/><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: I2035249a39616aa2d87bd93f9e49c70d231546cc </div>
<div style="display:none"> Gerrit-Change-Number: 27510 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Patrick Rudolph <patrick.rudolph@9elements.com> </div>