From 0de34dc323f709c138a42950b4182118aa2d118a Mon Sep 17 00:00:00 2001 From: Nicholas Chin Date: Thu, 20 Apr 2023 13:23:07 -0600 Subject: [PATCH] drivers/uart/oxpcie: Fix broken console output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The OxPCIe952 serial cards currently fails after entering postcar, since the state of oxpcie_present is not maintained from previous stage. As a quick work-around test the expected UART register space to see if anyone decodes the address. Change-Id: I5601034be6e413616fb3433c894fb008a3e02138 Signed-off-by: Nicholas Chin Signed-off-by: Kyösti Mälkki Reviewed-on: https://review.coreboot.org/c/coreboot/+/74597 Reviewed-by: Elyes Haouas Reviewed-by: Martin L Roth Tested-by: build bot (Jenkins) --- src/drivers/uart/oxpcie_early.c | 40 ++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/drivers/uart/oxpcie_early.c b/src/drivers/uart/oxpcie_early.c index 2cbc8c7948..206f54d1a5 100644 --- a/src/drivers/uart/oxpcie_early.c +++ b/src/drivers/uart/oxpcie_early.c @@ -5,8 +5,9 @@ #include #include #include +#include "uart8250reg.h" -static unsigned int oxpcie_present; +static int oxpcie_present; static DEVTREE_CONST u32 uart0_base = CONFIG_EARLY_PCI_MMIO_BASE + 0x1000; int pci_early_device_probe(u8 bus, u8 dev, u32 mmio_base) @@ -49,9 +50,42 @@ int pci_early_device_probe(u8 bus, u8 dev, u32 mmio_base) return 0; } -static int oxpcie_uart_active(void) +/* + * Stages that do not call pci_early_device_probe() identify an + * enabled UART with a test read. Since PCI bus enumeration + * has not happened PCI configuration register access is not + * possible here. + */ +static int uart_presence(uintptr_t base) { - return oxpcie_present; + /* LCR has no side-effects on reads. */ + const u8 reg = UART8250_LCR; + u8 val; + + if (CONFIG(DRIVERS_UART_8250MEM_32)) + val = read32p(base + 4 * reg) & 0xff; + else + val = read8p(base + reg); + + if (val == 0xff) + return -1; + + /* Something decoded MMIO read, assume it was the UART. */ + return 1; +} + +static bool oxpcie_uart_active(void) +{ + if (oxpcie_present == 0) + oxpcie_present = uart_presence(uart0_base); + + if (oxpcie_present > 0) + return true; + if (oxpcie_present < 0) + return false; + + /* not reached */ + return false; } uintptr_t uart_platform_base(unsigned int idx)