From afa07f7ae48d9e9d79aef712933777a56551f5be Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Thu, 24 May 2018 12:21:06 +0530 Subject: 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 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/26164 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/soc/intel/common/block/uart/Makefile.inc | 3 + src/soc/intel/common/block/uart/uart.c | 136 ++++++++++++++++++++++----- 2 files changed, 116 insertions(+), 23 deletions(-) (limited to 'src/soc/intel/common/block/uart') 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 +#include #include +#include +#include #include #include #include @@ -22,8 +25,16 @@ #include #include #include +#include +#include +#include +#include #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 */ -- cgit v1.2.3