diff options
author | Nicholas Chin <nic.c3.14@gmail.com> | 2023-04-20 13:23:07 -0600 |
---|---|---|
committer | Martin L Roth <gaumless@gmail.com> | 2023-07-14 15:28:39 +0000 |
commit | 0de34dc323f709c138a42950b4182118aa2d118a (patch) | |
tree | 31f21527a4652f20945b20e7f0806bc40ca59d4a /src/drivers/uart/oxpcie_early.c | |
parent | ca75c8f8c185415a7b9f29734db827f779cc84f4 (diff) |
drivers/uart/oxpcie: Fix broken console output
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 <nic.c3.14@gmail.com>
Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/74597
Reviewed-by: Elyes Haouas <ehaouas@noos.fr>
Reviewed-by: Martin L Roth <gaumless@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/drivers/uart/oxpcie_early.c')
-rw-r--r-- | src/drivers/uart/oxpcie_early.c | 40 |
1 files 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 <device/pci_ops.h> #include <console/uart.h> #include <device/pci.h> +#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) |