soc/amd/sabrina: add additional UART controllers

Compared to Cezanne there are 3 more UART controllers. Revision 1.50 of
the PPR #57243 was used as a reference.

Signed-off-by: Felix Held <felix-coreboot@felixheld.de>
Change-Id: I628b1a7a0930f3409acdcabda2b864d42bf6bd23
Reviewed-on: https://review.coreboot.org/c/coreboot/+/61086
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Marshall Dawson <marshalldawson3rd@gmail.com>
Reviewed-by: Jason Glenesk <jason.glenesk@gmail.com>
diff --git a/src/soc/amd/sabrina/Kconfig b/src/soc/amd/sabrina/Kconfig
index 6e84bf7..5e0c71f 100644
--- a/src/soc/amd/sabrina/Kconfig
+++ b/src/soc/amd/sabrina/Kconfig
@@ -236,6 +236,9 @@
 	hex
 	default 0xfedc9000 if UART_FOR_CONSOLE = 0
 	default 0xfedca000 if UART_FOR_CONSOLE = 1
+	default 0xfedce000 if UART_FOR_CONSOLE = 2
+	default 0xfedcf000 if UART_FOR_CONSOLE = 3
+	default 0xfedd1000 if UART_FOR_CONSOLE = 4
 
 config SMM_TSEG_SIZE
 	hex
diff --git a/src/soc/amd/sabrina/acpi/mmio.asl b/src/soc/amd/sabrina/acpi/mmio.asl
index 381405f..48ae1d2 100644
--- a/src/soc/amd/sabrina/acpi/mmio.asl
+++ b/src/soc/amd/sabrina/acpi/mmio.asl
@@ -124,6 +124,99 @@
 	AOAC_DEVICE(FCH_AOAC_DEV_UART1, 0)
 }
 
