summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRavi Sarawadi <ravishankar.sarawadi@intel.com>2022-05-08 00:27:31 -0700
committerSubrata Banik <subratabanik@google.com>2022-06-29 05:29:00 +0000
commite02fd83eba7bb20956e0d1d1ef18f28f146b0340 (patch)
tree87a53885dc721ce2c9a808202ee1598269f152a2 /src
parent91ffac8c04776e1e663c5987ea718522f605a9b4 (diff)
soc/intel/mtl/acpi: Add SoC ACPI directory for Meteor Lake
List of changes: 1. Select common ACPI Kconfig to include common ACPI code block from IA-common code 2. Select ACPI Kconfig support for wake up from sleep states. 3. Add SoC ASL code in ASL 2.0 syntax for SoC IPs like IPU, ISH, LAN, HDA etc. BUG=b:224325352 TEST= Build 'util/abuild/abuild -p none -t google/rex -a -c max'. Change-Id: Iebe3d38f50e202d75add88f336b5f3e9ba9f5a22 Signed-off-by: Ravi Sarawadi <ravishankar.sarawadi@intel.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/64168 Reviewed-by: Subrata Banik <subratabanik@google.com> Reviewed-by: Tarun Tuli <taruntuli@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src')
-rw-r--r--src/soc/intel/meteorlake/Kconfig7
-rw-r--r--src/soc/intel/meteorlake/acpi/camera_clock_ctl.asl55
-rw-r--r--src/soc/intel/meteorlake/acpi/dptf.asl9
-rw-r--r--src/soc/intel/meteorlake/acpi/hda.asl13
-rw-r--r--src/soc/intel/meteorlake/acpi/pci_irqs.asl155
-rw-r--r--src/soc/intel/meteorlake/acpi/pcie.asl301
-rw-r--r--src/soc/intel/meteorlake/acpi/serialio.asl69
-rw-r--r--src/soc/intel/meteorlake/acpi/southbridge.asl49
-rw-r--r--src/soc/intel/meteorlake/acpi/tcss.asl936
-rw-r--r--src/soc/intel/meteorlake/acpi/tcss_dma.asl84
-rw-r--r--src/soc/intel/meteorlake/acpi/tcss_pcierp.asl290
-rw-r--r--src/soc/intel/meteorlake/acpi/tcss_xhci.asl182
-rw-r--r--src/soc/intel/meteorlake/acpi/xhci.asl47
-rw-r--r--src/soc/intel/meteorlake/include/soc/tcss.h20
14 files changed, 2217 insertions, 0 deletions
diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig
index cd543ee922..78c3d5a865 100644
--- a/src/soc/intel/meteorlake/Kconfig
+++ b/src/soc/intel/meteorlake/Kconfig
@@ -16,6 +16,7 @@ config CPU_SPECIFIC_OPTIONS
select CPU_SUPPORTS_INTEL_TME
select CPU_SUPPORTS_PM_TIMER_EMULATION
select DRIVERS_INTEL_USB4_RETIMER
+ select DRIVERS_USB_ACPI
select FSP_COMPRESS_FSP_S_LZ4
select FAST_SPI_SUPPORTS_EXT_BIOS_WINDOW
select FSP_M_XIP
@@ -37,7 +38,13 @@ config CPU_SPECIFIC_OPTIONS
select PLATFORM_USES_FSP2_3
select PMC_GLOBAL_RESET_ENABLE_LOCK
select SOC_INTEL_COMMON
+ select SOC_INTEL_COMMON_ACPI_WAKE_SOURCE
select SOC_INTEL_COMMON_BLOCK
+ select SOC_INTEL_COMMON_BLOCK_ACPI
+ select SOC_INTEL_COMMON_BLOCK_ACPI_CPPC
+ select SOC_INTEL_COMMON_BLOCK_ACPI_GPIO
+ select SOC_INTEL_COMMON_BLOCK_ACPI_PEP
+ select SOC_INTEL_COMMON_BLOCK_ACPI_PEP_LPM_REQ
select SOC_INTEL_COMMON_BLOCK_CAR
select SOC_INTEL_COMMON_BLOCK_CHIP_CONFIG
select SOC_INTEL_COMMON_BLOCK_CPU
diff --git a/src/soc/intel/meteorlake/acpi/camera_clock_ctl.asl b/src/soc/intel/meteorlake/acpi/camera_clock_ctl.asl
new file mode 100644
index 0000000000..1bdd07e40f
--- /dev/null
+++ b/src/soc/intel/meteorlake/acpi/camera_clock_ctl.asl
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#define R_ICLK_PCR_CAMERA1 0x8000
+#define B_ICLK_PCR_FREQUENCY 0x3
+#define B_ICLK_PCR_REQUEST 0x4
+
+/* The clock control registers for each IMGCLK are offset by 0xC */
+#define B_ICLK_PCR_OFFSET 0xC
+
+Scope (\_SB.PCI0) {
+
+ /* IsCLK PCH base register for clock settings */
+ Name (ICKB, 0)
+ ICKB = PCRB (PID_ISCLK) + R_ICLK_PCR_CAMERA1
+ /*
+ * Helper function for Read And Or Write
+ * Arg0 : Clock source select
+ * Arg1 : And data
+ * Arg2 : Or data
+ */
+ Method (RAOW, 3, Serialized)
+ {
+ OperationRegion (ICLK, SystemMemory, (ICKB + (Arg0 * B_ICLK_PCR_OFFSET)), 4)
+ Field (ICLK, AnyAcc, NoLock, Preserve)
+ {
+ VAL0, 32
+ }
+ Local0 = VAL0
+ VAL0 = Local0 & Arg1 | Arg2
+ }
+
+ /*
+ * Clock control Method
+ * Arg0: Clock source select (0 .. 5 => IMGCLKOUT_0 .. IMGCLKOUT_5)
+ * Arg1: Frequency select
+ * 2'b00 - 19p2 XTAL
+ * 2'b01 - 19p2 IMG
+ * 2'b10 - 19p2 RTC
+ * 2'b11 - 24 IMG
+ */
+ Method (MCON, 0x2, NotSerialized)
+ {
+ /* Set Clock Frequency */
+ RAOW (Arg0, ~B_ICLK_PCR_FREQUENCY, Arg1)
+
+ /* Enable Clock */
+ RAOW (Arg0, ~B_ICLK_PCR_REQUEST, B_ICLK_PCR_REQUEST)
+ }
+
+ Method (MCOF, 0x1, NotSerialized)
+ {
+ /* Disable Clock */
+ RAOW (Arg0, ~B_ICLK_PCR_REQUEST, 0)
+ }
+}
diff --git a/src/soc/intel/meteorlake/acpi/dptf.asl b/src/soc/intel/meteorlake/acpi/dptf.asl
new file mode 100644
index 0000000000..959b44bd31
--- /dev/null
+++ b/src/soc/intel/meteorlake/acpi/dptf.asl
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/* Below are the unique ACPI Device IDs for thermal/dptf on Meteor Lake SoC. */
+/* DPTF ACPI Device ID */
+#define DPTF_DPTF_DEVICE "INTC1041"
+/* Generic ACPI Device ID for TSR0/1/2/3 and charger */
+#define DPTF_GEN_DEVICE "INTC1046"
+/* Fan ACPI Device ID */
+#define DPTF_FAN_DEVICE "INTC1048"
diff --git a/src/soc/intel/meteorlake/acpi/hda.asl b/src/soc/intel/meteorlake/acpi/hda.asl
new file mode 100644
index 0000000000..fc6cb4e505
--- /dev/null
+++ b/src/soc/intel/meteorlake/acpi/hda.asl
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/* Audio Controller - Device 31, Function 3 */
+
+Device (HDAS)
+{
+ Name (_ADR, 0x001f0003)
+ Name (_DDN, "Audio Controller")
+ Name (UUID, ToUUID ("A69F886E-6CEB-4594-A41F-7B5DCE24C553"))
+
+ /* Device is D3 wake capable */
+ Name (_S0W, 3)
+}
diff --git a/src/soc/intel/meteorlake/acpi/pci_irqs.asl b/src/soc/intel/meteorlake/acpi/pci_irqs.asl
new file mode 100644
index 0000000000..70e9f3de6b
--- /dev/null
+++ b/src/soc/intel/meteorlake/acpi/pci_irqs.asl
@@ -0,0 +1,155 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+Name (PICP, Package () {
+ /* D31 */
+ Package(){0x001FFFFF, 0, 0, 16 },
+ Package(){0x001FFFFF, 1, 0, 17 },
+ Package(){0x001FFFFF, 2, 0, 18 },
+ Package(){0x001FFFFF, 3, 0, 19 },
+ /* D30 */
+ Package(){0x001EFFFF, 0, 0, 16 },
+ Package(){0x001EFFFF, 1, 0, 17 },
+ Package(){0x001EFFFF, 2, 0, 27 },
+ Package(){0x001EFFFF, 3, 0, 28 },
+ /* D28 */
+ Package(){0x001CFFFF, 0, 0, 16 },
+ Package(){0x001CFFFF, 1, 0, 17 },
+ Package(){0x001CFFFF, 2, 0, 18 },
+ Package(){0x001CFFFF, 3, 0, 19 },
+ /* D25 */
+ Package(){0x0019FFFF, 0, 0, 29 },
+ Package(){0x0019FFFF, 1, 0, 30 },
+ Package(){0x0019FFFF, 2, 0, 31 },
+ /* D23 */
+ Package(){0x0017FFFF, 0, 0, 16 },
+ /* D22 */
+ Package(){0x0016FFFF, 0, 0, 16 },
+ Package(){0x0016FFFF, 1, 0, 17 },
+ Package(){0x0016FFFF, 2, 0, 18 },
+ Package(){0x0016FFFF, 3, 0, 19 },
+ /* D21 */
+ Package(){0x0015FFFF, 0, 0, 32 },
+ Package(){0x0015FFFF, 1, 0, 33 },
+ Package(){0x0015FFFF, 2, 0, 34 },
+ Package(){0x0015FFFF, 3, 0, 35 },
+ /* D20 */
+ Package(){0x0014FFFF, 0, 0, 16 },
+ Package(){0x0014FFFF, 1, 0, 17 },
+ Package(){0x0014FFFF, 2, 0, 18 },
+ /* D18 */
+ Package(){0x0012FFFF, 0, 0, 26 },
+ Package(){0x0012FFFF, 1, 0, 37 },
+ Package(){0x0012FFFF, 2, 0, 25 },
+ /* D16 */
+ Package(){0x0010FFFF, 0, 0, 23 },
+ Package(){0x0010FFFF, 1, 0, 22 },
+ /* D13 */
+ Package(){0x000DFFFF, 0, 0, 16 },
+ Package(){0x000DFFFF, 1, 0, 17 },
+ /* D11 */
+ Package(){0x000BFFFF, 0, 0, 16 },
+ /* D8 */
+ Package(){0x0008FFFF, 0, 0, 16 },
+ /* D7 */
+ Package(){0x0007FFFF, 0, 0, 16 },
+ Package(){0x0007FFFF, 1, 0, 17 },
+ Package(){0x0007FFFF, 2, 0, 18 },
+ Package(){0x0007FFFF, 3, 0, 19 },
+ /* D6 */
+ Package(){0x0006FFFF, 0, 0, 16 },
+ Package(){0x0006FFFF, 1, 0, 17 },
+ Package(){0x0006FFFF, 2, 0, 18 },
+ Package(){0x0006FFFF, 3, 0, 19 },
+ /* D5 */
+ Package(){0x0005FFFF, 0, 0, 16 },
+ /* D4 */
+ Package(){0x0004FFFF, 0, 0, 16 },
+ /* D2 */
+ Package(){0x0002FFFF, 0, 0, 16 },
+ /* D1 */
+ Package(){0x0001FFFF, 0, 0, 16 },
+ Package(){0x0001FFFF, 1, 0, 17 },
+ Package(){0x0001FFFF, 2, 0, 18 },
+ Package(){0x0001FFFF, 3, 0, 19 },
+})
+
+Name (PICN, Package () {
+ /* D31 */
+ Package(){0x001FFFFF, 0, 0, 11 },
+ Package(){0x001FFFFF, 1, 0, 10 },
+ Package(){0x001FFFFF, 2, 0, 11 },
+ Package(){0x001FFFFF, 3, 0, 11 },
+ /* D30 */
+ Package(){0x001EFFFF, 0, 0, 11 },
+ Package(){0x001EFFFF, 1, 0, 10 },
+ Package(){0x001EFFFF, 2, 0, 11 },
+ Package(){0x001EFFFF, 3, 0, 11 },
+ /* D28 */
+ Package(){0x001CFFFF, 0, 0, 11 },
+ Package(){0x001CFFFF, 1, 0, 10 },
+ Package(){0x001CFFFF, 2, 0, 11 },
+ Package(){0x001CFFFF, 3, 0, 11 },
+ /* D25 */
+ Package(){0x0019FFFF, 0, 0, 11 },
+ Package(){0x0019FFFF, 1, 0, 10 },
+ Package(){0x0019FFFF, 2, 0, 11 },
+ /* D23 */
+ Package(){0x0017FFFF, 0, 0, 11 },
+ /* D22 */
+ Package(){0x0016FFFF, 0, 0, 11 },
+ Package(){0x0016FFFF, 1, 0, 10 },
+ Package(){0x0016FFFF, 2, 0, 11 },
+ Package(){0x0016FFFF, 3, 0, 11 },
+ /* D21 */
+ Package(){0x0015FFFF, 0, 0, 11 },
+ Package(){0x0015FFFF, 1, 0, 10 },
+ Package(){0x0015FFFF, 2, 0, 11 },
+ Package(){0x0015FFFF, 3, 0, 11 },
+ /* D20 */
+ Package(){0x0014FFFF, 0, 0, 11 },
+ Package(){0x0014FFFF, 1, 0, 10 },
+ Package(){0x0014FFFF, 2, 0, 11 },
+ /* D18 */
+ Package(){0x0012FFFF, 0, 0, 11 },
+ Package(){0x0012FFFF, 1, 0, 10 },
+ Package(){0x0012FFFF, 2, 0, 11 },
+ /* D16 */
+ Package(){0x0010FFFF, 0, 0, 11 },
+ Package(){0x0010FFFF, 1, 0, 10 },
+ /* D13 */
+ Package(){0x000DFFFF, 0, 0, 11 },
+ /* D11 */
+ Package(){0x000BFFFF, 0, 0, 11 },
+ /* D8 */
+ Package(){0x0008FFFF, 0, 0, 11 },
+ /* D7 */
+ Package(){0x0007FFFF, 0, 0, 11 },
+ Package(){0x0007FFFF, 1, 0, 10 },
+ Package(){0x0007FFFF, 2, 0, 11 },
+ Package(){0x0007FFFF, 3, 0, 11 },
+ /* D6 */
+ Package(){0x0006FFFF, 0, 0, 11 },
+ Package(){0x0006FFFF, 1, 0, 10 },
+ Package(){0x0006FFFF, 2, 0, 11 },
+ Package(){0x0006FFFF, 3, 0, 11 },
+ /* D5 */
+ Package(){0x0005FFFF, 0, 0, 11 },
+ /* D4 */
+ Package(){0x0004FFFF, 0, 0, 11 },
+ /* D2 */
+ Package(){0x0002FFFF, 0, 0, 11 },
+ /* D1 */
+ Package(){0x0001FFFF, 0, 0, 11 },
+ Package(){0x0001FFFF, 1, 0, 10 },
+ Package(){0x0001FFFF, 2, 0, 11 },
+ Package(){0x0001FFFF, 3, 0, 11 },
+})
+
+Method (_PRT)
+{
+ If (PICM) {
+ Return (^PICP)
+ } Else {
+ Return (^PICN)
+ }
+}
diff --git a/src/soc/intel/meteorlake/acpi/pcie.asl b/src/soc/intel/meteorlake/acpi/pcie.asl
new file mode 100644
index 0000000000..386a57d26c
--- /dev/null
+++ b/src/soc/intel/meteorlake/acpi/pcie.asl
@@ -0,0 +1,301 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/* Intel PCH PCIe support */
+
+Method (IRQM, 1, Serialized) {
+
+ /* Interrupt Map INTA->INTA, INTB->INTB, INTC->INTC, INTD->INTD */
+ Name (IQAA, Package () {
+ Package () { 0x0000ffff, 0, 0, 16 },
+ Package () { 0x0000ffff, 1, 0, 17 },
+ Package () { 0x0000ffff, 2, 0, 18 },
+ Package () { 0x0000ffff, 3, 0, 19 } })
+ Name (IQAP, Package () {
+ Package () { 0x0000ffff, 0, 0, 11 },
+ Package () { 0x0000ffff, 1, 0, 10 },
+ Package () { 0x0000ffff, 2, 0, 11 },
+ Package () { 0x0000ffff, 3, 0, 11 } })
+
+ /* Interrupt Map INTA->INTB, INTB->INTC, INTC->INTD, INTD->INTA */
+ Name (IQBA, Package () {
+ Package () { 0x0000ffff, 0, 0, 17 },
+ Package () { 0x0000ffff, 1, 0, 18 },
+ Package () { 0x0000ffff, 2, 0, 19 },
+ Package () { 0x0000ffff, 3, 0, 16 } })
+ Name (IQBP, Package () {
+ Package () { 0x0000ffff, 0, 0, 10 },
+ Package () { 0x0000ffff, 1, 0, 11 },
+ Package () { 0x0000ffff, 2, 0, 11 },
+ Package () { 0x0000ffff, 3, 0, 11 } })
+
+ /* Interrupt Map INTA->INTC, INTB->INTD, INTC->INTA, INTD->INTB */
+ Name (IQCA, Package () {
+ Package () { 0x0000ffff, 0, 0, 18 },
+ Package () { 0x0000ffff, 1, 0, 19 },
+ Package () { 0x0000ffff, 2, 0, 16 },
+ Package () { 0x0000ffff, 3, 0, 17 } })
+ Name (IQCP, Package () {
+ Package () { 0x0000ffff, 0, 0, 11 },
+ Package () { 0x0000ffff, 1, 0, 11 },
+ Package () { 0x0000ffff, 2, 0, 11 },
+ Package () { 0x0000ffff, 3, 0, 10 } })
+
+ /* Interrupt Map INTA->INTD, INTB->INTA, INTC->INTB, INTD->INTC */
+ Name (IQDA, Package () {
+ Package () { 0x0000ffff, 0, 0, 19 },
+ Package () { 0x0000ffff, 1, 0, 16 },
+ Package () { 0x0000ffff, 2, 0, 17 },
+ Package () { 0x0000ffff, 3, 0, 18 } })
+ Name (IQDP, Package () {
+ Package () { 0x0000ffff, 0, 0, 11 },
+ Package () { 0x0000ffff, 1, 0, 11 },
+ Package () { 0x0000ffff, 2, 0, 10 },
+ Package () { 0x0000ffff, 3, 0, 11 } })
+
+ Switch (ToInteger (Arg0))
+ {
+ Case (Package () { 1, 5, 9, 13 }) {
+ If (PICM) {
+ Return (IQAA)
+ } Else {
+ Return (IQAP)
+ }
+ }
+
+ Case (Package () { 2, 6, 10, 14 }) {
+ If (PICM) {
+ Return (IQBA)
+ } Else {
+ Return (IQBP)
+ }
+ }
+
+ Case (Package () { 3, 7, 11, 15 }) {
+ If (PICM) {
+ Return (IQCA)
+ } Else {
+ Return (IQCP)
+ }
+ }
+
+ Case (Package () { 4, 8, 12, 16 }) {
+ If (PICM) {
+ Return (IQDA)
+ } Else {
+ Return (IQDP)
+ }
+ }
+
+ Default {
+ If (PICM) {
+ Return (IQDA)
+ } Else {
+ Return (IQDP)
+ }
+ }
+ }
+}
+
+Device (RP01)
+{
+ Name (_ADR, 0x001C0000)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP02)
+{
+ Name (_ADR, 0x001C0001)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP03)
+{
+ Name (_ADR, 0x001C0002)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP04)
+{
+ Name (_ADR, 0x001C0003)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP05)
+{
+ Name (_ADR, 0x001C0004)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP06)
+{
+ Name (_ADR, 0x001C0005)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP07)
+{
+ Name (_ADR, 0x001C0006)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP08)
+{
+ Name (_ADR, 0x001C0007)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP09)
+{
+ Name (_ADR, 0x00060000)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP10)
+{
+ Name (_ADR, 0x00060001)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP11)
+{
+ Name (_ADR, 0x00060002)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
+
+Device (RP12)
+{
+ Name (_ADR, 0x00010000)
+
+ OperationRegion (RPCS, PCI_Config, 0x4c, 4)
+ Field (RPCS, AnyAcc, NoLock, Preserve)
+ {
+ , 24,
+ RPPN, 8, /* Root Port Number */
+ }
+
+ Method (_PRT)
+ {
+ Return (IRQM (RPPN))
+ }
+}
diff --git a/src/soc/intel/meteorlake/acpi/serialio.asl b/src/soc/intel/meteorlake/acpi/serialio.asl
new file mode 100644
index 0000000000..4034f65618
--- /dev/null
+++ b/src/soc/intel/meteorlake/acpi/serialio.asl
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/* Intel Serial IO Devices */
+
+Device (I2C0)
+{
+ Name (_ADR, 0x00150000)
+ Name (_DDN, "Serial IO I2C Controller 0")
+}
+
+Device (I2C1)
+{
+ Name (_ADR, 0x00150001)
+ Name (_DDN, "Serial IO I2C Controller 1")
+}
+
+Device (I2C2)
+{
+ Name (_ADR, 0x00150002)
+ Name (_DDN, "Serial IO I2C Controller 2")
+}
+
+Device (I2C3)
+{
+ Name (_ADR, 0x00150003)
+ Name (_DDN, "Serial IO I2C Controller 3")
+}
+
+Device (I2C4)
+{
+ Name (_ADR, 0x00190000)
+ Name (_DDN, "Serial IO I2C Controller 4")
+}
+
+Device (I2C5)
+{
+ Name (_ADR, 0x00190001)
+ Name (_DDN, "Serial IO I2C Controller 5")
+}
+
+Device (SPI0)
+{
+ Name (_ADR, 0x001e0002)
+ Name (_DDN, "Serial IO SPI Controller 0")
+}
+
+Device (SPI1)
+{
+ Name (_ADR, 0x001e0003)
+ Name (_DDN, "Serial IO SPI Controller 1")
+}
+
+Device (UAR0)
+{
+ Name (_ADR, 0x001e0000)
+ Name (_DDN, "Serial IO UART Controller 0")
+}
+
+Device (UAR1)
+{
+ Name (_ADR, 0x001e0001)
+ Name (_DDN, "Serial IO UART Controller 1")
+}
+
+Device (UAR2)
+{
+ Name (_ADR, 0x00190002)
+ Name (_DDN, "Serial IO UART Controller 2")
+}
diff --git a/src/soc/intel/meteorlake/acpi/southbridge.asl b/src/soc/intel/meteorlake/acpi/southbridge.asl
new file mode 100644
index 0000000000..448cbf56a1
--- /dev/null
+++ b/src/soc/intel/meteorlake/acpi/southbridge.asl
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <intelblocks/itss.h>
+#include <intelblocks/pcr.h>
+#include <soc/itss.h>
+#include <soc/pcr_ids.h>
+
+/* PCI IRQ assignment */
+#include "pci_irqs.asl"
+
+/* PCR access */
+#include <soc/intel/common/acpi/pcr.asl>
+
+/* PCH clock */
+#include "camera_clock_ctl.asl"
+
+/* GPIO controller */
+#include "gpio.asl"
+
+/* ESPI 0:1f.0 */
+#include <soc/intel/common/block/acpi/acpi/lpc.asl>
+
+/* HDA */
+#include "hda.asl"
+
+/* PCIE Ports */
+#include "pcie.asl"
+
+/* Serial IO */
+#include "serialio.asl"
+
+/* SMBus 0:1f.4 */
+#include <soc/intel/common/block/acpi/acpi/smbus.asl>
+
+/* ISH 0:12.0 */
+#if CONFIG(DRIVERS_INTEL_ISH)
+#include <soc/intel/common/block/acpi/acpi/ish.asl>
+#endif
+
+/* USB XHCI 0:14.0 */
+#include "xhci.asl"
+
+/* PCI _OSC */
+#include <soc/intel/common/acpi/pci_osc.asl>
+
+/* GbE 0:1f.6 */
+#if CONFIG(MAINBOARD_USES_IFD_GBE_REGION)
+#include <soc/intel/common/block/acpi/acpi/pch_glan.asl>
+#endif
diff --git a/src/soc/intel/meteorlake/acpi/tcss.asl b/src/soc/intel/meteorlake/acpi/tcss.asl
new file mode 100644
index 0000000000..87d6521270
--- /dev/null
+++ b/src/soc/intel/meteorlake/acpi/tcss.asl
@@ -0,0 +1,936 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <soc/iomap.h>
+#include <soc/tcss.h>
+
+/*
+ * Type C Subsystem(TCSS) topology provides Runtime D3 support for USB host controller(xHCI),
+ * USB device controller(xDCI), Thunderbolt DMA devices and Thunderbolt PCIe controllers.
+ * PCIe RP0/RP1 is grouped with DMA0 and PCIe RP2/RP3 is grouped with DMA1.
+ */
+#define TCSS_TBT_PCIE0_RP0 0
+#define TCSS_TBT_PCIE0_RP1 1
+#define TCSS_TBT_PCIE0_RP2 2
+#define TCSS_TBT_PCIE0_RP3 3
+#define TCSS_XHCI 4
+#define TCSS_XDCI 5
+#define TCSS_DMA0 6
+#define TCSS_DMA1 7
+
+/*
+ * MAILBOX_BIOS_CMD_TCSS_DEVEN_INTERFACE
+ * Command code 0x15
+ * Description: Gateway command for handling TCSS DEVEN clear/restore.
+ * Field PARAM1[15:8] of the _INTERFACE register is used in this command to select from
+ * a pre-defined set of subcommands.
+ */
+#define MAILBOX_BIOS_CMD_TCSS_DEVEN_INTERFACE 0x00000015
+#define TCSS_DEVEN_MAILBOX_SUBCMD_GET_STATUS 0 /* Sub-command 0 */
+#define TCSS_DEVEN_MAILBOX_SUBCMD_TCSS_CHANGE_REQ 1 /* Sub-command 1 */
+#define TCSS_IOM_ACK_TIMEOUT_IN_MS 100
+
+#define MCHBAR_TCSS_DEVEN_OFFSET 0x7090
+
+#define REVISION_ID 1
+#define UNRECOGNIZED_UUID 0x4
+#define UNRECOGNIZED_REVISION 0x8
+
+#define USB_TUNNELING 0x1
+#define DISPLAY_PORT_TUNNELING 0x2
+#define PCIE_TUNNELING 0x4
+#define INTER_DOMAIN_USB4_INTERNET_PROTOCOL 0x8
+
+Scope (\_SB)
+{
+ /* Device base address */
+ Method (BASE, 1)
+ {
+ Local0 = Arg0 & 0x7 /* Function number */
+ Local1 = (Arg0 >> 16) & 0x1F /* Device number */
+ Local2 = (Local0 << 12) + (Local1 << 15)
+ Local3 = \_SB.PCI0.GPCB() + Local2
+ Return (Local3)
+ }
+
+ /*
+ * Define PCH ACPIBASE IO as an ACPI operating region. The base address can be
+ * found in Device 31, Function 2, Offset 40h.
+ */
+ OperationRegion (PMIO, SystemIO, ACPI_BASE_ADDRESS, 0x80)
+ Field (PMIO, ByteAcc, NoLock, Preserve) {
+ Offset(0x6C), /* 0x6C, General Purpose Event 0 Status [127:96] */
+ , 19,
+ CPWS, 1, /* CPU WAKE STATUS */
+ Offset(0x7C), /* 0x7C, General Purpose Event 0 Enable [127:96] */
+ , 19,
+ CPWE, 1 /* CPU WAKE EN */
+ }
+
+ Name (C2PW, 0) /* Set default value to 0. */
+
+ /*
+ * C2PM (CPU to PCH Method)
+ *
+ * This object is Enable/Disable GPE_CPU_WAKE_EN.
+ * Arguments: (4)
+ * Arg0 - An Integer containing the device wake capability
+ * Arg1 - An Integer containing the target system state
+ * Arg2 - An Integer containing the target device state
+ * Arg3 - An Integer containing the request device type
+ * Return Value:
+ * return 0
+ */
+ Method (C2PM, 4, NotSerialized)
+ {
+ Local0 = 1 << Arg3
+ /* This method is used to enable/disable wake from Tcss Device (WKEN). */
+ If (Arg0 && Arg1)
+ { /* If entering Sx and enabling wake, need to enable WAKE capability. */
+ If (CPWE == 0) { /* If CPU WAKE EN is not set, Set it. */
+ If (CPWS) { /* If CPU WAKE STATUS is set, Clear it. */
+ /* Clear CPU WAKE STATUS by writing 1. */
+ CPWS = 1
+ }
+ CPWE = 1 /* Set CPU WAKE EN by writing 1. */
+ }
+ If ((C2PW & Local0) == 0) {
+ /* Set Corresponding Device En BIT in C2PW. */
+ C2PW |= Local0
+ }
+ } Else { /* If Staying in S0 or Disabling Wake. */
+ If (Arg0 || Arg2) { /* Check if Exiting D0 and arming for wake. */
+ /* If CPU WAKE EN is not set, Set it. */
+ If (CPWE == 0) {
+ /* If CPU WAKE STATUS is set, Clear it. */
+ If (CPWS) {
+ /* Clear CPU WAKE STATUS by writing 1. */
+ CPWS = 1
+ }
+ CPWE = 1 /* Set CPU WAKE EN by writing 1. */
+ }
+ If ((C2PW & Local0) == 0) {
+ /* Set Corresponding Device En BIT in C2PW. */
+ C2PW |= Local0
+ }
+ } Else {
+ /*
+ * Disable runtime PME, either because staying in D0 or
+ * disabling wake.
+ */
+ If ((C2PW & Local0) != 0) {
+ /*
+ * Clear Corresponding Device En BIT in C2PW.
+ */
+ C2PW &= ~Local0
+ }
+ If ((CPWE != 0) && (C2PW == 0)) {
+ /*
+ * If CPU WAKE EN is set, Clear it. Clear CPU WAKE EN
+ * by writing 0.
+ */
+ CPWE = 0
+ }
+ }
+ }
+ Return (0)
+ }
+
+ Method (_OSC, 4, Serialized)
+ {
+ CreateDWordField (Arg3, 0, CDW1)
+ If (Arg0 == ToUUID("0811B06E-4A27-44F9-8D60-3CBBC22E7B48")) {
+ /* Platform-Wide _OSC Capabilities
+ * Arg0: UUID = {0811B06E-4A27-44F9-8D60-3CBBC22E7B48}
+ * Arg1: Revision ID = 1
+ * Arg2: Count of entries (DWORD) in Arge3 (Integer): 3
+ * Arg3: DWORD capabilities buffer:
+ * First DWORD: The standard definition bits are used to return errors.
+ * Second DWORD: See ACPI specification Platform-Wide _OSC Capabilities
+ * DWORD2 table for Bits 0-17. Bit 18 is newly defined as native USB4
+ * support. The OS sets this bit to indicate support for an OSPM-native
+ * USB4 Connection Manager which handles USB4 connection events and
+ * link management.
+ */
+ If (Arg1 != REVISION_ID) {
+ CDW1 |= UNRECOGNIZED_REVISION
+ }
+ Return (Arg3)
+ } ElseIf (Arg0 == ToUUID("23A0D13A-26AB-486C-9C5F-0FFA525A575A")) {
+ /*
+ * Operating System Capabilities for USB4
+ * Arg0: UUID = {23A0D13A-26AB-486C-9C5F-0FFA525A575A}
+ * Arg1: Revision ID = 1
+ * Arg2: Count of entries (DWORD) in Arg3 (Integer): 3
+ * Arg3: DWORD capabilities buffer:
+ * First DWORD: The standard definition bits are used to return errors.
+ * Second DWORD: OSPM support field for USB4, bits [31:0] reserved.
+ * Third DWORD: OSPM control field for USB4.
+ * bit 0: USB tunneling
+ * bit 1: DisplayPort tunneling
+ * bit 2: PCIe tunneling
+ * bit 3: Inter-domain USB4 internet protocol
+ * bit 31:4: reserved
+ * Return: The platform acknowledges the capabilities buffer by
+ * returning a buffer of DWORD of the same length. Masked/Cleared bits
+ * in the control field indicate that the platform does not permit OSPM
+ * control of the respectively capabilities or features.
+ */
+ CreateDWordField (Arg3, 8, CDW3)
+ Local0 = CDW3
+
+ If (Arg1 != REVISION_ID) {
+ CDW1 |= UNRECOGNIZED_REVISION
+ Return (Arg3)
+ }
+ Local0 |= USB_TUNNELING | DISPLAY_PORT_TUNNELING | PCIE_TUNNELING |
+ INTER_DOMAIN_USB4_INTERNET_PROTOCOL
+ CDW3 = Local0
+ Return (Arg3)
+ } Else {
+ CDW1 |= UNRECOGNIZED_UUID
+ Return (Arg3)
+ }
+ }
+}
+
+Scope (_GPE)
+{
+ /* PCI Express Hot-Plug wake event */
+ Method (_L61, 0, NotSerialized)
+ {
+ /*
+ * Delay for 100ms to meet the timing requirements of the PCI Express Base
+ * Specification, Revision 1.0A, Section 6.6 ("...software must wait at least
+ * 100ms from the end of reset of one or more device before it is permitted
+ * to issue Configuration Requests to those devices").
+ */
+ Sleep (100)
+
+ If (CondRefOf (\_SB.PCI0.TXHC)) {
+ /* Invoke PCIe root ports wake event handler */
+ \_SB.PCI0.TRP0.HPEV()
+ \_SB.PCI0.TRP1.HPEV()
+ \_SB.PCI0.TRP2.HPEV()
+ \_SB.PCI0.TRP3.HPEV()
+ }
+
+ /* Check Root Port 0 for a Hot Plug Event if the port is enabled */
+ If (((\_SB.PCI0.TRP0.VDID != 0xFFFFFFFF) && \_SB.PCI0.TRP0.HPSX)) {
+ If (\_SB.PCI0.TRP0.PDCX) {
+ /* Clear all status bits */
+ \_SB.PCI0.TRP0.PDCX = 1
+ \_SB.PCI0.TRP0.HPSX = 1
+ /*
+ * Intercept Presence Detect Changed interrupt and make sure
+ * the L0s is disabled on empty slots.
+ */
+ If (!\_SB.PCI0.TRP0.PDSX) {
+ /*
+ * The PCIe slot is empty, so disable L0s on hot unplug.
+ */
+ \_SB.PCI0.TRP0.L0SE = 0
+ }
+ /* Performs proper notification to the OS. */
+ Notify (\_SB.PCI0.TRP0, 0)
+ } Else {
+ /* False event. Clear Hot-Plug status, then exit. */
+ \_SB.PCI0.TRP0.HPSX = 1
+ }
+ }
+
+ /* Check Root Port 1 for a Hot Plug Event if the port is enabled */
+ If (((\_SB.PCI0.TRP1.VDID != 0xFFFFFFFF) && \_SB.PCI0.TRP1.HPSX)) {
+ If (\_SB.PCI0.TRP1.PDCX) {
+ \_SB.PCI0.TRP1.PDCX = 1
+ \_SB.PCI0.TRP1.HPSX = 1
+ If (!\_SB.PCI0.TRP1.PDSX) {
+ \_SB.PCI0.TRP1.L0SE = 0
+ }
+ Notify (\_SB.PCI0.TRP1, 0)
+ } Else {
+ \_SB.PCI0.TRP1.HPSX = 1
+ }
+ }
+
+ /* Check Root Port 2 for a Hot Plug Event if the port is enabled */
+ If (((\_SB.PCI0.TRP2.VDID != 0xFFFFFFFF) && \_SB.PCI0.TRP2.HPSX)) {
+ If (\_SB.PCI0.TRP2.PDCX) {
+ \_SB.PCI0.TRP2.PDCX = 1
+ \_SB.PCI0.TRP2.HPSX = 1
+ If (!\_SB.PCI0.TRP2.PDSX) {
+ \_SB.PCI0.TRP2.L0SE = 0
+ }
+ Notify (\_SB.PCI0.TRP2, 0)
+ } Else {
+ \_SB.PCI0.TRP2.HPSX = 1
+ }
+ }
+
+ /* Check Root Port 3 for a Hot Plug Event if the port is enabled */
+ If (((\_SB.PCI0.TRP3.VDID != 0xFFFFFFFF) && \_SB.PCI0.TRP3.HPSX)) {
+ If (\_SB.PCI0.TRP3.PDCX) {
+ \_SB.PCI0.TRP3.PDCX = 1
+ \_SB.PCI0.TRP3.HPSX = 1
+ If (!\_SB.PCI0.TRP3.PDSX) {
+ \_SB.PCI0.TRP3.L0SE = 0
+ }
+ Notify (\_SB.PCI0.TRP3, 0)
+ } Else {
+ \_SB.PCI0.TRP3.HPSX = 1
+ }
+ }
+ }
+
+ /* PCI Express power management event */
+ Method (_L69, 0, Serialized)
+ {
+ If (CondRefOf (\_SB.PCI0.TXHC)) {
+ If (\_SB.PCI0.TRP0.HPME() == 1) {
+ Notify (\_SB.PCI0.TDM0, 0x2)
+ Notify (\_SB.PCI0.TRP0, 0x2)
+ }
+
+ If (\_SB.PCI0.TRP1.HPME() == 1) {
+ Notify (\_SB.PCI0.TDM0, 0x2)
+ Notify (\_SB.PCI0.TRP1, 0x2)
+ }
+
+ If (\_SB.PCI0.TRP2.HPME() == 1) {
+ Notify (\_SB.PCI0.TDM1, 0x2)
+ Notify (\_SB.PCI0.TRP2, 0x2)
+ }
+
+ If (\_SB.PCI0.TRP3.HPME() == 1) {
+ Notify (\_SB.PCI0.TDM1, 0x2)
+ Notify (\_SB.PCI0.TRP3, 0x2)
+ }
+ }
+
+ /* Invoke PCIe root ports power management status handler */
+ \_SB.PCI0.TRP0.HPME()
+ \_SB.PCI0.TRP1.HPME()
+ \_SB.PCI0.TRP2.HPME()
+ \_SB.PCI0.TRP3.HPME()
+ }
+}
+
+Scope (\_SB.PCI0)
+{
+ Device (IOM)
+ {
+ Name (_HID, "INTC107A")
+ Name (_DDN, "Intel(R) Meteor Lake Input Output Manager(IOM) driver")
+ /* IOM preserved MMIO range from 0x3fff0aa0000 to 0x3fff0aa15ff. */
+ Name (_CRS, ResourceTemplate () {
+ QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
+ NonCacheable, ReadWrite, 0x0,
+ IOM_BASE_ADDR, IOM_BASE_ADDR_MAX, 0x0,
+ IOM_BASE_SIZE,,,)
+ })
+ }
+
+ /*
+ * Operation region defined to access the TCSS_DEVEN. Get the MCHBAR in offset
+ * 0x48 in B0:D0:F0. TCSS device enable base address is in offset 0x7090 of MCHBAR.
+ */
+ OperationRegion (TDEN, SystemMemory, (GMHB() + MCHBAR_TCSS_DEVEN_OFFSET), 0x4)
+ Field (TDEN, ByteAcc, NoLock, Preserve)
+ {
+ TRE0, 1, /* PCIE0_EN */
+ TRE1, 1, /* PCIE1_EN */
+ TRE2, 1, /* PCIE2_EN */
+ TRE3, 1, /* PCIE3_EN */
+ , 4,
+ THCE, 1, /* XHCI_EN */
+ TDCE, 1, /* XDCI_EN */
+ DME0, 1, /* TBT_DMA0_EN */
+ DME1, 1, /* TBT_DMA1_EN */
+ , 20
+ }
+
+ /*
+ * Operation region defined to access the pCode mailbox interface. Get the MCHBAR
+ * in offset 0x48 in B0:D0:F0. MMIO address is in offset 0x5DA0 of MCHBAR.
+ */
+ OperationRegion (PBAR, SystemMemory, (GMHB() + 0x5DA0), 0x08)
+ Field (PBAR, DWordAcc, NoLock, Preserve)
+ {
+ PMBD, 32, /* pCode MailBox Data, offset 0x5DA0 in MCHBAR */
+ PMBC, 8, /* pCode MailBox Command, [7:0] of offset 0x5DA4 in MCHBAR */
+ PSCM, 8, /* pCode MailBox Sub-Command, [15:8] of offset 0x5DA4 in MCHBAR */
+ , 15, /* Reserved */
+ PMBR, 1 /* pCode MailBox RunBit, [31:31] of offset 0x5DA4 in MCHBAR */
+ }
+
+ /*
+ * Poll pCode MailBox Ready
+ *
+ * Return 0xFF - Timeout
+ * 0x00 - Ready
+ */
+ Method (PMBY, 0)
+ {
+ Local0 = 0
+ While (PMBR && (Local0 < 1000)) {
+ Local0++
+ Stall (1)
+ }
+ If (Local0 == 1000) {
+ Printf("Timeout occurred.")
+ Return (0xFF)
+ }
+ Return (0)
+ }
+
+ /*
+ * Method to send pCode MailBox command TCSS_DEVEN_MAILBOX_SUBCMD_GET_STATUS
+ *
+ * Result will be updated in DATA[1:0]
+ * DATA[0:0] TCSS_DEVEN_CURRENT_STATE:
+ * 0 - TCSS Deven in normal state.
+ * 1 - TCSS Deven is cleared by BIOS Mailbox request.
+ * DATA[1:1] TCSS_DEVEN_REQUEST_STATUS:
+ * 0 - IDLE. TCSS DEVEN has reached its final requested state.
+ * 1 - In Progress. TCSS DEVEN is currently in progress of switching state
+ * according to given request (bit 0 reflects source state).
+ *
+ * Return 0x00 - TCSS Deven in normal state
+ * 0x01 - TCSS Deven is cleared by BIOS Mailbox request
+ * 0x1x - TCSS Deven is in progress of switching state according to given request
+ * 0xFE - Command timeout
+ * 0xFF - Command corrupt
+ */
+ Method (DSGS, 0)
+ {
+ If ((PMBY () == 0)) {
+ PMBC = MAILBOX_BIOS_CMD_TCSS_DEVEN_INTERFACE
+ PSCM = TCSS_DEVEN_MAILBOX_SUBCMD_GET_STATUS
+ PMBR = 1
+ If (PMBY () == 0) {
+ Local0 = PMBD
+ Local1 = PMBC
+ Stall (10)
+ If ((Local0 != PMBD) || (Local1 != PMBC)) {
+ Printf("pCode MailBox is corrupt.")
+ Return (0xFF)
+ }
+ Return (Local0)
+ } Else {
+ Printf("pCode MailBox is not ready.")
+ Return (0xFE)
+ }
+ } Else {
+ Printf("pCode MailBox is not ready.")
+ Return (0xFE)
+ }
+ }
+
+ /*
+ * Method to send pCode MailBox command TCSS_DEVEN_MAILBOX_SUBCMD_TCSS_CHANGE_REQ
+ *
+ * Arg0 : 0 - Restore to previously saved value of TCSS DEVEN
+ * 1 - Save current TCSS DEVEN value and clear it
+ *
+ * Return 0x00 - MAILBOX_BIOS_CMD_CLEAR_TCSS_DEVEN command completed
+ * 0xFD - Input argument is invalid
+ * 0xFE - Command timeout
+ * 0xFF - Command corrupt
+ */
+ Method (DSCR, 1)
+ {
+ If (Arg0 > 1) {
+ Printf("pCode MailBox is corrupt.")
+ Return (0xFD)
+ }
+ If ((PMBY () == 0)) {
+ PMBC = MAILBOX_BIOS_CMD_TCSS_DEVEN_INTERFACE
+ PSCM = TCSS_DEVEN_MAILBOX_SUBCMD_TCSS_CHANGE_REQ
+ PMBD = Arg0
+ PMBR = 1
+ If ((PMBY () == 0)) {
+ Local0 = PMBD
+ Local1 = PMBC
+ Stall (10)
+ If ((Local0 != PMBD) || (Local1 != PMBC)) {
+ Printf("pCode MailBox is corrupt.")
+ Return (0xFF)
+ }
+ /* Poll TCSS_DEVEN_REQUEST_STATUS, timeout value is 10ms. */
+ Local0 = 0
+ While ((DSGS () & 0x10) && (Local0 < 100)) {
+ Stall (100)
+ Local0++
+ }
+ If (Local0 == 100) {
+ Printf("pCode MailBox is not ready.")
+ Return (0xFE)
+ } Else {
+ Return (0x00)
+ }
+ } Else {
+ Printf("pCode MailBox is not ready.")
+ Return (0xFE)
+ }
+ } Else {
+ Printf("pCode MailBox is not ready.")
+ Return (0xFE)
+ }
+ }
+
+ /* From RegBar Base, IOM_TypeC_SW_configuration_1 is at offset 0x40 */
+ OperationRegion (IOMR, SystemMemory, IOM_BASE_ADDR, 0x100)
+ Field (IOMR, DWordAcc, NoLock, Preserve)
+ {
+ Offset(0x40),
+ , 15,
+ TD3C, 1, /* [15:15] Type C D3 cold bit */
+ TACK, 1, /* [16:16] IOM Acknowledge bit */
+ DPOF, 1, /* [17:17] Set 1 to indicate IOM, all the */
+ /* display is OFF, clear otherwise */
+ Offset(0x70), /* Pyhsical addr is offset 0x70. */
+ IMCD, 32, /* R_SA_IOM_BIOS_MAIL_BOX_CMD */
+ IMDA, 32 /* R_SA_IOM_BIOS_MAIL_BOX_DATA */
+ }
+
+ /*
+ * TBT Group0 ON method
+ */
+ Method (TG0N, 0)
+ {
+ If (\_SB.PCI0.TDM0.VDID == 0xFFFFFFFF) {
+ Printf("TDM0 does not exist.")
+ } Else {
+ If (\_SB.PCI0.TDM0.STAT == 0) {
+ /* DMA0 is in D3Cold early. */
+ \_SB.PCI0.TDM0.D3CX() /* RTD3 Exit */
+
+ Printf("Bring TBT RPs out of D3Code.")
+ If (\_SB.PCI0.TRP0.VDID != 0xFFFFFFFF) {
+ /* RP0 D3 cold exit. */
+ \_SB.PCI0.TRP0.D3CX()
+ }
+ If (\_SB.PCI0.TRP1.VDID != 0xFFFFFFFF) {
+ /* RP1 D3 cold exit. */
+ \_SB.PCI0.TRP1.D3CX()
+ }
+ } Else {
+ Printf("Drop TG0N due to it is already exit D3 cold.")
+ }
+
+ /* TBT RTD3 exit 10ms delay. */
+ Sleep (10)
+ }
+ }
+
+ /*
+ * TBT Group0 OFF method
+ */
+ Method (TG0F, 0)
+ {
+ If (\_SB.PCI0.TDM0.VDID == 0xFFFFFFFF) {
+ Printf("TDM0 does not exist.")
+ } Else {
+ If (\_SB.PCI0.TDM0.STAT == 1) {
+ If (\_SB.PCI0.TDM0.INFR != 1) {
+ Return
+ }
+ /* DMA0 is not in D3Cold now. */
+ \_SB.PCI0.TDM0.D3CE() /* Enable DMA RTD3 */
+
+ Printf("Push TBT RPs to D3Cold together")
+ If (\_SB.PCI0.TRP0.VDID != 0xFFFFFFFF) {
+ /* Put RP0 to D3 cold. */
+ \_SB.PCI0.TRP0.D3CE()
+ }
+ If (\_SB.PCI0.TRP1.VDID != 0xFFFFFFFF) {
+ /* Put RP1 to D3 cold. */
+ \_SB.PCI0.TRP1.D3CE()
+ }
+ }
+ }
+ }
+
+ /*
+ * TBT Group1 ON method
+ */
+ Method (TG1N, 0)
+ {
+ If (\_SB.PCI0.TDM1.VDID == 0xFFFFFFFF) {
+ Printf("TDM1 does not exist.")
+ } Else {
+ If (\_SB.PCI0.TDM1.STAT == 0) {
+ /* DMA1 is in D3Cold early. */
+ \_SB.PCI0.TDM1.D3CX() /* RTD3 Exit */
+
+ Printf("Bring TBT RPs out of D3Code.")
+ If (\_SB.PCI0.TRP2.VDID != 0xFFFFFFFF) {
+ /* RP2 D3 cold exit. */
+ \_SB.PCI0.TRP2.D3CX()
+ }
+ If (\_SB.PCI0.TRP3.VDID != 0xFFFFFFFF) {
+ /* RP3 D3 cold exit. */
+ \_SB.PCI0.TRP3.D3CX()
+ }
+ } Else {
+ Printf("Drop TG1N due to it is already exit D3 cold.")
+ }
+
+ /* TBT RTD3 exit 10ms delay. */
+ Sleep (10)
+ }
+ }
+
+ /*
+ * TBT Group1 OFF method
+ */
+ Method (TG1F, 0)
+ {
+ If (\_SB.PCI0.TDM1.VDID == 0xFFFFFFFF) {
+ Printf("TDM1 does not exist.")
+ } Else {
+ If (\_SB.PCI0.TDM1.STAT == 1) {
+ If (\_SB.PCI0.TDM1.INFR != 1) {
+ Return
+ }
+ /* DMA1 is not in D3Cold now */
+ \_SB.PCI0.TDM1.D3CE() /* Enable DMA RTD3. */
+
+ Printf("Push TBT RPs to D3Cold together")
+ If (\_SB.PCI0.TRP2.VDID != 0xFFFFFFFF) {
+ /* Put RP2 to D3 cold. */
+ \_SB.PCI0.TRP2.D3CE()
+ }
+ If (\_SB.PCI0.TRP3.VDID != 0xFFFFFFFF) {
+ /* Put RP3 to D3 cold */
+ \_SB.PCI0.TRP3.D3CE()
+ }
+ }
+ }
+ }
+
+ PowerResource (TBT0, 5, 1)
+ {
+ Method (_STA, 0)
+ {
+ Return (\_SB.PCI0.TDM0.STAT)
+ }
+
+ Method (_ON, 0)
+ {
+ TG0N()
+ }
+
+ Method (_OFF, 0)
+ {
+ If (\_SB.PCI0.TDM0.SD3C == 0) {
+ TG0F()
+ }
+ }
+ }
+
+ PowerResource (TBT1, 5, 1)
+ {
+ Method (_STA, 0)
+ {
+ Return (\_SB.PCI0.TDM1.STAT)
+ }
+
+ Method (_ON, 0)
+ {
+ TG1N()
+ }
+
+ Method (_OFF, 0)
+ {
+ If (\_SB.PCI0.TDM1.SD3C == 0) {
+ TG1F()
+ }
+ }
+ }
+
+ Method (TCON, 0)
+ {
+ /* Reset IOM D3 cold bit if it is in D3 cold now. */
+ If (TD3C == 1) /* It was in D3 cold before. */
+ {
+ /* Reset IOM D3 cold bit. */
+ TD3C = 0 /* Request IOM for D3 cold exit sequence. */
+ Local0 = 0 /* Time check counter variable */
+ /* Wait for ack, the maximum wait time for the ack is 100 msec. */
+ While ((TACK != 0) && (Local0 < TCSS_IOM_ACK_TIMEOUT_IN_MS)) {
+ /*
+ * Wait in this loop until TACK becomes 0 with timeout
+ * TCSS_IOM_ACK_TIMEOUT_IN_MS by default.
+ */
+ Sleep (1) /* Delay of 1ms. */
+ Local0++
+ }
+
+ If (Local0 == TCSS_IOM_ACK_TIMEOUT_IN_MS) {
+ Printf("Error: Timeout occurred.")
+ }
+ Else
+ {
+ /*
+ * If the TCSS Deven is cleared by BIOS Mailbox request, then
+ * restore to previously saved value of TCSS DEVNE.
+ */
+ Local0 = 0
+ While (\_SB.PCI0.TXHC.VDID == 0xFFFFFFFF) {
+ If (DSGS () == 1) {
+ DSCR (0)
+ }
+ Local0++
+ If (Local0 == 5) {
+ Printf("pCode mailbox command failed.")
+ Break
+ }
+ }
+ }
+ }
+ Else {
+ Printf("Drop TCON due to it is already exit D3 cold.")
+ }
+ }
+
+ Method (TCOF, 0)
+ {
+ If ((\_SB.PCI0.TXHC.SD3C != 0) || (\_SB.PCI0.TDM0.SD3C != 0)
+ || (\_SB.PCI0.TDM1.SD3C != 0))
+ {
+ Printf("Skip D3C entry.")
+ Return
+ }
+
+ /*
+ * If the TCSS Deven in normal state, then Save current TCSS DEVEN value and
+ * clear it.
+ */
+ Local0 = 0
+ While (\_SB.PCI0.TXHC.VDID != 0xFFFFFFFF) {
+ If (DSGS () == 0) {
+ DSCR (1)
+ }
+ Local0++
+ If (Local0 == 5) {
+ Printf("pCode mailbox command failed.")
+ Break
+ }
+ }
+
+ /* Request IOM for D3 cold entry sequence. */
+ TD3C = 1
+ }
+
+ PowerResource (D3C, 5, 0)
+ {
+ /*
+ * Variable to save power state
+ * 1 - TC Cold request cleared.
+ * 0 - TC Cold request sent.
+ */
+ Name (STAT, 0x1)
+
+ Method (_STA, 0)
+ {
+ Return (STAT)
+ }
+
+ Method (_ON, 0)
+ {
+ \_SB.PCI0.TCON()
+ STAT = 1
+ }
+
+ Method (_OFF, 0)
+ {
+ \_SB.PCI0.TCOF()
+ STAT = 0
+ }
+ }
+
+ /*
+ * TCSS xHCI device
+ */
+ Device (TXHC)
+ {
+ Name (_ADR, 0x000D0000)
+ Name (_DDN, "North XHCI controller")
+ Name (_STR, Unicode ("North XHCI controller"))
+ Name (DCPM, TCSS_XHCI)
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If (THCE == 1) {
+ Return (0x0F)
+ } Else {
+ Return (0x0)
+ }
+ }
+ #include "tcss_xhci.asl"
+ }
+
+ /*
+ * TCSS DMA0 device
+ */
+ Device (TDM0)
+ {
+ Name (_ADR, 0x000D0002)
+ Name (_DDN, "TBT DMA0 controller")
+ Name (_STR, Unicode ("TBT DMA0 controller"))
+ Name (DUID, 0) /* TBT DMA number */
+ Name (DCPM, TCSS_DMA0)
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If (DME0 == 1) {
+ Return (0x0F)
+ } Else {
+ Return (0x0)
+ }
+ }
+ #include "tcss_dma.asl"
+ }
+
+ /*
+ * TCSS DMA1 device
+ */
+ Device (TDM1)
+ {
+ Name (_ADR, 0x000D0003)
+ Name (_DDN, "TBT DMA1 controller")
+ Name (_STR, Unicode ("TBT DMA1 controller"))
+ Name (DUID, 1) /* TBT DMA number */
+ Name (DCPM, TCSS_DMA1)
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If (DME1 == 1) {
+ Return (0x0F)
+ } Else {
+ Return (0x0)
+ }
+ }
+ #include "tcss_dma.asl"
+ }
+
+ /*
+ * TCSS PCIE Root Port #00
+ */
+ Device (TRP0)
+ {
+ Name (_ADR, 0x00070000)
+ Name (TUID, 0) /* TBT PCIE RP Number 0 for RP00 */
+ Name (LTEN, 0) /* Latency Tolerance Reporting Mechanism, 0:Disable, 1:Enable */
+ Name (LMSL, 0) /* PCIE LTR max snoop Latency */
+ Name (LNSL, 0) /* PCIE LTR max no snoop Latency */
+ Name (DCPM, TCSS_TBT_PCIE0_RP0)
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If (TRE0 == 1) {
+ Return (0x0F)
+ } Else {
+ Return (0x0)
+ }
+ }
+
+ Method (_INI)
+ {
+ LTEN = 0
+ LMSL = 0x88C8
+ LNSL = 0x88C8
+ }
+ #include "tcss_pcierp.asl"
+ }
+
+ /*
+ * TCSS PCIE Root Port #01
+ */
+ Device (TRP1)
+ {
+ Name (_ADR, 0x00070001)
+ Name (TUID, 1) /* TBT PCIE RP Number 1 for RP01 */
+ Name (LTEN, 0) /* Latency Tolerance Reporting Mechanism, 0:Disable, 1:Enable */
+ Name (LMSL, 0) /* PCIE LTR max snoop Latency */
+ Name (LNSL, 0) /* PCIE LTR max no snoop Latency */
+ Name (DCPM, TCSS_TBT_PCIE0_RP1)
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If (TRE1 == 1) {
+ Return (0x0F)
+ } Else {
+ Return (0x0)
+ }
+ }
+
+ Method (_INI)
+ {
+ LTEN = 0
+ LMSL = 0x88C8
+ LNSL = 0x88C8
+ }
+ #include "tcss_pcierp.asl"
+ }
+
+ /*
+ * TCSS PCIE Root Port #02
+ */
+ Device (TRP2)
+ {
+ Name (_ADR, 0x00070002)
+ Name (TUID, 2) /* TBT PCIE RP Number 2 for RP02 */
+ Name (LTEN, 0) /* Latency Tolerance Reporting Mechanism, 0:Disable, 1:Enable */
+ Name (LMSL, 0) /* PCIE LTR max snoop Latency */
+ Name (LNSL, 0) /* PCIE LTR max no snoop Latency */
+ Name (DCPM, TCSS_TBT_PCIE0_RP2)
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If (TRE2 == 1) {
+ Return (0x0F)
+ } Else {
+ Return (0x0)
+ }
+ }
+
+ Method (_INI)
+ {
+ LTEN = 0
+ LMSL = 0x88C8
+ LNSL = 0x88C8
+ }
+ #include "tcss_pcierp.asl"
+ }
+
+ /*
+ * TCSS PCIE Root Port #03
+ */
+ Device (TRP3)
+ {
+ Name (_ADR, 0x00070003)
+ Name (TUID, 3) /* TBT PCIE RP Number 3 for RP03 */
+ Name (LTEN, 0) /* Latency Tolerance Reporting Mechanism, 0:Disable, 1:Enable */
+ Name (LMSL, 0) /* PCIE LTR max snoop Latency */
+ Name (LNSL, 0) /* PCIE LTR max no snoop Latency */
+ Name (DCPM, TCSS_TBT_PCIE0_RP3)
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If (TRE3 == 1) {
+ Return (0x0F)
+ } Else {
+ Return (0x0)
+ }
+ }
+
+ Method (_INI)
+ {
+ LTEN = 0
+ LMSL = 0x88C8
+ LNSL = 0x88C8
+ }
+ #include "tcss_pcierp.asl"
+ }
+}
diff --git a/src/soc/intel/meteorlake/acpi/tcss_dma.asl b/src/soc/intel/meteorlake/acpi/tcss_dma.asl
new file mode 100644
index 0000000000..d00f79432d
--- /dev/null
+++ b/src/soc/intel/meteorlake/acpi/tcss_dma.asl
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+OperationRegion (DPME, SystemMemory, BASE(_ADR), 0x100)
+Field (DPME, AnyAcc, NoLock, Preserve)
+{
+ VDID, 32,
+ Offset(0x84), /* 0x84, DMA CFG PM CAP */
+ PMST, 2, /* 1:0, PM_STATE */
+ , 6,
+ PMEE, 1, /* 8, PME_EN */
+ , 6,
+ PMES, 1, /* 15, PME_STATUS */
+ Offset(0xC8), /* 0xC8, TBT NVM FW Revision */
+ , 31,
+ INFR, 1, /* TBT NVM FW Ready */
+ Offset(0xEC), /* 0xEC, TBT TO PCIE Register */
+ TB2P, 32, /* TBT to PCIe */
+ P2TB, 32, /* PCIe to TBT */
+ Offset(0xFC), /* 0xFC, DMA RTD3 Force Power */
+ DD3E, 1, /* 0:0 DMA RTD3 Enable */
+ DFPE, 1, /* 1:1 DMA Force Power */
+ , 22,
+ DMAD, 8 /* 31:24 DMA Active Delay */
+}
+
+Name (STAT, 0x1) /* Variable to save power state 1 - D0, 0 - D3C */
+
+Method (_S0W, 0x0)
+{
+ Return (0x4)
+}
+
+Method (_PR0)
+{
+ If (DUID == 0) {
+ Return (Package() { \_SB.PCI0.D3C, \_SB.PCI0.TBT0 })
+ } Else {
+ Return (Package() { \_SB.PCI0.D3C, \_SB.PCI0.TBT1 })
+ }
+}
+
+Method (_PR3)
+{
+ If (DUID == 0) {
+ Return (Package() { \_SB.PCI0.D3C, \_SB.PCI0.TBT0 })
+ } Else {
+ Return (Package() { \_SB.PCI0.D3C, \_SB.PCI0.TBT1 })
+ }
+}
+
+/*
+ * RTD3 Exit Method to bring TBT controller out of RTD3 mode.
+ */
+Method (D3CX, 0, Serialized)
+{
+ DD3E = 0 /* Disable DMA RTD3 */
+ STAT = 0x1
+}
+
+/*
+ * RTD3 Entry method to enable TBT controller RTD3 mode.
+ */
+Method (D3CE, 0, Serialized)
+{
+ DD3E = 1 /* Enable DMA RTD3 */
+ STAT = 0
+}
+
+/*
+ * Variable to skip TCSS/TBT D3 cold; 1+: Skip D3CE, 0 - Enable D3CE
+ * TCSS D3 Cold and TBT RTD3 is only available when system power state is in S0.
+ */
+Name (SD3C, 0)
+
+Method (_DSW, 3)
+{
+ /* If entering Sx (Arg1 > 1), need to skip TCSS D3Cold & TBT RTD3/D3Cold. */
+ SD3C = Arg1
+}
+
+Method (_PRW, 0)
+{
+ Return (Package() { 0x6D, 4 })
+}
diff --git a/src/soc/intel/meteorlake/acpi/tcss_pcierp.asl b/src/soc/intel/meteorlake/acpi/tcss_pcierp.asl
new file mode 100644
index 0000000000..48b8c739c5
--- /dev/null
+++ b/src/soc/intel/meteorlake/acpi/tcss_pcierp.asl
@@ -0,0 +1,290 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+OperationRegion (PXCS, SystemMemory, BASE(_ADR), 0x800)
+Field (PXCS, AnyAcc, NoLock, Preserve)
+{
+ VDID, 32,
+ Offset(0x50), /* LCTL - Link Control Register */
+ L0SE, 1, /* 0, L0s Entry Enabled */
+ , 3,
+ LDIS, 1, /* 1, Link Disable */
+ , 3,
+ Offset(0x52), /* LSTS - Link Status Register */
+ , 13,
+ LASX, 1, /* 0, Link Active Status */
+ Offset(0x5A), /* SLSTS[7:0] - Slot Status Register */
+ ABPX, 1, /* 0, Attention Button Pressed */
+ , 2,
+ PDCX, 1, /* 3, Presence Detect Changed */
+ , 2,
+ PDSX, 1, /* 6, Presence Detect State */
+ , 1,
+ DLSC, 1, /* 8, Data Link Layer State Changed */
+ Offset(0x60), /* RSTS - Root Status Register */
+ , 16,
+ PSPX, 1, /* 16, PME Status */
+ Offset(0xA4),
+ D3HT, 2, /* Power State */
+ Offset(0xD8), /* 0xD8, MPC - Miscellaneous Port Configuration Register */
+ , 30,
+ HPEX, 1, /* 30, Hot Plug SCI Enable */
+ PMEX, 1, /* 31, Power Management SCI Enable */
+ Offset(0xE2), /* 0xE2, RPPGEN - Root Port Power Gating Enable */
+ , 2,
+ L23E, 1, /* 2, L23_Rdy Entry Request (L23ER) */
+ L23R, 1, /* 3, L23_Rdy to Detect Transition (L23R2DT) */
+ Offset(0x420), /* 0x420, PCIEPMECTL (PCIe PM Extension Control) */
+ , 30,
+ DPGE, 1, /* PCIEPMECTL[30]: Disabled, Detect and L23_Rdy State PHY Lane */
+ /* Power Gating Enable (DLSULPPGE) */
+ Offset(0x5BC), /* 0x5BC, PCIE ADVMCTRL */
+ , 3,
+ RPER, 1, /* RTD3PERST[3] */
+ RPFE, 1, /* RTD3PFETDIS[4] */
+}
+
+Field (PXCS, AnyAcc, NoLock, WriteAsZeros)
+{
+ Offset(0xDC), /* 0xDC, SMSCS - SMI/SCI Status Register */
+ , 30,
+ HPSX, 1, /* 30, Hot Plug SCI Status */
+ PMSX, 1 /* 31, Power Management SCI Status */
+}
+
+/*
+ * _DSM Device Specific Method
+ *
+ * Arg0: UUID Unique function identifier
+ * Arg1: Integer Revision Level
+ * Arg2: Integer Function Index (0 = Return Supported Functions)
+ * Arg3: Package Parameters
+ */
+Method (_DSM, 4, Serialized)
+{
+ Return (Buffer() { 0x00 })
+}
+
+/*
+ * A bitmask of functions support
+ */
+Name(OPTS, Buffer(2) {0, 0})
+
+Device (PXSX)
+{
+ Name (_ADR, 0x00000000)
+
+ /*
+ * _DSM Device Specific Method
+ *
+ * Arg0: UUID: E5C937D0-3553-4d7a-9117-EA4D19C3434D
+ * Arg1: Revision ID: 3
+ * Arg2: Function index: 0, 9
+ * Arg3: Empty package
+ */
+ Method (_DSM, 4, Serialized)
+ {
+ If (Arg0 == ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D")) {
+ If (Arg1 >= 3) {
+ If (Arg2 == 0) {
+ /*
+ * Function index: 0
+ * Standard query - A bitmask of functions supported
+ */
+ CreateBitField(OPTS, 9, FUN9)
+ FUN9 = 1
+ Return (OPTS)
+ } ElseIf (Arg2 == 9) {
+ /*
+ * Function index: 9
+ * Specifying device readiness durations
+ */
+ Return (Package() { FW_RESET_TIME, FW_DL_UP_TIME,
+ FW_FLR_RESET_TIME, FW_D3HOT_TO_D0_TIME,
+ FW_VF_ENABLE_TIME })
+ }
+ }
+ }
+ Return (Buffer() { 0x0 })
+ }
+
+ Method (_PRW, 0)
+ {
+ Return (Package() { 0x69, 4 })
+ }
+}
+
+Method (_DSW, 3)
+{
+ /* If entering Sx (Arg1 > 1), need to skip TCSS D3Cold & TBT RTD3/D3Cold. */
+ If ((TUID == 0) || (TUID == 1)) {
+ \_SB.PCI0.TDM0.SD3C = Arg1
+ } Else {
+ \_SB.PCI0.TDM1.SD3C = Arg1
+ }
+
+ C2PM (Arg0, Arg1, Arg2, DCPM)
+}
+
+Method (_PRW, 0)
+{
+ Return (Package() { 0x69, 4 })
+}
+
+/*
+ * Sub-Method of _L61 Hot-Plug event
+ * _L61 event handler should invoke this method to support HotPlug wake event from TBT RP.
+ */
+Method (HPEV, 0, Serialized)
+{
+ If ((VDID != 0xFFFFFFFF) && HPSX) {
+ If ((PDCX == 1) && (DLSC == 1)) {
+ /* Clear all status bits first. */
+ PDCX = 1
+ HPSX = 1
+
+ /* Perform proper notification to the OS. */
+ Notify (^, 0)
+ } Else {
+ /* False event. Clear Hot-Plug Status, then exit. */
+ HPSX = 1
+ }
+ }
+}
+
+/*
+ * Power Management routine for D3
+ */
+Name (STAT, 0x1) /* Variable to save power state 1 - D0, 0 - D3C */
+
+/*
+ * RTD3 Exit Method to bring TBT controller out of RTD3 mode.
+ */
+Method (D3CX, 0, Serialized)
+{
+ If (STAT == 0x1) {
+ Return
+ }
+
+ RPFE = 0 /* Set RTD3PFETDIS = 0 */
+ RPER = 0 /* Set RTD3PERST = 0 */
+ L23R = 1 /* Set L23r2dt = 1 */
+
+ /*
+ * Poll for L23r2dt == 0. Wait for transition to Detect.
+ */
+ Local0 = 0
+ Local1 = L23R
+ While (Local1) {
+ If (Local0 > 20) {
+ Break
+ }
+ Sleep(5)
+ Local0++
+ Local1 = L23R
+ }
+ STAT = 0x1
+}
+
+/*
+ * RTD3 Entry method to enable TBT controller RTD3 mode.
+ */
+Method (D3CE, 0, Serialized)
+{
+ If (STAT == 0x0) {
+ Return
+ }
+
+ L23E = 1 /* Set L23er = 1 */
+
+ /* Poll until L23er == 0 */
+ Local0 = 0
+ Local1 = L23E
+ While (Local1) {
+ If (Local0 > 20) {
+ Break
+ }
+ Sleep(5)
+ Local0++
+ Local1 = L23E
+ }
+
+ STAT = 0 /* D3Cold */
+ RPFE = 1 /* Set RTD3PFETDIS = 1 */
+ RPER = 1 /* Set RTD3PERST = 1 */
+}
+
+Method (_PS0, 0, Serialized)
+{
+ HPEV () /* Check and handle Hot Plug SCI status. */
+ If (HPEX == 1) {
+ HPEX = 0 /* Disable Hot Plug SCI */
+ }
+ HPME () /* Check and handle PME SCI status */
+ If (PMEX == 1) {
+ PMEX = 0 /* Disable Power Management SCI */
+ }
+}
+
+Method (_PS3, 0, Serialized)
+{
+ /* Check it is hotplug SCI or not, then clear PDC accordingly */
+ If (PDCX == 1) {
+ If (DLSC == 0) {
+ /* Clear PDC since it is not a hotplug. */
+ PDCX = 1
+ }
+ }
+
+ If (HPEX == 0) {
+ HPEX = 1 /* Enable Hot Plug SCI. */
+ HPEV () /* Check and handle Hot Plug SCI status. */
+ }
+ If (PMEX == 0) {
+ PMEX = 1 /* Enable Power Management SCI. */
+ HPME () /* Check and handle PME SCI status. */
+ }
+}
+
+Method (_S0W, 0x0, NotSerialized)
+{
+ Return (0x4)
+}
+
+Method (_PR0)
+{
+ If ((TUID == 0) || (TUID == 1)) {
+ Return (Package() { \_SB.PCI0.D3C, \_SB.PCI0.TBT0 })
+ } Else {
+ Return (Package() { \_SB.PCI0.D3C, \_SB.PCI0.TBT1 })
+ }
+}
+
+Method (_PR3)
+{
+ If ((TUID == 0) || (TUID == 1)) {
+ Return (Package() { \_SB.PCI0.D3C, \_SB.PCI0.TBT0 })
+ } Else {
+ Return (Package() { \_SB.PCI0.D3C, \_SB.PCI0.TBT1 })
+ }
+}
+
+/*
+ * PCI_EXP_STS Handler for PCIE Root Port
+ */
+Method (HPME, 0, Serialized)
+{
+ If ((VDID != 0xFFFFFFFF) && (PMSX == 1)) { /* if port exists and PME SCI Status set */
+ /*
+ * Notify child device; this will cause its driver to clear PME_Status from
+ * device.
+ */
+ Notify (PXSX, 0x2)
+ PMSX = 1 /* clear rootport's PME SCI status */
+ /*
+ * Consume one pending PME notification to prevent it from blocking the queue.
+ */
+ PSPX = 1
+ Return (0x01)
+ }
+ Return (0x00)
+}
diff --git a/src/soc/intel/meteorlake/acpi/tcss_xhci.asl b/src/soc/intel/meteorlake/acpi/tcss_xhci.asl
new file mode 100644
index 0000000000..acbeb30c13
--- /dev/null
+++ b/src/soc/intel/meteorlake/acpi/tcss_xhci.asl
@@ -0,0 +1,182 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+OperationRegion (XPRT, SystemMemory, BASE(_ADR), 0x100)
+Field (XPRT, ByteAcc, NoLock, Preserve)
+{
+ VDID, 32,
+ Offset(0x74), /* 0x74, XHCI CFG Power Control And Status */
+ D0D3, 2, /* 0x74 BIT[1:0] */
+ , 6,
+ PMEE, 1, /* PME Enable */
+ , 6,
+ PMES, 1, /* PME Status */
+}
+
+Method (_PS0, 0, Serialized)
+{
+ If (\_SB.PCI0.TXHC.PMEE == 1) {
+ /* Clear PME_EN of CPU xHCI */
+ \_SB.PCI0.TXHC.PMEE = 0
+ }
+}
+
+Method (_PS3, 0, Serialized)
+{
+ If (\_SB.PCI0.TXHC.PMEE == 0) {
+ /* Set PME_EN of CPU xHCI */
+ \_SB.PCI0.TXHC.PMEE = 1
+ }
+}
+
+Method (_S0W, 0x0, NotSerialized)
+{
+ Return (0x4)
+}
+
+/*
+ * Variable to skip TCSS/TBT D3 cold; 1+: Skip D3CE, 0 - Enable D3CE
+ * TCSS D3 Cold and TBT RTD3 is only available when system power state is in S0.
+ */
+Name (SD3C, 0)
+
+Method (_PR0)
+{
+ Return (Package () { \_SB.PCI0.D3C })
+}
+
+Method (_PR3)
+{
+ Return (Package () { \_SB.PCI0.D3C })
+}
+
+/*
+ * XHCI controller _DSM method
+ */
+Method (_DSM, 4, serialized)
+{
+ Return (Buffer() { 0 })
+}
+
+/*
+ * _SXD and _SXW methods
+ */
+Method (_S3D, 0, NotSerialized)
+{
+ Return (3)
+}
+
+Method (_S4D, 0, NotSerialized)
+{
+ Return (3)
+}
+
+Method (_S3W, 0, NotSerialized)
+{
+ Return (3)
+}
+
+Method (_S4W, 0, NotSerialized)
+{
+ Return (3)
+}
+
+/*
+ * Power resource for wake
+ */
+Method (_PRW, 0)
+{
+ Return (Package() { 0x6D, 4 })
+}
+
+/*
+ * Device sleep wake
+ */
+Method (_DSW, 3)
+{
+ C2PM (Arg0, Arg1, Arg2, DCPM)
+ /* If entering Sx (Arg1 > 1), need to skip TCSS D3Cold & TBT RTD3/D3Cold. */
+ SD3C = Arg1
+}
+
+/*
+ * xHCI Root Hub Device
+ */
+Device (RHUB)
+{
+ Name (_ADR, Zero)
+
+ /* High Speed Ports */
+ Device (HS01)
+ {
+ Name (_ADR, 0x01)
+ }
+
+ /* Super Speed Ports */
+ Device (SS01)
+ {
+ Name (_ADR, 0x02)
+ Method (_DSD, 0, NotSerialized)
+ {
+ Return( Package ()
+ {
+ ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ Package ()
+ {
+ Package (2) { "usb4-host-interface", \_SB.PCI0.TDM0 },
+ Package (2) { "usb4-port-number", 0 }
+ }
+ })
+ }
+ }
+
+ Device (SS02)
+ {
+ Name (_ADR, 0x03)
+ Method (_DSD, 0, NotSerialized)
+ {
+ Return( Package ()
+ {
+ ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ Package ()
+ {
+ Package (2) { "usb4-host-interface", \_SB.PCI0.TDM0 },
+ Package (2) { "usb4-port-number", 1 }
+ }
+ })
+ }
+ }
+
+ Device (SS03)
+ {
+ Name (_ADR, 0x04)
+ Method (_DSD, 0, NotSerialized)
+ {
+ Return( Package ()
+ {
+ ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ Package ()
+ {
+ Package (2) { "usb4-host-interface", \_SB.PCI0.TDM1 },
+ Package (2) { "usb4-port-number", 0 }
+ }
+ })
+ }
+ }
+
+ Device (SS04)
+ {
+ Name (_ADR, 0x05)
+ Method (_DSD, 0, NotSerialized)
+ {
+ Return( Package ()
+ {
+ ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+ Package ()
+ {
+ Package (2) { "usb4-host-interface", \_SB.PCI0.TDM1 },
+ Package (2) { "usb4-port-number", 1 }
+ }
+ })
+ }
+ }
+}
diff --git a/src/soc/intel/meteorlake/acpi/xhci.asl b/src/soc/intel/meteorlake/acpi/xhci.asl
new file mode 100644
index 0000000000..34b96f35d7
--- /dev/null
+++ b/src/soc/intel/meteorlake/acpi/xhci.asl
@@ -0,0 +1,47 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <soc/gpe.h>
+
+/* XHCI Controller 0:14.0 */
+
+Device (XHCI)
+{
+ Name (_ADR, 0x00140000)
+
+ Name (_PRW, Package () { GPE0_PME_B0, 3 })
+
+ Name (_S3D, 3) /* D3 supported in S3 */
+ Name (_S0W, 3) /* D3 can wake device in S0 */
+ Name (_S3W, 3) /* D3 can wake system from S3 */
+
+ Method (_PS0, 0, Serialized)
+ {
+
+ }
+
+ Method (_PS3, 0, Serialized)
+ {
+
+ }
+
+ /* Root Hub for Meteorlake */
+ Device (RHUB)
+ {
+ Name (_ADR, Zero)
+
+ /* USB2 */
+ Device (HS01) { Name (_ADR, 1) }
+ Device (HS02) { Name (_ADR, 2) }
+ Device (HS03) { Name (_ADR, 3) }
+ Device (HS04) { Name (_ADR, 4) }
+ Device (HS05) { Name (_ADR, 5) }
+ Device (HS06) { Name (_ADR, 6) }
+ Device (HS07) { Name (_ADR, 7) }
+ Device (HS08) { Name (_ADR, 8) }
+ Device (HS09) { Name (_ADR, 9) }
+ Device (HS10) { Name (_ADR, 10) }
+ /* USB3 */
+ Device (SS01) { Name (_ADR, 11) }
+ Device (SS02) { Name (_ADR, 12) }
+ }
+}
diff --git a/src/soc/intel/meteorlake/include/soc/tcss.h b/src/soc/intel/meteorlake/include/soc/tcss.h
index 014e3076e6..439606c6af 100644
--- a/src/soc/intel/meteorlake/include/soc/tcss.h
+++ b/src/soc/intel/meteorlake/include/soc/tcss.h
@@ -13,4 +13,24 @@
#define IOM_AUX_BIAS_CTRL_PULLDOWN_OFFSET_0 0x1088
#define IOM_AUX_BIAS_CTRL_PULLDOWN_OFFSET(x) (IOM_AUX_BIAS_CTRL_PULLDOWN_OFFSET_0 + (x) * 4)
+/*
+ * The PCI-SIG engineering change requirement provides the ACPI additions for firmware latency
+ * optimization. Both of FW_RESET_TIME and FW_D3HOT_TO_D0_TIME are applicable to the upstream
+ * port of the USB4/TBT topology.
+ */
+/* Number of microseconds to wait after a conventional reset */
+#define FW_RESET_TIME 50000
+
+/* Number of microseconds to wait after data link layer active report */
+#define FW_DL_UP_TIME 1
+
+/* Number of microseconds to wait after a function level reset */
+#define FW_FLR_RESET_TIME 1
+
+/* Number of microseconds to wait from D3 hot to D0 transition */
+#define FW_D3HOT_TO_D0_TIME 50000
+
+/* Number of microseconds to wait after setting the VF enable bit */
+#define FW_VF_ENABLE_TIME 1
+
#endif /* _SOC_TCSS_H_ */