Raul Rangel has uploaded this change for review.

View Change

WIP: soc/amd/picasso: Add ACPI AC/DC Wake Alarm

This adds the ACPI entry for the ACPI AC/DC Wake Alarm. This is
different than the RTC wake alarm, because it waits until the system has
entered S3 before firing the wake event. This prevents race conditions
between setting the alarm and suspending in time.

This is WIP because the SCI map is not getting set correctly.

BUG=b:157533281
BRANCH=zork
TEST=On Morphius try suspending and watching the system wake up

localhost /sys/devices/platform/ACPI000E:00 # tail ac_* dc_*
==> ac_alarm <==
disabled

==> ac_policy <==
never

==> ac_status <==
0x00

==> dc_alarm <==
disabled

==> dc_policy <==
never

==> dc_status <==
0x00
localhost /sys/devices/platform/ACPI000E:00 # echo 15 > ac_alarm
localhost /sys/devices/platform/ACPI000E:00 # powerd_dbus_suspend

<Device Resumes>

Signed-off-by: Raul E Rangel <rrangel@chromium.org>
Change-Id: Ia99aaba98405f9b6e50b33936716da9a71338f58
---
M src/soc/amd/common/block/include/amdblocks/acpimmio_map.h
M src/soc/amd/picasso/Makefile.inc
A src/soc/amd/picasso/acdc.c
M src/soc/amd/picasso/acpi/soc.asl
A src/soc/amd/picasso/acpi/wake_alarm.asl
5 files changed, 280 insertions(+), 1 deletion(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/66/45966/1
diff --git a/src/soc/amd/common/block/include/amdblocks/acpimmio_map.h b/src/soc/amd/common/block/include/amdblocks/acpimmio_map.h
index 758a5562..f3836ad 100644
--- a/src/soc/amd/common/block/include/amdblocks/acpimmio_map.h
+++ b/src/soc/amd/common/block/include/amdblocks/acpimmio_map.h
@@ -123,7 +123,6 @@
#define ACPIMMIO_GPIO1_BANK 0x1600
#define ACPIMMIO_GPIO2_BANK 0x1700
#define ACPIMMIO_XHCIPM_BANK 0x1c00
-#define ACPIMMIO_ACDCTMR_BANK 0x1d00
#define ACPIMMIO_AOAC_BANK 0x1e00

/* FIXME: Passing host base for SMBUS is not long-term solution. */
@@ -132,4 +131,6 @@

#endif

+#define ACPIMMIO_ACDCTMR_BANK 0x1d00
+
#endif /* __AMDBLOCKS_ACPIMMIO_MAP_H__ */
diff --git a/src/soc/amd/picasso/Makefile.inc b/src/soc/amd/picasso/Makefile.inc
index 1e9ba4a..6048691 100644
--- a/src/soc/amd/picasso/Makefile.inc
+++ b/src/soc/amd/picasso/Makefile.inc
@@ -80,6 +80,7 @@
ramstage-y += graphics.c
ramstage-y += pcie_gpp.c
ramstage-y += xhci.c
+ramstage-y += acdc.c
ramstage-y += dmi.c

smm-y += smihandler.c
diff --git a/src/soc/amd/picasso/acdc.c b/src/soc/amd/picasso/acdc.c
new file mode 100644
index 0000000..08c8404
--- /dev/null
+++ b/src/soc/amd/picasso/acdc.c
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <amdblocks/gpio_banks.h>
+#include <bootstate.h>
+#include <soc/smi.h>
+#include <soc/soc_util.h>
+
+static const struct sci_source acdc_sci_sources[] = {
+ {
+ .scimap = SMITYPE_ACDC_TIMER,
+ .gpe = GEVENT_30,
+ .direction = SMI_SCI_LVL_HIGH,
+ .level = SMI_SCI_EDG
+ },
+};
+
+static void configure_acdc_sci(void *unused)
+{
+ gpe_configure_sci(acdc_sci_sources, ARRAY_SIZE(acdc_sci_sources));
+}
+
+BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_ENTRY, configure_acdc_sci, NULL);
diff --git a/src/soc/amd/picasso/acpi/soc.asl b/src/soc/amd/picasso/acpi/soc.asl
index b3b036e..a92d1e0 100644
--- a/src/soc/amd/picasso/acpi/soc.asl
+++ b/src/soc/amd/picasso/acpi/soc.asl
@@ -14,6 +14,9 @@
/* Describe the AOAC devices */
#include "aoac.asl"

