diff options
author | Subrata Banik <subrata.banik@intel.com> | 2018-05-24 12:21:06 +0530 |
---|---|---|
committer | Patrick Georgi <pgeorgi@google.com> | 2018-08-20 15:51:48 +0000 |
commit | afa07f7ae48d9e9d79aef712933777a56551f5be (patch) | |
tree | f7f0342eb23f33d3c2834617e0f8e69a58b4ff52 /src/soc/intel/common/block/uart/uart.c | |
parent | 55a8d8a772322e5ceb71c28785b1815970c468c5 (diff) | |
download | coreboot-afa07f7ae48d9e9d79aef712933777a56551f5be.tar.xz |
soc/intel/common/block: Move common uart function to block/uart
This patch moves uart functions which are common across multiple soc to
block/uart. This will remove redundant code copy from soc
{skylake/apollolake/cannonlake}.
BUG=b:78109109
BRANCH=none
TEST=Build and boot on KBL/APL/CNL platform.
Change-Id: I109d0e5c942e499cb763bde47cb7d53dfbf5cef6
Signed-off-by: Maulik V Vaghela <maulik.v.vaghela@intel.com>
Signed-off-by: Subrata Banik <subrata.banik@intel.com>
Reviewed-on: https://review.coreboot.org/26164
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
Diffstat (limited to 'src/soc/intel/common/block/uart/uart.c')
-rw-r--r-- | src/soc/intel/common/block/uart/uart.c | 136 |
1 files changed, 113 insertions, 23 deletions
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 */ |