summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaul E Rangel <rrangel@chromium.org>2020-06-10 16:29:22 -0600
committerPatrick Georgi <pgeorgi@google.com>2020-06-22 12:23:07 +0000
commita31a76976097c7d7b28b7cf0f67cb2d6c66ded48 (patch)
tree4bf19ed862b368eccaab720ff8ca5202321acd16
parenta3db721633b8e2f226af60864562af192e5576e2 (diff)
downloadcoreboot-a31a76976097c7d7b28b7cf0f67cb2d6c66ded48.tar.xz
amd/picasso/acpi: Add power resources for I2C and UART
This allows the kernel to runtime suspend these devices and properly shut them down. If a tty is not used, the kernel will disable the device. I omitted UART0 because the PSP will not power the controller before accessing it. This causes PSP boot failures. See b/158772504. We also can't enable UART0 D3 until we stop using the mmio kernel command line `console=uart,mmio32,0xfedc9000`. The kernel will suspend the UART controller before it notices that the mmio address matches ttyS0. This causes the kernel to fail writing to the UART. So we need to move over to `console=ttyS0`. BUG=b:153001807, b:157617092, b:157858890, b:158772504 TEST=Boot trembyle and see I2C devices entering and exiting D3. * See the UART devices entering D3 * Made sure the i2c peripherals were still functional. * Ran suspend stress test for 40+ iterations. [ 0.349094] power-0362 __acpi_power_on : Power resource [FUR1] turned on [ 0.350627] power-0362 __acpi_power_on : Power resource [FUR2] turned on [ 0.352094] power-0362 __acpi_power_on : Power resource [FUR3] turned on [ 0.353626] power-0362 __acpi_power_on : Power resource [I2C2] turned on [ 0.376980] power-0362 __acpi_power_on : Power resource [PRIC] turned on [ 0.399997] power-0362 __acpi_power_on : Power resource [PRIC] turned on [ 0.401953] power-0362 __acpi_power_on : Power resource [I2C3] turned on [ 0.403460] power-0362 __acpi_power_on : Power resource [I2C4] turned on [ 0.483646] power-0418 __acpi_power_off : Power resource [I2C4] turned off [ 1.028404] power-0418 __acpi_power_off : Power resource [I2C3] turned off [ 1.448426] power-0418 __acpi_power_off : Power resource [I2C2] turned off [ 5.308094] power-0418 __acpi_power_off : Power resource [FUR1] turned off [ 5.340833] power-0418 __acpi_power_off : Power resource [FUR2] turned off [ 5.382041] power-0418 __acpi_power_off : Power resource [FUR3] turned off [ 5.423861] power-0362 __acpi_power_on : Power resource [I2C3] turned on [ 6.698225] power-0362 __acpi_power_on : Power resource [I2C2] turned on [ 6.856573] power-0418 __acpi_power_off : Power resource [I2C3] turned off [ 8.246970] power-0418 __acpi_power_off : Power resource [I2C2] turned off Signed-off-by: Raul E Rangel <rrangel@chromium.org> Change-Id: I04c4a729d4cb9772ab78586fdbb695b450cc1600 Reviewed-on: https://review.coreboot.org/c/coreboot/+/42473 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Aaron Durbin <adurbin@chromium.org>
-rw-r--r--src/soc/amd/picasso/acpi/aoac.asl146
-rw-r--r--src/soc/amd/picasso/acpi/sb_fch.asl72
-rw-r--r--src/soc/amd/picasso/acpi/soc.asl3
3 files changed, 221 insertions, 0 deletions
diff --git a/src/soc/amd/picasso/acpi/aoac.asl b/src/soc/amd/picasso/acpi/aoac.asl
new file mode 100644
index 0000000000..f26f85f205
--- /dev/null
+++ b/src/soc/amd/picasso/acpi/aoac.asl
@@ -0,0 +1,146 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <amdblocks/acpimmio_map.h>
+
+#define AOAC_DEVICE(DEV_NAME, DEV_ID, SX) \
+ PowerResource(DEV_NAME, SX, 0) { \
+ OperationRegion (AOAC, SystemMemory, ACPIMMIO_AOAC_BASE + 0x40 + (DEV_ID << 1), 2) \
+ Field (AOAC, ByteAcc, NoLock, Preserve) { \
+ /* \
+ * Target Device State \
+ * \
+ * 0 = D0 - Uninitialized \
+ * 1 = D0 - Initialized \
+ * 2 = D1/D2/D3Hot \
+ * 3 = D3Cold \
+ * \
+ * This field is only used to cut off register access. It does not \
+ * control any power states. D3Cold is the only value that will \
+ * cut off register access. All other values will allow register \
+ * access and are purely informational. \
+ */ \
+ TDS, 2, \
+\
+ DS, 1, /* Device State - Purely informational */ \
+\
+ /* \
+ * Power On Dev \
+ * \
+ * 1 = Perform hardware sequence to power on the device \
+ * 0 = Perform hardware sequence to power off the device \
+ * \
+ * This register is only valid when Is Software Control = 0. \
+ */ \
+ POD, 1, \
+\
+ /* Software Power On Reset B */ \
+ SPRB, 1, \
+ /* Software Ref Clock OK */ \
+ SRCO, 1, \
+ /* Software Reset B */ \
+ SRB, 1, \
+ /* \
+ * Is Software Control \
+ * \
+ * 1 = Allow software to control Power On Reset B, \
+ * Ref Clock OK, and Reset B. \
+ * 0 = Hardware control \
+ */ \
+ ISWC, 1, \
+\
+ /* Power Reset B State */ \
+ PRBS, 1, \
+ /* Ref Clock OK State */ \
+ RCOS, 1, \
+ /* Reset B State */ \
+ RBS, 1, \
+ /* Device Off Gating State */ \
+ DOGS, 1, \
+ /* D3 Cold State */ \
+ D3CS, 1, \
+ /* Device Clock OK State */ \
+ COS, 1, \
+ /* State of device */ \
+ STA0, 1, \
+ /* State of device */ \
+ STA1, 1, \
+ } \
+ Method(_STA) { \
+ Local0 = (PRBS && RCOS && RBS) \
+\
+ Printf("AOAC.%s._STA: %o", #DEV_NAME, Local0) \
+\
+ If (Local0) { \
+ Return (1) \
+ } Else { \
+ Return (0) \
+ } \
+ } \
+ Method(_ON, 0, Serialized) { \
+ Printf("AOAC.%s._ON", #DEV_NAME) \
+\
+ ISWC=0 \
+ POD=1 \
+\
+ While (!PRBS || !RCOS || !RBS) { \
+ Printf ("Waiting for device to power on") \
+ Stall (100) \
+ } \
+\
+ Printf("Done waiting") \
+ } \
+ Method(_OFF, 0, Serialized) { \
+ Printf("AOAC.%s._OFF", #DEV_NAME) \
+\
+ ISWC=0 \
+ POD=0 \
+\
+ While (PRBS || RCOS || RBS) { \
+ Printf ("Waiting for device to power off") \
+ Stall (100) \
+ } \
+\
+ Printf("Done waiting") \
+ } \
+ Method(_RST, 0, Serialized) { \
+ Printf("AOAC.%s._RST", #DEV_NAME) \
+\
+ ISWC=1 \
+ SRB=1 \
+\
+ /* Assert the SwRstB signal for 200 us */ \
+ Stall (200) \
+\
+ SRB=0 \
+ ISWC=0 \
+\
+ While (!PRBS || !RCOS || !RBS) { \
+ Printf ("Waiting for device to complete reset") \
+ Stall (100) \
+ } \
+ } \
+ }
+
+
+Device (AOAC) {
+ Name (_HID, EISAID("PNP0C02")) // ID for Motherboard resources
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ /*
+ * This case is used to indicate a valid device for which no
+ * device driver should be loaded (for example, a bridge
+ * device.) Children of this device may be present and valid.
+ * OSPM should continue enumeration below a device whose _STA
+ * returns this bit combination.
+ */
+ Return (0x08)
+ }
+
+ AOAC_DEVICE(I2C2, 7, 0)
+ AOAC_DEVICE(I2C3, 8, 0)
+ AOAC_DEVICE(I2C4, 9, 5) /* I2C4 is powered from the S5 power group. */
+ AOAC_DEVICE(FUR1, 12, 0)
+ AOAC_DEVICE(FUR2, 16, 0)
+ AOAC_DEVICE(FUR3, 26, 0)
+}
diff --git a/src/soc/amd/picasso/acpi/sb_fch.asl b/src/soc/amd/picasso/acpi/sb_fch.asl
index 0801c11722..00774fdd4f 100644
--- a/src/soc/amd/picasso/acpi/sb_fch.asl
+++ b/src/soc/amd/picasso/acpi/sb_fch.asl
@@ -153,6 +153,18 @@ Device (FUR1) {
Return (Local0)
}
}
+
+ Name (_PR0, Package () { \_SB.AOAC.FUR1 })
+ Name (_PR2, Package () { \_SB.AOAC.FUR1 })
+ Name (_PR3, Package () { \_SB.AOAC.FUR1 })
+ Method (_PS0, 0, Serialized) {
+ Printf("FUR1._PS0")
+ \_SB.AOAC.FUR1.TDS = 1
+ }
+ Method (_PS3, 0, Serialized) {
+ Printf("FUR1._PS3")
+ \_SB.AOAC.FUR1.TDS = 3
+ }
}
Device (FUR2) {
@@ -184,6 +196,18 @@ Device (FUR2) {
Return (Local0)
}
}
+
+ Name (_PR0, Package () { \_SB.AOAC.FUR2 })
+ Name (_PR2, Package () { \_SB.AOAC.FUR2 })
+ Name (_PR3, Package () { \_SB.AOAC.FUR2 })
+ Method (_PS0, 0, Serialized) {
+ Printf("FUR2._PS0")
+ \_SB.AOAC.FUR2.TDS = 1
+ }
+ Method (_PS3, 0, Serialized) {
+ Printf("FUR2._PS3")
+ \_SB.AOAC.FUR2.TDS = 3
+ }
}
Device (FUR3) {
@@ -215,6 +239,18 @@ Device (FUR3) {
Return (Local0)
}
}
+
+ Name (_PR0, Package () { \_SB.AOAC.FUR3 })
+ Name (_PR2, Package () { \_SB.AOAC.FUR3 })
+ Name (_PR3, Package () { \_SB.AOAC.FUR3 })
+ Method (_PS0, 0, Serialized) {
+ Printf("FUR3._PS0")
+ \_SB.AOAC.FUR3.TDS = 1
+ }
+ Method (_PS3, 0, Serialized) {
+ Printf("FUR3._PS3")
+ \_SB.AOAC.FUR3.TDS = 3
+ }
}
Device (I2C2) {
@@ -249,6 +285,18 @@ Device (I2C2) {
{
Return (0x0F)
}
+
+ Name (_PR0, Package () { \_SB.AOAC.I2C2 })
+ Name (_PR2, Package () { \_SB.AOAC.I2C2 })
+ Name (_PR3, Package () { \_SB.AOAC.I2C2 })
+ Method (_PS0, 0, Serialized) {
+ Printf("I2C2._PS0")
+ \_SB.AOAC.I2C2.TDS = 1
+ }
+ Method (_PS3, 0, Serialized) {
+ Printf("I2C2._PS3")
+ \_SB.AOAC.I2C2.TDS = 3
+ }
}
Device (I2C3)
@@ -283,6 +331,18 @@ Device (I2C3)
{
Return (0x0F)
}
+
+ Name (_PR0, Package () { \_SB.AOAC.I2C3 })
+ Name (_PR2, Package () { \_SB.AOAC.I2C3 })
+ Name (_PR3, Package () { \_SB.AOAC.I2C3 })
+ Method (_PS0, 0, Serialized) {
+ Printf("I2C3._PS0")
+ \_SB.AOAC.I2C3.TDS = 1
+ }
+ Method (_PS3, 0, Serialized) {
+ Printf("I2C3._PS3")
+ \_SB.AOAC.I2C3.TDS = 3
+ }
}
Device (I2C4) {
@@ -317,6 +377,18 @@ Device (I2C4) {
{
Return (0x0F)
}
+
+ Name (_PR0, Package () { \_SB.AOAC.I2C4 })
+ Name (_PR2, Package () { \_SB.AOAC.I2C4 })
+ Name (_PR3, Package () { \_SB.AOAC.I2C4 })
+ Method (_PS0, 0, Serialized) {
+ Printf("I2C4._PS0")
+ \_SB.AOAC.I2C4.TDS = 1
+ }
+ Method (_PS3, 0, Serialized) {
+ Printf("I2C4._PS3")
+ \_SB.AOAC.I2C4.TDS = 3
+ }
}
Device (MISC)
diff --git a/src/soc/amd/picasso/acpi/soc.asl b/src/soc/amd/picasso/acpi/soc.asl
index b411c20ba4..b3b036ea7d 100644
--- a/src/soc/amd/picasso/acpi/soc.asl
+++ b/src/soc/amd/picasso/acpi/soc.asl
@@ -11,6 +11,9 @@ Device(PCI0) {
/* Describe PCI INT[A-H] for the Southbridge */
#include "pci_int.asl"
+/* Describe the AOAC devices */
+#include "aoac.asl"
+
/* Describe the devices in the Southbridge */
#include "sb_fch.asl"