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
|
endif # HAVE_MRC
|
||||||
|
|
||||||
config INTEL_PCH_UART_CONSOLE
|
config SERIALIO_UART_CONSOLE
|
||||||
bool "Use Serial IO UART for console"
|
bool
|
||||||
default n
|
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
|
config CONSOLE_UART_BASE_ADDRESS
|
||||||
hex "Serial IO UART number to use for console"
|
default 0xd6000000 if SERIALIO_UART_CONSOLE
|
||||||
default 0x0
|
|
||||||
depends on INTEL_PCH_UART_CONSOLE
|
|
||||||
|
|
||||||
config TTYS0_BASE
|
|
||||||
hex
|
|
||||||
default 0xd6000000
|
|
||||||
depends on INTEL_PCH_UART_CONSOLE
|
|
||||||
|
|
||||||
config EHCI_BAR
|
config EHCI_BAR
|
||||||
hex
|
hex
|
||||||
|
|
|
@ -30,7 +30,6 @@ ramstage-y += serialio.c
|
||||||
ramstage-y += ../../../../southbridge/intel/lynxpoint/smbus.c
|
ramstage-y += ../../../../southbridge/intel/lynxpoint/smbus.c
|
||||||
ramstage-y += smi.c
|
ramstage-y += smi.c
|
||||||
smm-y += smihandler.c
|
smm-y += smihandler.c
|
||||||
romstage-$(CONFIG_DRIVERS_UART_8250MEM) += uart.c
|
|
||||||
bootblock-y += usb_debug.c
|
bootblock-y += usb_debug.c
|
||||||
romstage-y += usb_debug.c
|
romstage-y += usb_debug.c
|
||||||
ramstage-y += usb_debug.c
|
ramstage-y += usb_debug.c
|
||||||
|
@ -38,4 +37,9 @@ ramstage-y += usb_ehci.c
|
||||||
ramstage-y += usb_xhci.c
|
ramstage-y += usb_xhci.c
|
||||||
smm-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
|
ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/hda_verb.c
|
||||||
|
|
|
@ -105,6 +105,9 @@ static void pch_early_lpc(void)
|
||||||
RCBA32_OR(FD, PCH_DISABLE_ALWAYS);
|
RCBA32_OR(FD, PCH_DISABLE_ALWAYS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Defined in Lynx Point code */
|
||||||
|
void uart_bootblock_init(void);
|
||||||
|
|
||||||
void bootblock_early_southbridge_init(void)
|
void bootblock_early_southbridge_init(void)
|
||||||
{
|
{
|
||||||
map_rcba();
|
map_rcba();
|
||||||
|
@ -112,4 +115,7 @@ void bootblock_early_southbridge_init(void)
|
||||||
enable_port80_on_lpc();
|
enable_port80_on_lpc();
|
||||||
set_spi_speed();
|
set_spi_speed();
|
||||||
pch_early_lpc();
|
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,
|
unsigned long current,
|
||||||
struct acpi_rsdp *rsdp)
|
struct acpi_rsdp *rsdp)
|
||||||
{
|
{
|
||||||
if (CONFIG(INTEL_PCH_UART_CONSOLE))
|
if (CONFIG(SERIALIO_UART_CONSOLE)) {
|
||||||
current = acpi_write_dbg2_pci_uart(rsdp, current,
|
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,
|
PCH_DEV_UART1 : PCH_DEV_UART0,
|
||||||
ACPI_ACCESS_SIZE_BYTE_ACCESS);
|
ACPI_ACCESS_SIZE_DWORD_ACCESS);
|
||||||
|
}
|
||||||
return acpi_write_hpet(device, current, rsdp);
|
return acpi_write_hpet(device, current, rsdp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <soc/serialio.h>
|
#include <soc/serialio.h>
|
||||||
#include <soc/intel/broadwell/pch/chip.h>
|
#include <soc/intel/broadwell/pch/chip.h>
|
||||||
#include <southbridge/intel/lynxpoint/iobp.h>
|
#include <southbridge/intel/lynxpoint/iobp.h>
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
/* Set D3Hot Power State in ACPI mode */
|
/* Set D3Hot Power State in ACPI mode */
|
||||||
static void serialio_enable_d3hot(struct resource *res)
|
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);
|
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)
|
if (CONFIG(SERIALIO_UART_CONSOLE)) {
|
||||||
switch (dev->path.pci.devfn) {
|
switch (dev->path.pci.devfn) {
|
||||||
case PCH_DEVFN_UART0: /* UART0 */
|
case PCH_DEVFN_UART0:
|
||||||
return !!(CONFIG_INTEL_PCH_UART_CONSOLE_NUMBER == 0);
|
return CONFIG_UART_FOR_CONSOLE == 0;
|
||||||
case PCH_DEVFN_UART1: /* UART1 */
|
case PCH_DEVFN_UART1:
|
||||||
return !!(CONFIG_INTEL_PCH_UART_CONSOLE_NUMBER == 1);
|
return CONFIG_UART_FOR_CONSOLE == 1;
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable clock in PCI mode */
|
/* Enable clock in PCI mode */
|
||||||
|
@ -239,8 +240,8 @@ static void serialio_init(struct device *dev)
|
||||||
dev_nvs->bar0[sio_index] = (u32)bar0->base;
|
dev_nvs->bar0[sio_index] = (u32)bar0->base;
|
||||||
dev_nvs->bar1[sio_index] = (u32)bar1->base;
|
dev_nvs->bar1[sio_index] = (u32)bar1->base;
|
||||||
|
|
||||||
|
if (!serialio_uart_is_debug(dev)) {
|
||||||
/* Do not enable UART if it is used as debug port */
|
/* Do not enable UART if it is used as debug port */
|
||||||
if (!serialio_uart_is_debug(dev))
|
|
||||||
dev_nvs->enable[sio_index] = 1;
|
dev_nvs->enable[sio_index] = 1;
|
||||||
|
|
||||||
/* Put device in D3hot state via BAR1 */
|
/* Put device in D3hot state via BAR1 */
|
||||||
|
@ -248,24 +249,24 @@ static void serialio_init(struct device *dev)
|
||||||
serialio_enable_d3hot(bar1); /* all but SDMA */
|
serialio_enable_d3hot(bar1); /* all but SDMA */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void serialio_set_resources(struct device *dev)
|
|
||||||
{
|
|
||||||
pci_dev_set_resources(dev);
|
|
||||||
|
|
||||||
#if CONFIG(INTEL_PCH_UART_CONSOLE)
|
|
||||||
/* Update UART base address if used for debug */
|
|
||||||
if (serialio_uart_is_debug(dev)) {
|
|
||||||
struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0);
|
|
||||||
if (res)
|
|
||||||
uartmem_setbaseaddr(res->base);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
static void serialio_read_resources(struct device *dev)
|
||||||
|
{
|
||||||
|
pci_dev_read_resources(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);
|
||||||
|
res->base = CONFIG_CONSOLE_UART_BASE_ADDRESS;
|
||||||
|
res->size = 0x1000;
|
||||||
|
res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct device_operations device_ops = {
|
static struct device_operations device_ops = {
|
||||||
.read_resources = &pci_dev_read_resources,
|
.read_resources = &serialio_read_resources,
|
||||||
.set_resources = &serialio_set_resources,
|
.set_resources = &pci_dev_set_resources,
|
||||||
.enable_resources = &pci_dev_enable_resources,
|
.enable_resources = &pci_dev_enable_resources,
|
||||||
.init = &serialio_init,
|
.init = &serialio_init,
|
||||||
.ops_pci = &pci_dev_ops_pci,
|
.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