<p>Patrick Rudolph has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/20985">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">drvs/ec/lenovo/h8: Add ssdt generator<br><br>Add SSDT generator to add dynamic ACPI code.<br>Implement GBDC and SBDC for thinkpad_acpi kernel module.<br><br>Tested on Lenovo T430:<br>The bluetooth module is detected and can be powercycled using network manager.<br><br>Change-Id: Ida825196650966194a883945896a038b0790fe45<br>Signed-off-by: Patrick Rudolph <siro@das-labor.org><br>---<br>M src/ec/lenovo/h8/Makefile.inc<br>M src/ec/lenovo/h8/h8.c<br>M src/ec/lenovo/h8/h8.h<br>A src/ec/lenovo/h8/ssdt.c<br>4 files changed, 136 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/85/20985/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/src/ec/lenovo/h8/Makefile.inc b/src/ec/lenovo/h8/Makefile.inc<br>index a02543a..5c85e6f 100644<br>--- a/src/ec/lenovo/h8/Makefile.inc<br>+++ b/src/ec/lenovo/h8/Makefile.inc<br>@@ -3,6 +3,7 @@<br> ramstage-y += h8.c<br> ramstage-y += bluetooth.c<br> ramstage-y += wwan.c<br>+ramstage-$(CONFIG_HAVE_ACPI_TABLES) += ssdt.c<br> smm-y += smm.c<br> <br> endif<br>diff --git a/src/ec/lenovo/h8/h8.c b/src/ec/lenovo/h8/h8.c<br>index 882ac02..8b8f49f 100644<br>--- a/src/ec/lenovo/h8/h8.c<br>+++ b/src/ec/lenovo/h8/h8.c<br>@@ -181,10 +181,21 @@<br>        pc_keyboard_init(NO_AUX_DEVICE);<br> }<br> <br>+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)<br>+static const char* h8_acpi_name(struct device *dev)<br>+{<br>+  return "EC";<br>+}<br>+#endif<br>+<br> struct device_operations h8_dev_ops = {<br> #if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLES)<br>      .get_smbios_strings = h8_smbios_strings,<br> #endif<br>+#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)<br>+  .acpi_fill_ssdt_generator = h8_ssdt_generator,<br>+       .acpi_name = h8_acpi_name,<br>+#endif<br>   .init = h8_init,<br> };<br> <br>diff --git a/src/ec/lenovo/h8/h8.h b/src/ec/lenovo/h8/h8.h<br>index 4175463..951d22f 100644<br>--- a/src/ec/lenovo/h8/h8.h<br>+++ b/src/ec/lenovo/h8/h8.h<br>@@ -39,6 +39,8 @@<br> bool h8_wwan_nv_enable(void);<br> bool h8_has_wwan(struct device *dev);<br> <br>+void h8_ssdt_generator(struct device *dev);<br>+<br> /* EC registers */<br> #define H8_CONFIG0 0x00<br> #define H8_CONFIG0_EVENTS_ENABLE  0x02<br>diff --git a/src/ec/lenovo/h8/ssdt.c b/src/ec/lenovo/h8/ssdt.c<br>new file mode 100644<br>index 0000000..eb9f2c1<br>--- /dev/null<br>+++ b/src/ec/lenovo/h8/ssdt.c<br>@@ -0,0 +1,122 @@<br>+/*<br>+ * This file is part of the coreboot project.<br>+ *<br>+ * Copyright (C) 2017 Patrick Rudolph <siro@das-labor.org><br>+ *<br>+ * This program is free software; you can redistribute it and/or modify<br>+ * it under the terms of the GNU General Public License as published by<br>+ * the Free Software Foundation; version 2 of the License.<br>+ *<br>+ * This program is distributed in the hope that it will be useful,<br>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>+ * GNU General Public License for more details.<br>+ */<br>+<br>+#include <southbridge/intel/common/gpio.h><br>+#include <console/console.h><br>+#include <device/device.h><br>+#include <ec/acpi/ec.h><br>+#include <arch/acpigen.h><br>+#include <option.h><br>+#include <string.h><br>+<br>+#include "h8.h"<br>+#include "chip.h"<br>+<br>+static char *h8_dsdt_scope(struct device *dev, const char *scope)<br>+{<br>+      static char buf[DEVICE_PATH_MAX] = {};<br>+       const char *path = acpi_device_path(dev);<br>+<br>+ memset(buf, 0, sizeof(buf));<br>+ snprintf(buf, sizeof(buf) - 1, "%s.%s", path, scope);<br>+<br>+   return buf;<br>+}<br>+<br>+/* Generate ACPI methods GBDC and SBDC */<br>+static void h8_dsdt_bluetooth(struct device *dev)<br>+{<br>+       const bool has_bdc = h8_has_bdc(dev);<br>+<br>+     /* Method (GBDC, 0) */<br>+       acpigen_write_method("GBDC", 0);<br>+   /* Store(Zero, Local0) */<br>+    acpigen_write_store_ops(ZERO_OP, LOCAL0_OP);<br>+ if (has_bdc) {<br>+               /* BDC present */<br>+            /* Or(Local0, One, Local0) */<br>+                acpigen_write_or(LOCAL0_OP, ONE_OP, LOCAL0_OP);<br>+<br>+           /* If(LEqual(\_SB.PCI0.LPCB.EC.BTEB, One)) */<br>+                acpigen_write_if();<br>+          acpigen_emit_byte(LEQUAL_OP);<br>+                acpigen_emit_namestring(h8_dsdt_scope(dev, "BTEB"));<br>+               acpigen_emit_byte(ONE_OP);<br>+<br>+                /* Or(Local0, 2, Local0) */<br>+          acpigen_emit_byte(OR_OP);<br>+            acpigen_emit_byte(LOCAL0_OP);<br>+                acpigen_write_integer(2);<br>+            acpigen_emit_byte(LOCAL0_OP);<br>+                acpigen_pop_len(); /* If */<br>+<br>+               /* State at resume: Enabled */<br>+               /* Or(Local0, 4, Local0) */<br>+          acpigen_emit_byte(OR_OP);<br>+            acpigen_emit_byte(LOCAL0_OP);<br>+                acpigen_write_integer(4);<br>+            acpigen_emit_byte(LOCAL0_OP);<br>+        }<br>+    /* Return(Local0) */<br>+ acpigen_emit_byte(RETURN_OP);<br>+        acpigen_emit_byte(LOCAL0_OP);<br>+        acpigen_pop_len(); /* Method */<br>+<br>+   /* Method (SBDC, 0) */<br>+       acpigen_write_method("SBDC", 1);<br>+   if (has_bdc) {<br>+               /* And(Arg0, 2, Local0) */<br>+           acpigen_emit_byte(AND_OP);<br>+           acpigen_emit_byte(ARG0_OP);<br>+          acpigen_write_integer(2);<br>+            acpigen_emit_byte(LOCAL0_OP);<br>+                /* If(Lequal(Local0, 2)) */<br>+          acpigen_write_if_lequal_op_int(LOCAL0_OP, 2);<br>+                /* Store(One, \_SB.PCI0.LPCB.EC.BTEB) */<br>+             acpigen_write_store();<br>+               acpigen_emit_byte(ONE_OP);<br>+           acpigen_emit_namestring(h8_dsdt_scope(dev, "BTEB"));<br>+               acpigen_pop_len(); /* If */<br>+          /* Else */<br>+           acpigen_write_else();<br>+                /* Store(Zero, \_SB.PCI0.LPCB.EC.BTEB) */<br>+            acpigen_write_store();<br>+               acpigen_emit_byte(ZERO_OP);<br>+          acpigen_emit_namestring(h8_dsdt_scope(dev, "BTEB"));<br>+               acpigen_pop_len(); /* Else */<br>+<br>+             /* FIXME: Implement state at resume */<br>+       }<br>+    acpigen_pop_len(); /* Method */<br>+}<br>+<br>+/*<br>+ * Generates EC SSDT.<br>+ */<br>+void h8_ssdt_generator(struct device *dev)<br>+{<br>+   if (!acpi_device_path(dev))<br>+          return;<br>+<br>+   printk(BIOS_INFO, "ACPI:    * H8\n");<br>+<br>+   /* Scope HKEY */<br>+     acpigen_write_scope(h8_dsdt_scope(dev, "HKEY"));<br>+<br>+        /* Used by thinkpad_acpi */<br>+  h8_dsdt_bluetooth(dev);<br>+<br>+   acpigen_pop_len(); /* Scope HKEY */<br>+}<br></pre><p>To view, visit <a href="https://review.coreboot.org/20985">change 20985</a>. To unsubscribe, 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/20985"/><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: Ida825196650966194a883945896a038b0790fe45 </div>
<div style="display:none"> Gerrit-Change-Number: 20985 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Patrick Rudolph <siro@das-labor.org> </div>