diff options
author | Raul E Rangel <rrangel@chromium.org> | 2020-06-10 16:29:22 -0600 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2020-06-22 12:23:07 +0000 |
commit | a31a76976097c7d7b28b7cf0f67cb2d6c66ded48 (patch) | |
tree | 4bf19ed862b368eccaab720ff8ca5202321acd16 /src/soc | |
parent | a3db721633b8e2f226af60864562af192e5576e2 (diff) |
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>
Diffstat (limited to 'src/soc')
-rw-r--r-- | src/soc/amd/picasso/acpi/aoac.asl | 146 | ||||
-rw-r--r-- | src/soc/amd/picasso/acpi/sb_fch.asl | 72 | ||||
-rw-r--r-- | src/soc/amd/picasso/acpi/soc.asl | 3 |
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" |