soc/intel/broadwell: Re-do SerialIO UART console support
Use the same code from Lynx Point on Broadwell, and adjust as needed. Also add a config file to ensure the code gets build-tested. Tested on out-of-tree Compal LA-A992P (Haswell ULT), UART 0 works. Change-Id: I527024098738700d5fbaf3e27cf4db331a0322bd Signed-off-by: Angel Pons <th3fanbus@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/37553 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
This commit is contained in:
parent
e42ce6bb49
commit
07baa7a7f0
|
@ -0,0 +1,5 @@
|
|||
# Configuration used to build-test Wildcat Point SerialIO UART console code.
|
||||
CONFIG_VENDOR_GOOGLE=y
|
||||
CONFIG_BOARD_GOOGLE_GUADO=y
|
||||
CONFIG_SERIALIO_UART_CONSOLE=y
|
||||
# CONFIG_DRIVERS_UART_8250IO is not set
|
|
@ -153,20 +153,16 @@ config RO_REGION_ONLY
|
|||
|
||||
endif # HAVE_MRC
|
||||
|
||||
config INTEL_PCH_UART_CONSOLE
|
||||
bool "Use Serial IO UART for console"
|
||||
config SERIALIO_UART_CONSOLE
|
||||
bool
|
||||
default n
|
||||
select DRIVERS_UART_8250MEM
|
||||
select DRIVERS_UART_8250MEM_32
|
||||
help
|
||||
Selected by mainboards where SerialIO UARTs can be used to retrieve
|
||||
coreboot logs. Boards also need to set UART_FOR_CONSOLE accordingly.
|
||||
|
||||
config INTEL_PCH_UART_CONSOLE_NUMBER
|
||||
hex "Serial IO UART number to use for console"
|
||||
default 0x0
|
||||
depends on INTEL_PCH_UART_CONSOLE
|
||||
|
||||
config TTYS0_BASE
|
||||
hex
|
||||
default 0xd6000000
|
||||
depends on INTEL_PCH_UART_CONSOLE
|
||||
config CONSOLE_UART_BASE_ADDRESS
|
||||
default 0xd6000000 if SERIALIO_UART_CONSOLE
|
||||
|
||||
config EHCI_BAR
|
||||
hex
|
||||
|
|
|
@ -30,7 +30,6 @@ ramstage-y += serialio.c
|
|||
ramstage-y += ../../../../southbridge/intel/lynxpoint/smbus.c
|
||||
ramstage-y += smi.c
|
||||
smm-y += smihandler.c
|
||||
romstage-$(CONFIG_DRIVERS_UART_8250MEM) += uart.c
|
||||
bootblock-y += usb_debug.c
|
||||
romstage-y += usb_debug.c
|
||||
ramstage-y += usb_debug.c
|
||||
|
@ -38,4 +37,9 @@ ramstage-y += usb_ehci.c
|
|||
ramstage-y += usb_xhci.c
|
||||
smm-y += usb_xhci.c
|
||||
|
||||
bootblock-$(CONFIG_SERIALIO_UART_CONSOLE) += ../../../../southbridge/intel/lynxpoint/iobp.c
|
||||
bootblock-$(CONFIG_SERIALIO_UART_CONSOLE) += ../../../../southbridge/intel/lynxpoint/uart_init.c
|
||||
all-$(CONFIG_SERIALIO_UART_CONSOLE) += ../../../../southbridge/intel/lynxpoint/uart.c
|
||||
smm-$(CONFIG_SERIALIO_UART_CONSOLE) += ../../../../southbridge/intel/lynxpoint/uart.c
|
||||
|
||||
ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/hda_verb.c
|
||||
|
|
|
@ -105,6 +105,9 @@ static void pch_early_lpc(void)
|
|||
RCBA32_OR(FD, PCH_DISABLE_ALWAYS);
|
||||
}
|
||||
|
||||
/* Defined in Lynx Point code */
|
||||
void uart_bootblock_init(void);
|
||||
|
||||
void bootblock_early_southbridge_init(void)
|
||||
{
|
||||
map_rcba();
|
||||
|
@ -112,4 +115,7 @@ void bootblock_early_southbridge_init(void)
|
|||
enable_port80_on_lpc();
|
||||
set_spi_speed();
|
||||
pch_early_lpc();
|
||||
|
||||
if (CONFIG(SERIALIO_UART_CONSOLE))
|
||||
uart_bootblock_init();
|
||||
}
|
||||
|
|
|
@ -604,11 +604,12 @@ static unsigned long broadwell_write_acpi_tables(const struct device *device,
|
|||
unsigned long current,
|
||||
struct acpi_rsdp *rsdp)
|
||||
{
|
||||
if (CONFIG(INTEL_PCH_UART_CONSOLE))
|
||||
if (CONFIG(SERIALIO_UART_CONSOLE)) {
|
||||
current = acpi_write_dbg2_pci_uart(rsdp, current,
|
||||
(CONFIG_INTEL_PCH_UART_CONSOLE_NUMBER == 1) ?
|
||||
(CONFIG_UART_FOR_CONSOLE == 1) ?
|
||||
PCH_DEV_UART1 : PCH_DEV_UART0,
|
||||
ACPI_ACCESS_SIZE_BYTE_ACCESS);
|
||||
ACPI_ACCESS_SIZE_DWORD_ACCESS);
|
||||
}
|
||||
return acpi_write_hpet(device, current, rsdp);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <soc/serialio.h>
|
||||
#include <soc/intel/broadwell/pch/chip.h>
|
||||
#include <southbridge/intel/lynxpoint/iobp.h>
|
||||
#include <types.h>
|
||||
|
||||
/* Set D3Hot Power State in ACPI mode */
|
||||
static void serialio_enable_d3hot(struct resource *res)
|
||||
|
@ -24,17 +25,17 @@ static void serialio_enable_d3hot(struct resource *res)
|
|||
write32(res2mmio(res, PCH_PCS, 0), reg32);
|
||||
}
|
||||
|
||||
static int serialio_uart_is_debug(struct device *dev)
|
||||
static bool serialio_uart_is_debug(struct device *dev)
|
||||
{
|
||||
#if CONFIG(INTEL_PCH_UART_CONSOLE)
|
||||
switch (dev->path.pci.devfn) {
|
||||
case PCH_DEVFN_UART0: /* UART0 */
|
||||
return !!(CONFIG_INTEL_PCH_UART_CONSOLE_NUMBER == 0);
|
||||
case PCH_DEVFN_UART1: /* UART1 */
|
||||
return !!(CONFIG_INTEL_PCH_UART_CONSOLE_NUMBER == 1);
|
||||
if (CONFIG(SERIALIO_UART_CONSOLE)) {
|
||||
switch (dev->path.pci.devfn) {
|
||||
case PCH_DEVFN_UART0:
|
||||
return CONFIG_UART_FOR_CONSOLE == 0;
|
||||
case PCH_DEVFN_UART1:
|
||||
return CONFIG_UART_FOR_CONSOLE == 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Enable clock in PCI mode */
|
||||
|
@ -239,33 +240,33 @@ static void serialio_init(struct device *dev)
|
|||
dev_nvs->bar0[sio_index] = (u32)bar0->base;
|
||||
dev_nvs->bar1[sio_index] = (u32)bar1->base;
|
||||
|
||||
/* Do not enable UART if it is used as debug port */
|
||||
if (!serialio_uart_is_debug(dev))
|
||||
if (!serialio_uart_is_debug(dev)) {
|
||||
/* Do not enable UART if it is used as debug port */
|
||||
dev_nvs->enable[sio_index] = 1;
|
||||
|
||||
/* Put device in D3hot state via BAR1 */
|
||||
if (dev->path.pci.devfn != PCH_DEVFN_SDMA)
|
||||
serialio_enable_d3hot(bar1); /* all but SDMA */
|
||||
/* Put device in D3hot state via BAR1 */
|
||||
if (dev->path.pci.devfn != PCH_DEVFN_SDMA)
|
||||
serialio_enable_d3hot(bar1); /* all but SDMA */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void serialio_set_resources(struct device *dev)
|
||||
static void serialio_read_resources(struct device *dev)
|
||||
{
|
||||
pci_dev_set_resources(dev);
|
||||
pci_dev_read_resources(dev);
|
||||
|
||||
#if CONFIG(INTEL_PCH_UART_CONSOLE)
|
||||
/* Update UART base address if used for debug */
|
||||
if (serialio_uart_is_debug(dev)) {
|
||||
/* Set the configured UART base address for the debug port */
|
||||
if (CONFIG(SERIALIO_UART_CONSOLE) && serialio_uart_is_debug(dev)) {
|
||||
struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0);
|
||||
if (res)
|
||||
uartmem_setbaseaddr(res->base);
|
||||
res->base = CONFIG_CONSOLE_UART_BASE_ADDRESS;
|
||||
res->size = 0x1000;
|
||||
res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct device_operations device_ops = {
|
||||
.read_resources = &pci_dev_read_resources,
|
||||
.set_resources = &serialio_set_resources,
|
||||
.read_resources = &serialio_read_resources,
|
||||
.set_resources = &pci_dev_set_resources,
|
||||
.enable_resources = &pci_dev_enable_resources,
|
||||
.init = &serialio_init,
|
||||
.ops_pci = &pci_dev_ops_pci,
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <device/pci_def.h>
|
||||
#include <reg_script.h>
|
||||
#include <stdint.h>
|
||||
#include <uart8250.h>
|
||||
#include <soc/iobp.h>
|
||||
#include <soc/serialio.h>
|
||||
|
||||
const struct reg_script uart_init[] = {
|
||||
/* Set MMIO BAR */
|
||||
REG_PCI_WRITE32(PCI_BASE_ADDRESS_0, CONFIG_TTYS0_BASE),
|
||||
/* Enable Memory access and Bus Master */
|
||||
REG_PCI_OR32(PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER),
|
||||
/* Initialize LTR */
|
||||
REG_MMIO_RMW32(CONFIG_TTYS0_BASE + SIO_REG_PPR_GEN,
|
||||
~SIO_REG_PPR_GEN_LTR_MODE_MASK, 0),
|
||||
REG_MMIO_RMW32(CONFIG_TTYS0_BASE + SIO_REG_PPR_RST,
|
||||
~(SIO_REG_PPR_RST_ASSERT), 0),
|
||||
/* Take UART out of reset */
|
||||
REG_MMIO_OR32(CONFIG_TTYS0_BASE + SIO_REG_PPR_RST,
|
||||
SIO_REG_PPR_RST_ASSERT),
|
||||
/* Set M and N divisor inputs and enable clock */
|
||||
REG_MMIO_WRITE32(CONFIG_TTYS0_BASE + SIO_REG_PPR_CLOCK,
|
||||
SIO_REG_PPR_CLOCK_EN | SIO_REG_PPR_CLOCK_UPDATE |
|
||||
(SIO_REG_PPR_CLOCK_N_DIV << 16) |
|
||||
(SIO_REG_PPR_CLOCK_M_DIV << 1)),
|
||||
REG_SCRIPT_END
|
||||
};
|
||||
|
||||
void pch_uart_init(void)
|
||||
{
|
||||
/* Program IOBP CB000154h[12,9:8,4:0] = 1001100011111b */
|
||||
u32 gpiodf = 0x131f;
|
||||
#if defined(__SIMPLE_DEVICE__)
|
||||
pci_devfn_t dev;
|
||||
#else
|
||||
struct device *dev;
|
||||
#endif
|
||||
|
||||
/* Put UART in byte access mode for 16550 compatibility */
|
||||
switch (CONFIG_INTEL_PCH_UART_CONSOLE_NUMBER) {
|
||||
case 0:
|
||||
dev = PCH_DEV_UART0;
|
||||
gpiodf |= SIO_IOBP_GPIODF_UART0_BYTE_ACCESS;
|
||||
break;
|
||||
case 1:
|
||||
dev = PCH_DEV_UART1;
|
||||
gpiodf |= SIO_IOBP_GPIODF_UART1_BYTE_ACCESS;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
/* Program IOBP GPIODF */
|
||||
pch_iobp_update(SIO_IOBP_GPIODF, ~gpiodf, gpiodf);
|
||||
|
||||
/* Program IOBP CB000180h[5:0] = 111111b (undefined register) */
|
||||
pch_iobp_update(0xcb000180, ~0x0000003f, 0x0000003f);
|
||||
|
||||
/* Initialize chipset uart interface */
|
||||
reg_script_run_on_dev(dev, uart_init);
|
||||
|
||||
/*
|
||||
* Perform standard UART initialization
|
||||
* Divisor 1 is 115200 BAUD
|
||||
*/
|
||||
uart8250_mem_init(CONFIG_TTYS0_BASE, 1);
|
||||
}
|
Loading…
Reference in New Issue