summaryrefslogtreecommitdiff
path: root/src/soc/intel/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/common')
-rw-r--r--src/soc/intel/common/block/acpi/acpi.c2
-rw-r--r--src/soc/intel/common/block/include/intelblocks/uart.h56
-rw-r--r--src/soc/intel/common/block/smm/smihandler.c2
-rw-r--r--src/soc/intel/common/block/uart/Makefile.inc3
-rw-r--r--src/soc/intel/common/block/uart/uart.c136
5 files changed, 162 insertions, 37 deletions
diff --git a/src/soc/intel/common/block/acpi/acpi.c b/src/soc/intel/common/block/acpi/acpi.c
index 01a4928b14..dd42f76d33 100644
--- a/src/soc/intel/common/block/acpi/acpi.c
+++ b/src/soc/intel/common/block/acpi/acpi.c
@@ -169,7 +169,7 @@ unsigned long southbridge_write_acpi_tables(struct device *device,
struct acpi_rsdp *rsdp)
{
current = acpi_write_dbg2_pci_uart(rsdp, current,
- pch_uart_get_debug_controller(),
+ uart_get_device(),
ACPI_ACCESS_SIZE_DWORD_ACCESS);
return acpi_write_hpet(device, current, rsdp);
}
diff --git a/src/soc/intel/common/block/include/intelblocks/uart.h b/src/soc/intel/common/block/include/intelblocks/uart.h
index 78feb3e246..545e158b61 100644
--- a/src/soc/intel/common/block/include/intelblocks/uart.h
+++ b/src/soc/intel/common/block/include/intelblocks/uart.h
@@ -1,7 +1,7 @@
/*
* This file is part of the coreboot project.
*
- * Copyright (C) 2017 Intel Corporation.
+ * Copyright (C) 2017-2018 Intel Corporation.
*
* 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
@@ -17,14 +17,31 @@
#define SOC_INTEL_COMMON_BLOCK_UART_H
#include <arch/io.h>
+#include <console/uart.h>
#include <device/device.h>
+#include <intelblocks/gpio.h>
#include <stdint.h>
+#define MAX_GPIO_PAD_PER_UART 2
+
+struct uart_gpio_pad_config {
+ int console_index;
+ struct pad_config gpios[MAX_GPIO_PAD_PER_UART];
+};
+
+/*
+ * While using this common UART block for any SOC following is expected from soc
+ * 1. SOC will define proper UART_BASE which is base address for UART console.
+ * 2. SOC will return correct device pointer based on console index
+ * 3. SOC will provide appropriate GPIO pad configuration for UART console
+ * 4. SOC will allow common code to set UART into legacy mode if supported.
+ */
+
/*
* Common routine to initialize UART controller PCI config space, take it out of
* reset and configure M/N dividers.
*/
-void uart_common_init(device_t dev, uintptr_t baseaddr);
+void uart_common_init(struct device *dev, uintptr_t baseaddr);
/*
* Check if UART debug controller is initialized
@@ -33,7 +50,7 @@ void uart_common_init(device_t dev, uintptr_t baseaddr);
* out of reset
* false = otherwise
*/
-bool uart_debug_controller_is_initialized(void);
+bool uart_is_controller_initialized(void);
/*
* Check if dev corresponds to UART debug port controller.
@@ -44,26 +61,41 @@ bool uart_debug_controller_is_initialized(void);
*/
bool uart_is_debug_controller(struct device *dev);
-/**************************** SoC callbacks ***********************************/
-
-void pch_uart_read_resources(struct device *dev);
+/*
+ * BootBlock pre initialization of UART console
+ */
+void uart_bootblock_init(void);
/*
- * Check if UART debug port controller needs to be initialized on resume.
+ * Get UART debug controller device structure
*
* Returns:
- * true = when SoC wants common code to do the UART debug port initialization
- * false = otherwise
+ * Pointer to device structure = If device has a UART debug controller.
+ * NULL = otherwise
*/
-bool pch_uart_init_debug_controller_on_resume(void);
+struct device *uart_get_device(void);
+
+/**************************** SoC callbacks ***********************************/
/*
- * Get UART debug controller device structure
+ * SoC should implement soc_uart_console_to_device() function to
+ * get UART debug controller device structure based on console number
+ * Caller needs to check proper UART console index supported by SoC.
+ * If wrong UART console index is passed to function, it'll return NULL.
+ *
+ * Input:
+ * UART console index selected in config
*
* Returns:
* Pointer to device structure = If device has a UART debug controller.
* NULL = otherwise
*/
-device_t pch_uart_get_debug_controller(void);
+struct device *soc_uart_console_to_device(int uart_console);
+
+/*
+ * Set UART to legacy mode
+ * Put UART in byte access mode for 16550 compatibility
+ */
+void soc_uart_set_legacy_mode(void);
#endif /* SOC_INTEL_COMMON_BLOCK_UART_H */
diff --git a/src/soc/intel/common/block/smm/smihandler.c b/src/soc/intel/common/block/smm/smihandler.c
index b49f2a3f3b..c6f9692d81 100644
--- a/src/soc/intel/common/block/smm/smihandler.c
+++ b/src/soc/intel/common/block/smm/smihandler.c
@@ -208,7 +208,7 @@ void smihandler_southbridge_sleep(
case ACPI_S3:
printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n");
- gnvs->uior = uart_debug_controller_is_initialized();
+ gnvs->uior = uart_is_controller_initialized();
/* Invalidate the cache before going to S3 */
wbinvd();
diff --git a/src/soc/intel/common/block/uart/Makefile.inc b/src/soc/intel/common/block/uart/Makefile.inc
index 348b153907..d7a770258f 100644
--- a/src/soc/intel/common/block/uart/Makefile.inc
+++ b/src/soc/intel/common/block/uart/Makefile.inc
@@ -1,3 +1,6 @@
bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_UART) += uart.c
+romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_UART) += uart.c
ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_UART) += uart.c
smm-$(CONFIG_SOC_INTEL_COMMON_BLOCK_UART) += uart.c
+postcar-$(CONFIG_SOC_INTEL_COMMON_BLOCK_UART) += uart.c
+verstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_UART) += uart.c
diff --git a/src/soc/intel/common/block/uart/uart.c b/src/soc/intel/common/block/uart/uart.c
index b84a7ec534..12b99e737e 100644
--- a/src/soc/intel/common/block/uart/uart.c
+++ b/src/soc/intel/common/block/uart/uart.c
@@ -1,7 +1,7 @@
/*
* This file is part of the coreboot project.
*
- * Copyright (C) 2017 Intel Corporation.
+ * Copyright (C) 2017-2018 Intel Corporation.
*
* 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
@@ -14,7 +14,10 @@
*/
#include <arch/acpi.h>
+#include <assert.h>
#include <compiler.h>
+#include <cbmem.h>
+#include <console/uart.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_def.h>
@@ -22,8 +25,16 @@
#include <device/pci_ops.h>
#include <intelblocks/lpss.h>
#include <intelblocks/uart.h>
+#include <soc/pci_devs.h>
+#include <soc/iomap.h>
+#include <soc/nvs.h>
+#include <string.h>
#define UART_PCI_ENABLE (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER)
+#define UART_CONSOLE_INVALID_INDEX 0xFF
+
+extern const struct uart_gpio_pad_config uart_gpio_pads[];
+extern const int uart_max_index;
static void uart_lpss_init(uintptr_t baseaddr)
{
@@ -35,8 +46,37 @@ static void uart_lpss_init(uintptr_t baseaddr)
CONFIG_SOC_INTEL_COMMON_LPSS_UART_CLK_N_VAL);
}
-void uart_common_init(device_t dev, uintptr_t baseaddr)
+#if IS_ENABLED(CONFIG_DRIVERS_UART_8250MEM)
+uintptr_t uart_platform_base(int idx)
+{
+ /* return Base address for UART console index */
+ return UART_BASE_0_ADDR(idx);
+}
+#endif
+
+static int uart_get_valid_index(void)
+{
+ int index;
+
+ for (index = 0; index < uart_max_index; index++) {
+ if (uart_gpio_pads[index].console_index ==
+ CONFIG_UART_FOR_CONSOLE)
+ return index;
+ }
+ /* For valid index, code should not reach here */
+ return UART_CONSOLE_INVALID_INDEX;
+}
+
+void uart_common_init(struct device *device, uintptr_t baseaddr)
{
+#if defined(__SIMPLE_DEVICE__)
+ pci_devfn_t dev = (pci_devfn_t)(uintptr_t)device;
+#else
+ struct device *dev = device;
+#endif
+ if (!dev)
+ return;
+
/* Set UART base address */
pci_write_config32(dev, PCI_BASE_ADDRESS_0, baseaddr);
@@ -46,27 +86,34 @@ void uart_common_init(device_t dev, uintptr_t baseaddr)
uart_lpss_init(baseaddr);
}
-__weak device_t pch_uart_get_debug_controller(void)
+struct device *uart_get_device(void)
{
/*
- * device_t can either be a pointer to struct device (e.g. ramstage) or
- * a simple integer (e.g. SMM) depending upon whether __SIMPLE_DEVICE__
- * is defined for the stage. Thus, the return requires additional
- * casting to uintptr_t.
+ * This function will get called even if UART_DEBUG config options is
+ * not selected.
+ * By default returning NULL in case CONFIG_UART_DEBUG option is not
+ * selected to avoid compilation errors.
*/
- return (device_t)(uintptr_t)NULL;
+ if (!IS_ENABLED(CONFIG_UART_DEBUG))
+ return NULL;
+
+ int console_index = uart_get_valid_index();
+
+ if (console_index != UART_CONSOLE_INVALID_INDEX)
+ return soc_uart_console_to_device(CONFIG_UART_FOR_CONSOLE);
+ else
+ return NULL;
}
-bool uart_debug_controller_is_initialized(void)
+bool uart_is_controller_initialized(void)
{
+ uintptr_t base;
+
#if defined(__SIMPLE_DEVICE__)
- pci_devfn_t dev;
+ pci_devfn_t dev = (pci_devfn_t)(uintptr_t)uart_get_device();
#else
- struct device *dev;
+ struct device *dev = uart_get_device();
#endif
- uintptr_t base;
-
- dev = pch_uart_get_debug_controller();
if (!dev)
return false;
@@ -81,22 +128,66 @@ bool uart_debug_controller_is_initialized(void)
return !lpss_is_controller_in_reset(base);
}
+static void uart_configure_gpio_pads(void)
+{
+ int index = uart_get_valid_index();
+
+ if (index != UART_CONSOLE_INVALID_INDEX)
+ gpio_configure_pads(uart_gpio_pads[index].gpios,
+ MAX_GPIO_PAD_PER_UART);
+}
+
+void uart_bootblock_init(void)
+{
+ /* Program UART BAR0, command, reset and clock register */
+ uart_common_init(uart_get_device(),
+ UART_BASE(CONFIG_UART_FOR_CONSOLE));
+
+ if (!IS_ENABLED(CONFIG_DRIVERS_UART_8250MEM_32))
+ /* Put UART in byte access mode for 16550 compatibility */
+ soc_uart_set_legacy_mode();
+
+ /* Configure the 2 pads per UART. */
+ uart_configure_gpio_pads();
+}
+
#if ENV_RAMSTAGE
-__weak void pch_uart_read_resources(struct device *dev)
+static void uart_read_resources(struct device *dev)
{
pci_dev_read_resources(dev);
+
+ /* Set the configured UART base address for the debug port */
+ if (IS_ENABLED(CONFIG_UART_DEBUG) && uart_is_debug_controller(dev)) {
+ struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0);
+ /* Need to set the base and size for the resource allocator. */
+ res->base = UART_BASE(CONFIG_UART_FOR_CONSOLE);
+ res->size = UART_BASE_SIZE;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED |
+ IORESOURCE_FIXED;
+ }
}
-__weak bool pch_uart_init_debug_controller_on_resume(void)
+/*
+ * Check if UART debug port controller needs to be initialized on resume.
+ *
+ * Returns:
+ * true = when SoC wants debug port initialization on resume
+ * false = otherwise
+ */
+static bool pch_uart_init_debug_controller_on_resume(void)
{
- /* By default, do not initialize controller. */
+ global_nvs_t *gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
+
+ if (gnvs)
+ return !!gnvs->uior;
+
return false;
}
bool uart_is_debug_controller(struct device *dev)
{
- return dev == pch_uart_get_debug_controller();
+ return dev == uart_get_device();
}
/*
@@ -126,8 +217,7 @@ static bool uart_controller_needs_init(struct device *dev)
return false;
/*
- * Call SoC specific routine to confirm it wants to initialize
- * controller.
+ * check if SOC wants to initialize UART on resume
*/
return pch_uart_init_debug_controller_on_resume();
}
@@ -146,7 +236,7 @@ static void uart_common_enable_resources(struct device *dev)
}
static struct device_operations device_ops = {
- .read_resources = &pch_uart_read_resources,
+ .read_resources = &uart_read_resources,
.set_resources = &pci_dev_set_resources,
.enable_resources = &uart_common_enable_resources,
.ops_pci = &pci_dev_ops_pci,
@@ -177,8 +267,8 @@ static const unsigned short pci_device_ids[] = {
};
static const struct pci_driver pch_uart __pci_driver = {
- .ops = &device_ops,
- .vendor = PCI_VENDOR_ID_INTEL,
+ .ops = &device_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
.devices = pci_device_ids,
};
#endif /* ENV_RAMSTAGE */