+/* Describe the Wake Alarm Device devices */
+#include "wake_alarm.asl"
+
/* Describe the devices in the Southbridge */
#include "sb_fch.asl"

diff --git a/src/soc/amd/picasso/acpi/wake_alarm.asl b/src/soc/amd/picasso/acpi/wake_alarm.asl
new file mode 100644
index 0000000..e5cd866
--- /dev/null
+++ b/src/soc/amd/picasso/acpi/wake_alarm.asl
@@ -0,0 +1,252 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <amdblocks/acpimmio_map.h>
+
+Device(AWAK) {
+ Name(_HID, "ACPI000E")
+ OperationRegion (ACDC, SystemMemory, AMD_SB_ACPI_MMIO_ADDR + ACPIMMIO_ACDCTMR_BANK, 0x24)
+ Field (ACDC, WordAcc, NoLock, Preserve) {
+ /*
+ * AC Timer Value
+ *
+ * Writing the register with a value other than FFFF_FFFFh
+ * starts the AC timer. Reading this register returns the
+ * current value of the AC timer.
+ */
+ ACTV, 32,
+
+ /*
+ * AC Expired Timer Policy
+ */
+ ACTP, 32,
+
+ /*
+ * AC Timer Status
+ */
+ ACST, 32,
+
+ Offset (0x10),
+ /*
+ * DC Timer Value
+ *
+ * Writing the register with a value other than FFFF_FFFFh
+ * starts the DC timer. Reading this register returns the
+ * current value of the DC timer.
+ */
+ DCTV, 32,
+
+ /*
+ * DC Expired Timer Policy
+ */
+ DCTP, 32,
+
+ /*
+ * DC Timer Status
+ */
+ DCST, 32,
+
+ Offset (0x20),
+ BUSY, 1,
+ , 7, /* Reserved */
+
+ ACEN, 1, /* Enable AC Timer to wake up system. */
+ DCEN, 1, /* Enable DC Timer to wake up system. */
+ , 22, /* Reserved */
+
+ }
+
+ // _PRW: Power Resources for Wake
+ Name (_PRW, Package () {
+ 0x1E,
+ 0x03
+ })
+
+ /**
+ * Get Capability
+ *
+ * Return Value:
+ * 31:9 - Reserved
+ * 8 - 1 = Wake supported from S5 on DC
+ * 7 - 1 = Wake supported from S4 on DC
+ * 6 - 1 = Wake supported from S5 on AC
+ * 5 - 1 = Wake supported from S4 on AC
+ * 4 - 1 = _GWS returns correct values for wakes from S4/S5 caused by
+ * timer
+ * 3 - 1 = Real time accuracy in milliseconds
+ * 0 = Real time accuracy in seconds
+ * 2 - 1 = Get/Set real time features implemented
+ * 1 - 1 = DC wake implemented
+ * 0 - 1 = AC wake implemented
+ * Bit [9] to Bit [31] are reserved and must be 0.
+ */
+ Name (_GCP, 0x03)
+
+ /**
+ * Get Wake alarm status
+ *
+ * Args0: Timer Identifier
+ * 0 = AC Timer
+ * 1 = DC Timer
+ *
+ * Return:
+ * 31:2 - Reserved
+ * 1 - 1 = Timer caused a platform wake
+ * 0 - 1 = Timer expired
+ */
+ Method(_GWS, 1) {
+ If (Arg0) {
+ Return (DCST)
+ } Else {
+ Return (ACST)
+ }
+ }
+
+ /**
+ * Clear Wake alarm status
+ *
+ * Args0: Timer Identifier
+ * 0 = AC Timer
+ * 1 = DC Timer
+ *
+ * Return:
+ * 1 - Failure
+ * 0 - Success
+ */
+ Method(_CWS, 1) {
+ If (Arg0) {
+ DCST = 0x3
+ } Else {
+ ACST = 0x3
+ }
+ Return(0)
+ }
+
+ /**
+ * Set Expired Timer Wake Policy
+ *
+ * Args0: Timer Identifier
+ * 0 = AC Timer
+ * 1 = DC Timer
+ *
+ * Args1: Expired Timer Wake Policy
+ * 0 = The timer will wake up the system instantly after the power
+ * source changes.
+ * 1 - 0xFFFFFFFE = Time between the power source changes and the
+ * timer wakes up the system (in units of second).
+ * 0xFFFFFFFF = The timer will never wake up the system after the
+ * power source changes.
+ * Return:
+ * 1 - Failure
+ * 0 - Success
+ */
+ Method(_STP, 2) {
+ If (Arg0) {
+ DCTP = Arg1
+ } Else {
+ ACTP = Arg1
+ }
+ Return(0)
+ }
+
+ /**
+ * Get Expired Timer Wake Policy
+ *
+ * Args0: Timer Identifier
+ * 0 = AC Timer
+ * 1 = DC Timer
+ *
+ * Return:
+ * 0 = The timer will wake up the system instantly after the power
+ * source changes.
+ * 1 - 0xFFFFFFFE = Time between the power source changes and the
+ * timer wakes up the system (in units of second).
+ * 0xFFFFFFFF = The timer will never wake up the system after the
+ * power source changes.
+ */
+ Method(_TIP, 1) {
+ If (Arg0) {
+ Return (DCTP)
+ } Else {
+ Return (ACTP)
+ }
+ }
+
+ /**
+ * Set Timer Value
+ *
+ * Args0: Timer Identifier
+ * 0 = AC Timer
+ * 1 = DC Timer
+ *
+ * Args1: Timer Value
+ *
+ * Return:
+ * 1 - Failure
+ * 0 - Success
+ */
+ Method(_STV, 2, Serialized) {
+ If (Arg0) {
+ DCEN = 1
+ While (BUSY) {
+ Printf ("Waiting for DC Timer")
+ Stall (100)
+ }
+ DCTV = Arg1
+ While (BUSY) {
+ Printf ("Waiting for DC Timer to initialize")
+ Stall (100)
+ }
+ } Else {
+ ACEN = 1
+ While (BUSY) {
+ Printf ("Waiting for AC Timer")
+ Stall (100)
+ }
+ ACTV = Arg1
+ While (BUSY) {
+ Printf ("Waiting for AC Timer to initialize")
+ Stall (100)
+ }
+ }
+ Return(0)
+ }
+
+ /**
+ * Get Timer Value
+ *
+ * Args0: Timer Identifier
+ * 0 = AC Timer
+ * 1 = DC Timer
+ *
+ * Return:
+ * 0 - 0xFFFFFFFE = The current timer value.
+ * 0xFFFFFFFF = The timer is disabled.
+ */
+ Method(_TIV, 1) {
+ If (Arg0) {
+ Return (DCTV)
+ } Else {
+ Return (ACTV)
+ }
+ }
+}
+
+
+Scope(\_GPE) {
+ Method(_L30, 0, Serialized) {
+ Local0 = 0
+ If (\_SB.AWAK._GWS(1) & 0x2) { /* DC timer caused wake */
+ \_SB.AWAK._CWS(1) /* Clear DC timer wake */
+ Local0 = 1
+ }
+
+ If (\_SB.AWAK._GWS(0) & 0x2) { /* AC timer caused wake */
+ \_SB.AWAK._CWS(0) /* Clear AC timer wake */
+ Local0 = 1
+ }
+
+ If (Local0) {
+ Notify(\_SB.AWAK, 0x2) //notify the OSPM of device wake
+ }
+ }
+}

To view, visit change 45966. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ia99aaba98405f9b6e50b33936716da9a71338f58
Gerrit-Change-Number: 45966
Gerrit-PatchSet: 1
Gerrit-Owner: Raul Rangel <rrangel@chromium.org>
Gerrit-MessageType: newchange