diff options
-rw-r--r-- | src/soc/amd/picasso/Kconfig | 44 | ||||
-rw-r--r-- | src/soc/amd/picasso/acpi/globalnvs.asl | 5 | ||||
-rw-r--r-- | src/soc/amd/picasso/acpi/sb_fch.asl | 41 | ||||
-rw-r--r-- | src/soc/amd/picasso/acpi/sb_pci0_fch.asl | 46 | ||||
-rw-r--r-- | src/soc/amd/picasso/include/soc/iomap.h | 7 | ||||
-rw-r--r-- | src/soc/amd/picasso/include/soc/southbridge.h | 20 | ||||
-rw-r--r-- | src/soc/amd/picasso/southbridge.c | 6 | ||||
-rw-r--r-- | src/soc/amd/picasso/uart.c | 67 |
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; } |