+Device (FUR2) {
+	Name (_HID, "AMDI0020")
+	Name (_UID, 0x2)
+	Method (_CRS, 0) {
+		Local0 = ResourceTemplate() {
+			Interrupt (
+				ResourceConsumer,
+				Edge,
+				ActiveHigh,
+				Exclusive, , , IRQR)
+			{ 0 }
+			Memory32Fixed (ReadWrite, APU_UART2_BASE, 0x1000)
+		}
+		CreateDWordField (Local0, IRQR._INT, IRQN)
+		If (PICM) {
+			IRQN = IUA2
+		} Else {
+			IRQN = PUA2
+		}
+		If (IRQN == 0x1f) {
+			Return (ResourceTemplate() {
+				Memory32Fixed (ReadWrite, APU_UART2_BASE, 0x1000)
+			})
+		} Else {
+			Return (Local0)
+		}
+	}
+
+	AOAC_DEVICE(FCH_AOAC_DEV_UART2, 0)
+}
+
+Device (FUR3) {
+	Name (_HID, "AMDI0020")
+	Name (_UID, 0x3)
+	Method (_CRS, 0) {
+		Local0 = ResourceTemplate() {
+			Interrupt (
+				ResourceConsumer,
+				Edge,
+				ActiveHigh,
+				Exclusive, , , IRQR)
+			{ 0 }
+			Memory32Fixed (ReadWrite, APU_UART3_BASE, 0x1000)
+		}
+		CreateDWordField (Local0, IRQR._INT, IRQN)
+		If (PICM) {
+			IRQN = IUA3
+		} Else {
+			IRQN = PUA3
+		}
+		If (IRQN == 0x1f) {
+			Return (ResourceTemplate() {
+				Memory32Fixed (ReadWrite, APU_UART3_BASE, 0x1000)
+			})
+		} Else {
+			Return (Local0)
+		}
+	}
+
+	AOAC_DEVICE(FCH_AOAC_DEV_UART3, 0)
+}
+
+Device (FUR4) {
+	Name (_HID, "AMDI0020")
+	Name (_UID, 0x4)
+	Method (_CRS, 0) {
+		Local0 = ResourceTemplate() {
+			Interrupt (
+				ResourceConsumer,
+				Edge,
+				ActiveHigh,
+				Exclusive, , , IRQR)
+			{ 0 }
+			Memory32Fixed (ReadWrite, APU_UART4_BASE, 0x1000)
+		}
+		CreateDWordField (Local0, IRQR._INT, IRQN)
+		If (PICM) {
+			IRQN = IUA4
+		} Else {
+			IRQN = PUA4
+		}
+		If (IRQN == 0x1f) {
+			Return (ResourceTemplate() {
+				Memory32Fixed (ReadWrite, APU_UART4_BASE, 0x1000)
+			})
+		} Else {
+			Return (Local0)
+		}
+	}
+
+	AOAC_DEVICE(FCH_AOAC_DEV_UART4, 0)
+}
+
 Device (I2C0) {
 	Name (_HID, "AMDI0010")
 	Name (_UID, 0x0)
diff --git a/src/soc/amd/sabrina/aoac.c b/src/soc/amd/sabrina/aoac.c
index 33b00b4..ab525441 100644
--- a/src/soc/amd/sabrina/aoac.c
+++ b/src/soc/amd/sabrina/aoac.c
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 
-/* TODO: Check if this is still correct */
-
 #include <stdint.h>
 #include <amdblocks/acpimmio.h>
 #include <amdblocks/aoac.h>
@@ -12,6 +10,9 @@
 #define FCH_AOAC_UART_FOR_CONSOLE \
 		(CONFIG_UART_FOR_CONSOLE == 0 ? FCH_AOAC_DEV_UART0 \
 		: CONFIG_UART_FOR_CONSOLE == 1 ? FCH_AOAC_DEV_UART1 \
+		: CONFIG_UART_FOR_CONSOLE == 2 ? FCH_AOAC_DEV_UART2 \
+		: CONFIG_UART_FOR_CONSOLE == 3 ? FCH_AOAC_DEV_UART3 \
+		: CONFIG_UART_FOR_CONSOLE == 4 ? FCH_AOAC_DEV_UART4 \
 		: -1)
 #if CONFIG(AMD_SOC_CONSOLE_UART) && FCH_AOAC_UART_FOR_CONSOLE == -1
 # error Unsupported UART_FOR_CONSOLE chosen
diff --git a/src/soc/amd/sabrina/chip.c b/src/soc/amd/sabrina/chip.c
index 9835c6e..c00f91b 100644
--- a/src/soc/amd/sabrina/chip.c
+++ b/src/soc/amd/sabrina/chip.c
@@ -59,6 +59,9 @@
 		break;
 	case APU_UART0_BASE:
 	case APU_UART1_BASE:
+	case APU_UART2_BASE:
+	case APU_UART3_BASE:
+	case APU_UART4_BASE:
 		dev->ops = &sabrina_uart_mmio_ops;
 		break;
 	case APU_EMMC_BASE:
diff --git a/src/soc/amd/sabrina/chipset.cb b/src/soc/amd/sabrina/chipset.cb
index 486f42f..8c6fab9 100644
--- a/src/soc/amd/sabrina/chipset.cb
+++ b/src/soc/amd/sabrina/chipset.cb
@@ -110,5 +110,8 @@
 	device mmio 0xfedc5000 alias i2c_3 off end
 	device mmio 0xfedc9000 alias uart_0 off end
 	device mmio 0xfedca000 alias uart_1 off end
+	device mmio 0xfedce000 alias uart_2 off end
+	device mmio 0xfedcf000 alias uart_3 off end
+	device mmio 0xfedd1000 alias uart_4 off end
 	device mmio 0xfedd5000 alias emmc off end
 end
diff --git a/src/soc/amd/sabrina/include/soc/uart.h b/src/soc/amd/sabrina/include/soc/uart.h
index a28c57b..27e6248 100644
--- a/src/soc/amd/sabrina/include/soc/uart.h
+++ b/src/soc/amd/sabrina/include/soc/uart.h
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 
-/* TODO: Check if this is still correct */
-
 #ifndef AMD_SABRINA_UART_H
 #define AMD_SABRINA_UART_H
 
diff --git a/src/soc/amd/sabrina/uart.c b/src/soc/amd/sabrina/uart.c
index c48c3da..0ffdacf 100644
--- a/src/soc/amd/sabrina/uart.c
+++ b/src/soc/amd/sabrina/uart.c
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 
-/* TODO: Check if this is still correct */
-
 #include <amdblocks/aoac.h>
 #include <amdblocks/gpio.h>
 #include <amdblocks/uart.h>
@@ -27,6 +25,18 @@
 			PAD_NF(GPIO_140, UART1_TXD, PULL_NONE),
 			PAD_NF(GPIO_142, UART1_RXD, PULL_NONE),
 	} },
+	[2] = { APU_UART2_BASE, {
+			PAD_NF(GPIO_138, UART2_TXD, PULL_NONE),
+			PAD_NF(GPIO_136, UART2_RXD, PULL_NONE),
+	} },
+	[3] = { APU_UART3_BASE, {
+			PAD_NF(GPIO_135, UART3_TXD, PULL_NONE),
+			PAD_NF(GPIO_137, UART3_RXD, PULL_NONE),
+	} },
+	[4] = { APU_UART4_BASE, {
+			PAD_NF(GPIO_156, UART4_TXD, PULL_NONE),
+			PAD_NF(GPIO_155, UART4_RXD, PULL_NONE),
+	} },
 };
 
 uintptr_t get_uart_base(unsigned int idx)
@@ -57,6 +67,12 @@
 		return "FUR0";
 	case APU_UART1_BASE:
 		return "FUR1";
+	case APU_UART2_BASE:
+		return "FUR2";
+	case APU_UART3_BASE:
+		return "FUR3";
+	case APU_UART4_BASE:
+		return "FUR4";
 	default:
 		return NULL;
 	}
@@ -74,6 +90,15 @@
 	case APU_UART1_BASE:
 		dev_id = FCH_AOAC_DEV_UART1;
 		break;
+	case APU_UART2_BASE:
+		dev_id = FCH_AOAC_DEV_UART2;
+		break;
+	case APU_UART3_BASE:
+		dev_id = FCH_AOAC_DEV_UART3;
+		break;
+	case APU_UART4_BASE:
+		dev_id = FCH_AOAC_DEV_UART4;
+		break;
 	default:
 		printk(BIOS_ERR, "%s: Unknown device: %s\n", __func__, dev_path(dev));
 		return;