aboutsummaryrefslogtreecommitdiff
path: root/src/ec
diff options
context:
space:
mode:
Diffstat (limited to 'src/ec')
-rw-r--r--src/ec/google/wilco/acpi/ec.asl4
-rw-r--r--src/ec/google/wilco/acpi/ec_ram.asl51
-rw-r--r--src/ec/google/wilco/acpi/event.asl7
-rw-r--r--src/ec/google/wilco/acpi/ucsi.asl157
-rw-r--r--src/ec/google/wilco/chip.c105
5 files changed, 320 insertions, 4 deletions
diff --git a/src/ec/google/wilco/acpi/ec.asl b/src/ec/google/wilco/acpi/ec.asl
index 675ee3778e..4fa887b1b4 100644
--- a/src/ec/google/wilco/acpi/ec.asl
+++ b/src/ec/google/wilco/acpi/ec.asl
@@ -57,6 +57,9 @@ Device (EC0)
If (\DPTE == One) {
W (DWST, Arg1)
}
+
+ /* Initialize UCSI */
+ ^UCSI.INIT ()
}
/*
@@ -165,6 +168,7 @@ Device (EC0)
#include "lid.asl"
#include "platform.asl"
#include "vbtn.asl"
+ #include "ucsi.asl"
#ifdef EC_ENABLE_DPTF
#include "dptf.asl"
#endif
diff --git a/src/ec/google/wilco/acpi/ec_ram.asl b/src/ec/google/wilco/acpi/ec_ram.asl
index 0de39475bc..47e9072dcb 100644
--- a/src/ec/google/wilco/acpi/ec_ram.asl
+++ b/src/ec/google/wilco/acpi/ec_ram.asl
@@ -143,3 +143,54 @@ Name (DWHY, Package () { 0x37, 0xff, WR }) /* DPTF: Write Hysteresis */
Name (DWTQ, Package () { 0x38, 0xff, WR }) /* DPTF: Write Trip Query */
Name (CSOS, Package () { 0xb8, 0xff, WR }) /* OS support for S0ix */
Name (CSEX, Package () { 0xb9, 0xff, WR }) /* OS enter(1)/exit(0) S0ix */
+
+/*
+ * EC UCSI
+ */
+Name (UVR0, Package () { 0x80, 0xff, RD }) /* UCSI Version */
+Name (UVR1, Package () { 0x81, 0xff, RD }) /* UCSI Version */
+Name (UCI0, Package () { 0x84, 0xff, RD }) /* UCSI Change Indicator */
+Name (UCI1, Package () { 0x85, 0xff, RD }) /* UCSI Change Indicator */
+Name (UCI2, Package () { 0x86, 0xff, RD }) /* UCSI Change Indicator */
+Name (UCI3, Package () { 0x87, 0xff, RD }) /* UCSI Change Indicator */
+Name (UCL0, Package () { 0x88, 0xff, WR }) /* UCSI Control */
+Name (UCL1, Package () { 0x89, 0xff, WR }) /* UCSI Control */
+Name (UCL2, Package () { 0x8a, 0xff, WR }) /* UCSI Control */
+Name (UCL3, Package () { 0x8b, 0xff, WR }) /* UCSI Control */
+Name (UCL4, Package () { 0x8c, 0xff, WR }) /* UCSI Control */
+Name (UCL5, Package () { 0x8d, 0xff, WR }) /* UCSI Control */
+Name (UCL6, Package () { 0x8e, 0xff, WR }) /* UCSI Control */
+Name (UCL7, Package () { 0x8f, 0xff, WR }) /* UCSI Control */
+Name (UMI0, Package () { 0x90, 0xff, RD }) /* UCSI Message In */
+Name (UMI1, Package () { 0x91, 0xff, RD }) /* UCSI Message In */
+Name (UMI2, Package () { 0x92, 0xff, RD }) /* UCSI Message In */
+Name (UMI3, Package () { 0x93, 0xff, RD }) /* UCSI Message In */
+Name (UMI4, Package () { 0x94, 0xff, RD }) /* UCSI Message In */
+Name (UMI5, Package () { 0x95, 0xff, RD }) /* UCSI Message In */
+Name (UMI6, Package () { 0x96, 0xff, RD }) /* UCSI Message In */
+Name (UMI7, Package () { 0x97, 0xff, RD }) /* UCSI Message In */
+Name (UMI8, Package () { 0x98, 0xff, RD }) /* UCSI Message In */
+Name (UMI9, Package () { 0x99, 0xff, RD }) /* UCSI Message In */
+Name (UMIA, Package () { 0x9a, 0xff, RD }) /* UCSI Message In */
+Name (UMIB, Package () { 0x9b, 0xff, RD }) /* UCSI Message In */
+Name (UMIC, Package () { 0x9c, 0xff, RD }) /* UCSI Message In */
+Name (UMID, Package () { 0x9d, 0xff, RD }) /* UCSI Message In */
+Name (UMIE, Package () { 0x9e, 0xff, RD }) /* UCSI Message In */
+Name (UMIF, Package () { 0x9f, 0xff, RD }) /* UCSI Message In */
+Name (UMO0, Package () { 0xa0, 0xff, WR }) /* UCSI Message Out */
+Name (UMO1, Package () { 0xa1, 0xff, WR }) /* UCSI Message Out */
+Name (UMO2, Package () { 0xa2, 0xff, WR }) /* UCSI Message Out */
+Name (UMO3, Package () { 0xa3, 0xff, WR }) /* UCSI Message Out */
+Name (UMO4, Package () { 0xa4, 0xff, WR }) /* UCSI Message Out */
+Name (UMO5, Package () { 0xa5, 0xff, WR }) /* UCSI Message Out */
+Name (UMO6, Package () { 0xa6, 0xff, WR }) /* UCSI Message Out */
+Name (UMO7, Package () { 0xa7, 0xff, WR }) /* UCSI Message Out */
+Name (UMO8, Package () { 0xa8, 0xff, WR }) /* UCSI Message Out */
+Name (UMO9, Package () { 0xa9, 0xff, WR }) /* UCSI Message Out */
+Name (UMOA, Package () { 0xaa, 0xff, WR }) /* UCSI Message Out */
+Name (UMOB, Package () { 0xab, 0xff, WR }) /* UCSI Message Out */
+Name (UMOC, Package () { 0xac, 0xff, WR }) /* UCSI Message Out */
+Name (UMOD, Package () { 0xad, 0xff, WR }) /* UCSI Message Out */
+Name (UMOE, Package () { 0xae, 0xff, WR }) /* UCSI Message Out */
+Name (UMOF, Package () { 0xaf, 0xff, WR }) /* UCSI Message Out */
+Name (UCTL, Package () { 0xb0, 0xff, WR }) /* UCSI Control Register */
diff --git a/src/ec/google/wilco/acpi/event.asl b/src/ec/google/wilco/acpi/event.asl
index fab4fc46c3..f6534d3773 100644
--- a/src/ec/google/wilco/acpi/event.asl
+++ b/src/ec/google/wilco/acpi/event.asl
@@ -145,3 +145,10 @@ Method (_Q66, 0, Serialized)
ECQ4 (Local0)
}
}
+
+/* UCSI SCI uses a unique event code */
+Method (_Q79, 0, Serialized)
+{
+ Printf ("EC _Q79 UCSI Event")
+ Notify (^UCSI, 0x80)
+}
diff --git a/src/ec/google/wilco/acpi/ucsi.asl b/src/ec/google/wilco/acpi/ucsi.asl
new file mode 100644
index 0000000000..f69e5924e7
--- /dev/null
+++ b/src/ec/google/wilco/acpi/ucsi.asl
@@ -0,0 +1,157 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2019 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+Device (UCSI)
+{
+ Name (_HID, "GOOG000E")
+ Name (_CID, EisaId ("PNP0CA0"))
+ Name (_DDN, "Wilco EC UCSI")
+ Name (_UID, One)
+ Name (_ADR, Zero)
+ Name (_STA, 0xf)
+
+ /* Value written to EC control register to start UCSI command */
+ Name (UCMD, 0xE0)
+
+ /* Shared memory fields are defined in the SSDT */
+ External (VER0, FieldUnitObj)
+ External (VER1, FieldUnitObj)
+ External (CCI0, FieldUnitObj)
+ External (CCI1, FieldUnitObj)
+ External (CCI2, FieldUnitObj)
+ External (CCI3, FieldUnitObj)
+ External (CTL0, FieldUnitObj)
+ External (CTL1, FieldUnitObj)
+ External (CTL2, FieldUnitObj)
+ External (CTL3, FieldUnitObj)
+ External (CTL4, FieldUnitObj)
+ External (CTL5, FieldUnitObj)
+ External (CTL6, FieldUnitObj)
+ External (CTL7, FieldUnitObj)
+ External (MGI0, FieldUnitObj)
+ External (MGI1, FieldUnitObj)
+ External (MGI2, FieldUnitObj)
+ External (MGI3, FieldUnitObj)
+ External (MGI4, FieldUnitObj)
+ External (MGI5, FieldUnitObj)
+ External (MGI6, FieldUnitObj)
+ External (MGI7, FieldUnitObj)
+ External (MGI8, FieldUnitObj)
+ External (MGI9, FieldUnitObj)
+ External (MGIA, FieldUnitObj)
+ External (MGIB, FieldUnitObj)
+ External (MGIC, FieldUnitObj)
+ External (MGID, FieldUnitObj)
+ External (MGIE, FieldUnitObj)
+ External (MGIF, FieldUnitObj)
+ External (MGO0, FieldUnitObj)
+ External (MGO1, FieldUnitObj)
+ External (MGO2, FieldUnitObj)
+ External (MGO3, FieldUnitObj)
+ External (MGO4, FieldUnitObj)
+ External (MGO5, FieldUnitObj)
+ External (MGO6, FieldUnitObj)
+ External (MGO7, FieldUnitObj)
+ External (MGO8, FieldUnitObj)
+ External (MGO9, FieldUnitObj)
+ External (MGOA, FieldUnitObj)
+ External (MGOB, FieldUnitObj)
+ External (MGOC, FieldUnitObj)
+ External (MGOD, FieldUnitObj)
+ External (MGOE, FieldUnitObj)
+ External (MGOF, FieldUnitObj)
+
+ Method (INIT)
+ {
+ /* Read UCSI version from EC into shared memory */
+ ^VER0 = R (^^UVR0)
+ ^VER1 = R (^^UVR1)
+ }
+
+ Method (_DSM, 4, Serialized)
+ {
+ If (Arg0 != ToUUID ("6f8398c2-7ca4-11e4-ad36-631042b5008f")) {
+ Return (Buffer (One) { Zero })
+ }
+
+ Switch (ToInteger (Arg2))
+ {
+ Case (Zero)
+ {
+ Return (Buffer (One) { 0x07 })
+ }
+ Case (One)
+ {
+ /* Write Message Out */
+ W (^^UMO0, ^MGO0)
+ W (^^UMO1, ^MGO1)
+ W (^^UMO2, ^MGO2)
+ W (^^UMO3, ^MGO3)
+ W (^^UMO4, ^MGO4)
+ W (^^UMO5, ^MGO5)
+ W (^^UMO6, ^MGO6)
+ W (^^UMO7, ^MGO7)
+ W (^^UMO8, ^MGO8)
+ W (^^UMO9, ^MGO9)
+ W (^^UMOA, ^MGOA)
+ W (^^UMOB, ^MGOB)
+ W (^^UMOC, ^MGOC)
+ W (^^UMOD, ^MGOD)
+ W (^^UMOE, ^MGOE)
+ W (^^UMOF, ^MGOF)
+
+ /* Write Control */
+ W (^^UCL0, ^CTL0)
+ W (^^UCL1, ^CTL1)
+ W (^^UCL2, ^CTL2)
+ W (^^UCL3, ^CTL3)
+ W (^^UCL4, ^CTL4)
+ W (^^UCL5, ^CTL5)
+ W (^^UCL6, ^CTL6)
+ W (^^UCL7, ^CTL7)
+
+ /* Start EC Command */
+ W (^^UCTL, ^UCMD)
+ }
+ Case (2)
+ {
+ /* Read Message In */
+ ^MGI0 = R (^^UMI0)
+ ^MGI1 = R (^^UMI1)
+ ^MGI2 = R (^^UMI2)
+ ^MGI3 = R (^^UMI3)
+ ^MGI4 = R (^^UMI4)
+ ^MGI5 = R (^^UMI5)
+ ^MGI6 = R (^^UMI6)
+ ^MGI7 = R (^^UMI7)
+ ^MGI8 = R (^^UMI8)
+ ^MGI9 = R (^^UMI9)
+ ^MGIA = R (^^UMIA)
+ ^MGIB = R (^^UMIB)
+ ^MGIC = R (^^UMIC)
+ ^MGID = R (^^UMID)
+ ^MGIE = R (^^UMIE)
+ ^MGIF = R (^^UMIF)
+
+ /* Read Status */
+ ^CCI0 = R (^^UCI0)
+ ^CCI1 = R (^^UCI1)
+ ^CCI2 = R (^^UCI2)
+ ^CCI3 = R (^^UCI3)
+ }
+ }
+ Return (Buffer (One) { Zero })
+ }
+}
diff --git a/src/ec/google/wilco/chip.c b/src/ec/google/wilco/chip.c
index 9b0be19f9a..09211f82ab 100644
--- a/src/ec/google/wilco/chip.c
+++ b/src/ec/google/wilco/chip.c
@@ -14,7 +14,10 @@
*/
#include <arch/acpi.h>
+#include <arch/acpi_device.h>
+#include <arch/acpigen.h>
#include <bootstate.h>
+#include <cbmem.h>
#include <device/pnp.h>
#include <ec/acpi/ec.h>
#include <pc80/keyboard.h>
@@ -25,6 +28,64 @@
#include "ec.h"
#include "chip.h"
+/*
+ * The UCSI fields are defined in the UCSI specification at
+ * https://www.intel.com/content/www/us/en/io/universal-serial-bus/usb-type-c-ucsi-spec.html
+ * https://www.intel.com/content/www/us/en/io/universal-serial-bus/bios-implementation-of-ucsi.html
+ */
+
+static struct fieldlist ucsi_region_fields[] = {
+ FIELDLIST_NAMESTR("VER0", 8),
+ FIELDLIST_NAMESTR("VER1", 8),
+ FIELDLIST_NAMESTR("RSV0", 8),
+ FIELDLIST_NAMESTR("RSV1", 8),
+ FIELDLIST_NAMESTR("CCI0", 8),
+ FIELDLIST_NAMESTR("CCI1", 8),
+ FIELDLIST_NAMESTR("CCI2", 8),
+ FIELDLIST_NAMESTR("CCI3", 8),
+ FIELDLIST_NAMESTR("CTL0", 8),
+ FIELDLIST_NAMESTR("CTL1", 8),
+ FIELDLIST_NAMESTR("CTL2", 8),
+ FIELDLIST_NAMESTR("CTL3", 8),
+ FIELDLIST_NAMESTR("CTL4", 8),
+ FIELDLIST_NAMESTR("CTL5", 8),
+ FIELDLIST_NAMESTR("CTL6", 8),
+ FIELDLIST_NAMESTR("CTL7", 8),
+ FIELDLIST_NAMESTR("MGI0", 8),
+ FIELDLIST_NAMESTR("MGI1", 8),
+ FIELDLIST_NAMESTR("MGI2", 8),
+ FIELDLIST_NAMESTR("MGI3", 8),
+ FIELDLIST_NAMESTR("MGI4", 8),
+ FIELDLIST_NAMESTR("MGI5", 8),
+ FIELDLIST_NAMESTR("MGI6", 8),
+ FIELDLIST_NAMESTR("MGI7", 8),
+ FIELDLIST_NAMESTR("MGI8", 8),
+ FIELDLIST_NAMESTR("MGI9", 8),
+ FIELDLIST_NAMESTR("MGIA", 8),
+ FIELDLIST_NAMESTR("MGIB", 8),
+ FIELDLIST_NAMESTR("MGIC", 8),
+ FIELDLIST_NAMESTR("MGID", 8),
+ FIELDLIST_NAMESTR("MGIE", 8),
+ FIELDLIST_NAMESTR("MGIF", 8),
+ FIELDLIST_NAMESTR("MGO0", 8),
+ FIELDLIST_NAMESTR("MGO1", 8),
+ FIELDLIST_NAMESTR("MGO2", 8),
+ FIELDLIST_NAMESTR("MGO3", 8),
+ FIELDLIST_NAMESTR("MGO4", 8),
+ FIELDLIST_NAMESTR("MGO5", 8),
+ FIELDLIST_NAMESTR("MGO6", 8),
+ FIELDLIST_NAMESTR("MGO7", 8),
+ FIELDLIST_NAMESTR("MGO8", 8),
+ FIELDLIST_NAMESTR("MGO9", 8),
+ FIELDLIST_NAMESTR("MGOA", 8),
+ FIELDLIST_NAMESTR("MGOB", 8),
+ FIELDLIST_NAMESTR("MGOC", 8),
+ FIELDLIST_NAMESTR("MGOD", 8),
+ FIELDLIST_NAMESTR("MGOE", 8),
+ FIELDLIST_NAMESTR("MGOF", 8),
+};
+static const size_t ucsi_region_len = ARRAY_SIZE(ucsi_region_fields);
+
static void wilco_ec_post_complete(void *unused)
{
wilco_ec_send(KB_BIOS_PROGRESS, BIOS_PROGRESS_POST_COMPLETE);
@@ -111,11 +172,47 @@ static void wilco_ec_read_resources(struct device *dev)
wilco_ec_resource(dev, 2, CONFIG_EC_BASE_PACKET, 16);
}
+static void wilco_ec_fill_ssdt_generator(struct device *dev)
+{
+ struct opregion opreg;
+ void *region_ptr;
+
+ if (!dev->enabled)
+ return;
+
+ region_ptr = cbmem_add(CBMEM_ID_ACPI_UCSI, ucsi_region_len);
+ if (!region_ptr)
+ return;
+ memset(region_ptr, 0, ucsi_region_len);
+
+ opreg.name = "UCSM";
+ opreg.regionspace = SYSTEMMEMORY;
+ opreg.regionoffset = (uintptr_t)region_ptr;
+ opreg.regionlen = ucsi_region_len;
+
+ acpigen_write_scope(acpi_device_path_join(dev, "UCSI"));
+ acpigen_write_name("_CRS");
+ acpigen_write_resourcetemplate_header();
+ acpigen_write_mem32fixed(1, (uintptr_t)region_ptr, ucsi_region_len);
+ acpigen_write_resourcetemplate_footer();
+ acpigen_write_opregion(&opreg);
+ acpigen_write_field(opreg.name, ucsi_region_fields, ucsi_region_len,
+ FIELD_ANYACC | FIELD_LOCK | FIELD_PRESERVE);
+ acpigen_pop_len(); /* Scope */
+}
+
+static const char *wilco_ec_acpi_name(const struct device *dev)
+{
+ return "EC0";
+}
+
static struct device_operations ops = {
- .init = wilco_ec_init,
- .read_resources = wilco_ec_read_resources,
- .enable_resources = DEVICE_NOOP,
- .set_resources = DEVICE_NOOP,
+ .init = wilco_ec_init,
+ .read_resources = wilco_ec_read_resources,
+ .enable_resources = DEVICE_NOOP,
+ .set_resources = DEVICE_NOOP,
+ .acpi_fill_ssdt_generator = wilco_ec_fill_ssdt_generator,
+ .acpi_name = wilco_ec_acpi_name,
};
static struct pnp_info info[] = {