aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/amd/picasso/Kconfig44
-rw-r--r--src/soc/amd/picasso/acpi/globalnvs.asl5
-rw-r--r--src/soc/amd/picasso/acpi/sb_fch.asl41
-rw-r--r--src/soc/amd/picasso/acpi/sb_pci0_fch.asl46
-rw-r--r--src/soc/amd/picasso/include/soc/iomap.h7
-rw-r--r--src/soc/amd/picasso/include/soc/southbridge.h20
-rw-r--r--src/soc/amd/picasso/southbridge.c6
-rw-r--r--src/soc/amd/picasso/uart.c67
8 files changed, 217 insertions, 19 deletions
diff --git a/src/soc/amd/picasso/Kconfig b/src/soc/amd/picasso/Kconfig
index 6d0a3efff4..5af830cc83 100644
--- a/src/soc/amd/picasso/Kconfig
+++ b/src/soc/amd/picasso/Kconfig
@@ -157,16 +157,46 @@ config PICASSO_UART
select NO_UART_ON_SUPERIO
select UART_OVERRIDE_REFCLK
help
- There are two UART controllers in Picasso.
- The UART registers are memory-mapped. UART
- controller 0 registers range from FEDC_6000h
- to FEDC_6FFFh. UART controller 1 registers
- range from FEDC_8000h to FEDC_8FFFh.
+ There are four memory-mapped UARTs controllers in Picasso at:
+ 0: 0xfedc9000
+ 1: 0xfedca000
+ 2: 0xfedc3000
+ 3: 0xfedcf000
+
+choice PICASSO_UART_CLOCK_SOURCE
+ prompt "UART Frequency"
+ depends on PICASSO_UART
+ default PICASSO_UART_48MZ
+
+config PICASSO_UART_48MZ
+ bool "48 MHz clock"
+ help
+ Select this option for the most compatibility.
+
+config PICASSO_UART_1_8MZ
+ bool "1.8432 MHz clock"
+ help
+ Select this option if an old payload or Linux ttyS0 arguments
+ require it.
+
+endchoice
+
+config PICASSO_UART_LEGACY
+ bool "Decode legacy I/O range"
+ depends on PICASSO_UART
+ help
+ Assign I/O 3F8, 2F8, etc. to a Picasso UART. Only a single UART may
+ decode legacy addresses and this option enables the one used for the
+ console. A UART accessed with I/O does not allow all the features
+ of MMIO. The MMIO decode is still present when this option is used.
config CONSOLE_UART_BASE_ADDRESS
- depends on CONSOLE_SERIAL
+ depends on CONSOLE_SERIAL && PICASSO_UART
hex
- default 0xfedc6000
+ default 0xfedc9000 if UART_FOR_CONSOLE = 0
+ default 0xfedca000 if UART_FOR_CONSOLE = 1
+ default 0xfedc3000 if UART_FOR_CONSOLE = 2
+ default 0xfedcf000 if UART_FOR_CONSOLE = 3
config SMM_TSEG_SIZE
hex
diff --git a/src/soc/amd/picasso/acpi/globalnvs.asl b/src/soc/amd/picasso/acpi/globalnvs.asl
index 12480c7d0f..a373a99e7d 100644
--- a/src/soc/amd/picasso/acpi/globalnvs.asl
+++ b/src/soc/amd/picasso/acpi/globalnvs.asl
@@ -55,7 +55,10 @@ Field (GNVS, ByteAcc, NoLock, Preserve)
, 1,
UT0E, 1, // UART0, 11
UT1E, 1, // UART1, 12
- , 14,
+ , 3,
+ UT2E, 1, // UART2, 16
+ , 9,
+ UT23, 1, // UART3, 26
ESPI, 1, // ESPI, 27
/* ChromeOS stuff (0x100 -> 0xfff, size 0xeff) */
Offset (0x100),
diff --git a/src/soc/amd/picasso/acpi/sb_fch.asl b/src/soc/amd/picasso/acpi/sb_fch.asl
index e7975f8d94..13b9025970 100644
--- a/src/soc/amd/picasso/acpi/sb_fch.asl
+++ b/src/soc/amd/picasso/acpi/sb_fch.asl
@@ -58,7 +58,8 @@ Device (FUR0)
Name (_CRS, ResourceTemplate()
{
IRQ (Edge, ActiveHigh, Exclusive) { 10 }
- Memory32Fixed (ReadWrite, 0xFEDC6000, 0x2000)
+ Memory32Fixed (ReadWrite, APU_UART0_BASE, 0x1000)
+ Memory32Fixed (ReadWrite, APU_DMAC0_BASE, 0x1000)
})
Method (_STA, 0x0, NotSerialized)
{
@@ -71,12 +72,44 @@ Device (FUR1) {
Name (_UID, 0x1)
Name (_CRS, ResourceTemplate()
{
- IRQ (Edge, ActiveHigh, Exclusive) { 11 }
- Memory32Fixed (ReadWrite, 0xFEDC8000, 0x2000)
+ IRQ (Edge, ActiveHigh, Exclusive) { 11 }
+ Memory32Fixed (ReadWrite, APU_UART1_BASE, 0x1000)
+ Memory32Fixed (ReadWrite, APU_DMAC1_BASE, 0x1000)
})
Method (_STA, 0x0, NotSerialized)
{
- Return (0x0F)
+ Return (0x0F)
+ }
+}
+
+Device (FUR2)
+{
+ Name (_HID, "AMD0020")
+ Name (_UID, 0x0)
+ Name (_CRS, ResourceTemplate()
+ {
+ IRQ (Edge, ActiveHigh, Exclusive) { 15 }
+ Memory32Fixed (ReadWrite, APU_UART2_BASE, 0x1000)
+ Memory32Fixed (ReadWrite, APU_DMAC2_BASE, 0x1000)
+ })
+ Method (_STA, 0x0, NotSerialized)
+ {
+ Return (0x0F)
+ }
+}
+
+Device (FUR3) {
+ Name (_HID, "AMD0020")
+ Name (_UID, 0x1)
+ Name (_CRS, ResourceTemplate()
+ {
+ IRQ (Edge, ActiveHigh, Exclusive) { 5 }
+ Memory32Fixed (ReadWrite, APU_UART3_BASE, 0x1000)
+ Memory32Fixed (ReadWrite, APU_DMAC3_BASE, 0x1000)
+ })
+ Method (_STA, 0x0, NotSerialized)
+ {
+ Return (0x0F)
}
}
diff --git a/src/soc/amd/picasso/acpi/sb_pci0_fch.asl b/src/soc/amd/picasso/acpi/sb_pci0_fch.asl
index 5e16fefaa5..bd340dd4bb 100644
--- a/src/soc/amd/picasso/acpi/sb_pci0_fch.asl
+++ b/src/soc/amd/picasso/acpi/sb_pci0_fch.asl
@@ -236,9 +236,23 @@ Field( SMIC, ByteAcc, NoLock, Preserve) {
offset (0x1e59), /* UART1 D3 State */
U1DS, 3,
+ offset (0x1e60), /* UART2 D3 Control */
+ U2TD, 2,
+ , 1,
+ U2PD, 1,
+ offset (0x1e61), /* UART2 D3 State */
+ U2DS, 3,
+
offset (0x1e71), /* SD D3 State */
SDDS, 3,
+ offset (0x1e74), /* UART3 D3 Control */
+ U3TD, 2,
+ , 1,
+ U3PD, 1,
+ offset (0x1e75), /* UART3 D3 State */
+ U3DS, 3,
+
offset (0x1e80), /* Shadow Register Request */
, 15,
RQ15, 1,
@@ -375,6 +389,22 @@ Method(FDDC, 2, Serialized)
Store(U1DS, Local0)
}
}
+ Case(16) {
+ Store(0x00, U2TD)
+ Store(One, U2PD)
+ Store(U2DS, Local0)
+ while(LNotEqual(Local0,0x7)) {
+ Store(U2DS, Local0)
+ }
+ }
+ Case(26) {
+ Store(0x00, U3TD)
+ Store(One, U3PD)
+ Store(U3DS, Local0)
+ while(LNotEqual(Local0,0x7)) {
+ Store(U3DS, Local0)
+ }
+ }
}
} else {
/* put device into D3cold */
@@ -427,6 +457,22 @@ Method(FDDC, 2, Serialized)
}
Store(0x03, U1TD)
}
+ Case(16) {
+ Store(Zero, U2PD)
+ Store(U2DS, Local0)
+ while(LNotEqual(Local0,0x0)) {
+ Store(U2DS, Local0)
+ }
+ Store(0x03, U2TD)
+ }
+ Case(26) {
+ Store(Zero, U3PD)
+ Store(U3DS, Local0)
+ while(LNotEqual(Local0,0x0)) {
+ Store(U3DS, Local0)
+ }
+ Store(0x03, U3TD)
+ }
}
if(LEqual(I1TD, 3)) {
if(LEqual(I2TD, 3)) {
diff --git a/src/soc/amd/picasso/include/soc/iomap.h b/src/soc/amd/picasso/include/soc/iomap.h
index ad0e7c4609..344b8865ed 100644
--- a/src/soc/amd/picasso/include/soc/iomap.h
+++ b/src/soc/amd/picasso/include/soc/iomap.h
@@ -28,6 +28,7 @@
* any documentation but should be considered reserved through FED8_1FFFh.
*/
#include <amdblocks/acpimmio_map.h>
+#define SUPPORTS_ACPIMMIO_SM_PCI_BASE 1 /* 0xfed80000 */
#define SUPPORTS_ACPIMMIO_SMI_BASE 1 /* 0xfed80100 */
#define SUPPORTS_ACPIMMIO_PMIO_BASE 1 /* 0xfed80300 */
#define SUPPORTS_ACPIMMIO_BIOSRAM_BASE 1 /* 0xfed80500 */
@@ -60,8 +61,10 @@
#endif
#define HPET_BASE_ADDRESS 0xfed00000
-#define APU_UART0_BASE 0xfedc6000
-#define APU_UART1_BASE 0xfedc8000
+#define APU_UART0_BASE 0xfedc9000
+#define APU_UART1_BASE 0xfedca000
+#define APU_UART2_BASE 0xfedce000
+#define APU_UART3_BASE 0xfedcf000
#define FLASH_BASE_ADDR ((0xffffffff - CONFIG_ROM_SIZE) + 1)
diff --git a/src/soc/amd/picasso/include/soc/southbridge.h b/src/soc/amd/picasso/include/soc/southbridge.h
index 8bd061b2fc..0fb187dc52 100644
--- a/src/soc/amd/picasso/include/soc/southbridge.h
+++ b/src/soc/amd/picasso/include/soc/southbridge.h
@@ -28,6 +28,14 @@
* - fixed addresses offset from 0xfed80000
*/
+/* SMBus controller registers: 0xfed80000 or D14F0 */
+#define SMB_UART_CONFIG 0xfc
+#define SMB_UART3_1_8M BIT(31) /* defaults are 0 = 48MHz */
+#define SMB_UART2_1_8M BIT(30)
+#define SMB_UART1_1_8M BIT(29)
+#define SMB_UART0_1_8M BIT(28)
+#define SMB_UART_1_8M_SHIFT 28
+
/* Power management registers: 0xfed80300 or index/data at IO 0xcd6/cd7 */
#define PM_DECODE_EN 0x00
#define SMBUS_ASF_IO_EN BIT(4)
@@ -209,6 +217,7 @@
#define FCH_AOAC_DEV_UART1 12
#define FCH_AOAC_DEV_UART2 16
#define FCH_AOAC_DEV_AMBA 17
+#define FCH_AOAC_DEV_UART3 26
#define FCH_AOAC_DEV_ESPI 27
/* Bit definitions for Device D3 Control AOACx0000[40...7E] step 2 */
@@ -230,6 +239,11 @@
#define FCH_AOAC_STAT0 BIT(6)
#define FCH_AOAC_STAT1 BIT(7)
+#define FCH_UART_LEGACY_DECODE 0xfedc0020
+#define FCH_LEGACY_3F8_SH 3
+#define FCH_LEGACY_2F8_SH 1
+#define FCH_LEGACY_3E8_SH 2
+
#define PM1_LIMIT 16
#define GPE0_LIMIT 28
#define TOTAL_BITS(a) (8 * sizeof(a))
@@ -294,7 +308,10 @@ typedef struct aoac_devs {
unsigned int :1;
unsigned int ut0e:1; /* 11: UART0 */
unsigned int ut1e:1; /* 12: UART1 */
- unsigned int :14;
+ unsigned int :3;
+ unsigned int ut2e:1; /* 16: UART2 */
+ unsigned int :9;
+ unsigned int ut3e:1; /* 26: UART3 */
unsigned int espi:1; /* 27: ESPI */
unsigned int :4;
} __packed aoac_devs_t;
@@ -317,6 +334,7 @@ void sb_read_mode(u32 mode);
void sb_set_spi100(u16 norm, u16 fast, u16 alt, u16 tpm);
void fch_pre_init(void);
void fch_early_init(void);
+void set_uart_config(int idx);
/**
* @brief Save the UMA bize
*
diff --git a/src/soc/amd/picasso/southbridge.c b/src/soc/amd/picasso/southbridge.c
index 92067286a9..fe801d4126 100644
--- a/src/soc/amd/picasso/southbridge.c
+++ b/src/soc/amd/picasso/southbridge.c
@@ -40,6 +40,8 @@
#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 \
: -1)
#if FCH_AOAC_UART_FOR_CONSOLE == -1
# error Unsupported UART_FOR_CONSOLE chosen
@@ -282,6 +284,8 @@ void fch_pre_init(void)
sb_enable_legacy_io();
enable_aoac_devices();
sb_reset_i2c_slaves();
+ if (CONFIG(PICASSO_UART))
+ set_uart_config(CONFIG_UART_FOR_CONSOLE);
}
static void print_num_status_bits(int num_bits, uint32_t status,
@@ -463,6 +467,8 @@ static void set_sb_final_nvs(void)
gnvs->aoac.ic4e = is_aoac_device_enabled(FCH_AOAC_DEV_I2C4);
gnvs->aoac.ut0e = is_aoac_device_enabled(FCH_AOAC_DEV_UART0);
gnvs->aoac.ut1e = is_aoac_device_enabled(FCH_AOAC_DEV_UART1);
+ gnvs->aoac.ut2e = is_aoac_device_enabled(FCH_AOAC_DEV_UART2);
+ gnvs->aoac.ut3e = is_aoac_device_enabled(FCH_AOAC_DEV_UART3);
gnvs->aoac.espi = 1;
}
diff --git a/src/soc/amd/picasso/uart.c b/src/soc/amd/picasso/uart.c
index d5d30061bf..445862430a 100644
--- a/src/soc/amd/picasso/uart.c
+++ b/src/soc/amd/picasso/uart.c
@@ -1,7 +1,7 @@
/*
* This file is part of the coreboot project.
*
- * Copyright (C) 2015 Advanced Micro Devices, Inc.
+ * Copyright (C) 2019 Advanced Micro Devices, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -13,18 +13,77 @@
* GNU General Public License for more details.
*/
+#include <arch/mmio.h>
#include <console/uart.h>
+#include <commonlib/helpers.h>
+#include <amdblocks/gpio_banks.h>
+#include <amdblocks/acpimmio.h>
#include <soc/southbridge.h>
+#include <soc/gpio.h>
+
+static const struct _uart_info {
+ uintptr_t base;
+ struct soc_amd_gpio mux[2];
+} uart_info[] = {
+ [0] = { APU_UART0_BASE, {
+ PAD_NF(GPIO_138, UART0_TXD, PULL_NONE),
+ PAD_NF(GPIO_136, UART0_RXD, PULL_NONE),
+ } },
+ [1] = { APU_UART1_BASE, {
+ PAD_NF(GPIO_143, UART1_TXD, PULL_NONE),
+ PAD_NF(GPIO_141, UART1_RXD, PULL_NONE),
+ } },
+ [2] = { APU_UART2_BASE, {
+ PAD_NF(GPIO_137, UART2_TXD, PULL_NONE),
+ PAD_NF(GPIO_135, UART2_RXD, PULL_NONE),
+ } },
+ [3] = { APU_UART3_BASE, {
+ PAD_NF(GPIO_140, UART3_TXD, PULL_NONE),
+ PAD_NF(GPIO_142, UART3_RXD, PULL_NONE),
+ } },
+};
uintptr_t uart_platform_base(int idx)
{
- if (CONFIG_UART_FOR_CONSOLE < 0 || CONFIG_UART_FOR_CONSOLE > 1)
+ if (idx < 0 || idx > ARRAY_SIZE(uart_info))
return 0;
- return (uintptr_t)(APU_UART0_BASE + 0x2000 * (idx & 1));
+ return uart_info[idx].base;
+}
+
+void set_uart_config(int idx)
+{
+ uint32_t uart_ctrl;
+ uint16_t uart_leg;
+
+ if (idx < 0 || idx > ARRAY_SIZE(uart_info))
+ return;
+
+ program_gpios(uart_info[idx].mux, 2);
+
+ if (CONFIG(PICASSO_UART_1_8MZ)) {
+ uart_ctrl = sm_pci_read32(SMB_UART_CONFIG);
+ uart_ctrl |= 1 << (SMB_UART_1_8M_SHIFT + idx);
+ sm_pci_write32(SMB_UART_CONFIG, uart_ctrl);
+ }
+
+ if (CONFIG(PICASSO_UART_LEGACY) && idx != 3) {
+ /* Force 3F8 if idx=0, 2F8 if idx=1, 3E8 if idx=2 */
+
+ /* TODO: make clearer once PPR is updated */
+ uart_leg = (idx << 8) | (idx << 10) | (idx << 12) | (idx << 14);
+ if (idx == 0)
+ uart_leg |= 1 << FCH_LEGACY_3F8_SH;
+ else if (idx == 1)
+ uart_leg |= 1 << FCH_LEGACY_2F8_SH;
+ else if (idx == 2)
+ uart_leg |= 1 << FCH_LEGACY_3E8_SH;
+
+ write16((void *)FCH_UART_LEGACY_DECODE, uart_leg);
+ }
}
unsigned int uart_platform_refclk(void)
{
- return 48000000;
+ return CONFIG(PICASSO_UART_48MZ) ? 48000000 : 115200 * 16;
}