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 | |
parent | 55a8d8a772322e5ceb71c28785b1815970c468c5 (diff) |
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')
23 files changed, 332 insertions, 324 deletions
diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig index 4577e76a72..3e84a50cc6 100644 --- a/src/soc/intel/apollolake/Kconfig +++ b/src/soc/intel/apollolake/Kconfig @@ -170,12 +170,7 @@ config DRIVERS_I2C_DESIGNWARE_CLOCK_MHZ int default 133 -config CONSOLE_UART_BASE_ADDRESS - depends on CONSOLE_SERIAL - hex - default 0xde000000 - -config SOC_UART_DEBUG +config UART_DEBUG bool "Enable SoC UART debug port selected by UART_FOR_CONSOLE." default n select CONSOLE_SERIAL diff --git a/src/soc/intel/apollolake/Makefile.inc b/src/soc/intel/apollolake/Makefile.inc index 8a37ae41e6..08a5037683 100644 --- a/src/soc/intel/apollolake/Makefile.inc +++ b/src/soc/intel/apollolake/Makefile.inc @@ -17,7 +17,7 @@ bootblock-y += lpc.c bootblock-y += mmap_boot.c bootblock-y += pmutil.c bootblock-y += spi.c -bootblock-$(CONFIG_SOC_UART_DEBUG) += uart.c +bootblock-$(CONFIG_UART_DEBUG) += uart.c bootblock-$(CONFIG_FSP_CAR) += bootblock/cache_as_ram_fsp.S romstage-y += car.c @@ -25,7 +25,7 @@ romstage-$(CONFIG_PLATFORM_USES_FSP2_0) += romstage.c romstage-y += gspi.c romstage-y += heci.c romstage-y += i2c.c -romstage-$(CONFIG_SOC_UART_DEBUG) += uart.c +romstage-$(CONFIG_UART_DEBUG) += uart.c romstage-y += memmap.c romstage-y += meminit.c ifeq ($(CONFIG_SOC_INTEL_GLK),y) @@ -42,7 +42,7 @@ smm-y += mmap_boot.c smm-y += pmutil.c smm-y += smihandler.c smm-y += spi.c -smm-$(CONFIG_SOC_UART_DEBUG) += uart.c +smm-$(CONFIG_UART_DEBUG) += uart.c smm-y += elog.c ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi.c @@ -57,7 +57,7 @@ ramstage-y += i2c.c ramstage-y += lpc.c ramstage-y += memmap.c ramstage-y += mmap_boot.c -ramstage-$(CONFIG_SOC_UART_DEBUG) += uart.c +ramstage-$(CONFIG_UART_DEBUG) += uart.c ramstage-y += nhlt.c ramstage-y += spi.c ramstage-y += systemagent.c @@ -72,7 +72,7 @@ postcar-y += memmap.c postcar-y += mmap_boot.c postcar-y += spi.c postcar-y += i2c.c -postcar-$(CONFIG_SOC_UART_DEBUG) += uart.c +postcar-$(CONFIG_UART_DEBUG) += uart.c postcar-$(CONFIG_FSP_CAR) += exit_car_fsp.S @@ -82,7 +82,7 @@ verstage-y += gspi.c verstage-y += heci.c verstage-y += memmap.c verstage-y += mmap_boot.c -verstage-$(CONFIG_SOC_UART_DEBUG) += uart.c +verstage-$(CONFIG_UART_DEBUG) += uart.c verstage-y += pmutil.c verstage-y += reset.c verstage-y += spi.c diff --git a/src/soc/intel/apollolake/bootblock/bootblock.c b/src/soc/intel/apollolake/bootblock/bootblock.c index f9c62282ff..bc5c1709fc 100644 --- a/src/soc/intel/apollolake/bootblock/bootblock.c +++ b/src/soc/intel/apollolake/bootblock/bootblock.c @@ -25,13 +25,13 @@ #include <intelblocks/rtc.h> #include <intelblocks/systemagent.h> #include <intelblocks/pmclib.h> +#include <intelblocks/uart.h> #include <soc/iomap.h> #include <soc/cpu.h> #include <soc/gpio.h> #include <soc/systemagent.h> #include <soc/pci_devs.h> #include <soc/pm.h> -#include <soc/uart.h> #include <spi-generic.h> #include <timestamp.h> @@ -95,8 +95,8 @@ void bootblock_soc_early_init(void) pmc_global_reset_enable(0); /* Prepare UART for serial console. */ - if (IS_ENABLED(CONFIG_SOC_UART_DEBUG)) - pch_uart_init(); + if (IS_ENABLED(CONFIG_UART_DEBUG)) + uart_bootblock_init(); if (IS_ENABLED(CONFIG_TPM_ON_FAST_SPI)) tpm_enable(); diff --git a/src/soc/intel/apollolake/include/soc/iomap.h b/src/soc/intel/apollolake/include/soc/iomap.h index 479882f47c..eea1e6199b 100644 --- a/src/soc/intel/apollolake/include/soc/iomap.h +++ b/src/soc/intel/apollolake/include/soc/iomap.h @@ -54,4 +54,12 @@ #define EARLY_I2C_BASE_ADDRESS 0xfe020000 #define EARLY_I2C_BASE(x) (EARLY_I2C_BASE_ADDRESS + (0x1000 * (x))) +#define UART_BASE_SIZE 0x1000 + +#define UART_BASE_0_ADDRESS 0xddffc000 +/* UART BARs are 4KB in size */ +#define UART_BASE_0_ADDR(x) (UART_BASE_0_ADDRESS + (2 * \ + UART_BASE_SIZE * (x))) +#define UART_BASE(x) UART_BASE_0_ADDR(x) + #endif /* _SOC_APOLLOLAKE_IOMAP_H_ */ diff --git a/src/soc/intel/apollolake/include/soc/uart.h b/src/soc/intel/apollolake/include/soc/uart.h deleted file mode 100644 index bf8b9d74e3..0000000000 --- a/src/soc/intel/apollolake/include/soc/uart.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2015 Intel Corp. - * (Written by Alexandru Gagniuc <alexandrux.gagniuc@intel.com> for Intel Corp.) - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _SOC_APOLLOLAKE_UART_H_ -#define _SOC_APOLLOLAKE_UART_H_ - -/* Initialize the console UART including the pads for the configured UART. */ -void pch_uart_init(void); - -#endif /* _SOC_APOLLOLAKE_UART_H_ */ diff --git a/src/soc/intel/apollolake/romstage.c b/src/soc/intel/apollolake/romstage.c index d2353f1743..416877103c 100644 --- a/src/soc/intel/apollolake/romstage.c +++ b/src/soc/intel/apollolake/romstage.c @@ -47,7 +47,6 @@ #include <soc/pci_devs.h> #include <soc/pm.h> #include <soc/romstage.h> -#include <soc/uart.h> #include <spi_flash.h> #include <string.h> #include <timestamp.h> @@ -252,7 +251,7 @@ asmlinkage void car_stage_entry(void) static void fill_console_params(FSPM_UPD *mupd) { if (IS_ENABLED(CONFIG_CONSOLE_SERIAL)) { - if (IS_ENABLED(CONFIG_SOC_UART_DEBUG)) { + if (IS_ENABLED(CONFIG_UART_DEBUG)) { mupd->FspmConfig.SerialDebugPortDevice = CONFIG_UART_FOR_CONSOLE; /* use MMIO port type */ diff --git a/src/soc/intel/apollolake/uart.c b/src/soc/intel/apollolake/uart.c index a59b567e56..875bc49575 100644 --- a/src/soc/intel/apollolake/uart.c +++ b/src/soc/intel/apollolake/uart.c @@ -1,7 +1,7 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2015-2017 Intel Corp. + * Copyright (C) 2015-2018 Intel Corp. * * 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 @@ -20,96 +20,71 @@ * shouldn't cause any fragmentation. */ -#include <cbmem.h> -#include <console/uart.h> -#include <device/device.h> -#include <device/pci.h> +#include <assert.h> #include <intelblocks/uart.h> #include <soc/gpio.h> -#include <soc/nvs.h> #include <soc/pci_devs.h> -#include <soc/uart.h> +#include <string.h> -static const struct pad_config uart_gpios[] = { +/* UART pad configuration. Support RXD and TXD for now. */ +const struct uart_gpio_pad_config uart_gpio_pads[] = { #if IS_ENABLED(CONFIG_SOC_INTEL_GLK) - PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_60, NATIVE, DEEP, NF1, HIZCRx1, - DISPUPD), /* LPSS_UART0_RXD */ - PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_61, NATIVE, DEEP, NF1, HIZCRx1, - DISPUPD), /* LPSS_UART0_TXD */ - PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_64, NATIVE, DEEP, NF1, HIZCRx1, - DISPUPD), /* LPSS_UART2_RXD */ - PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_65, NATIVE, DEEP, NF1, HIZCRx1, - DISPUPD), /* LPSS_UART2_TXD */ + { + .console_index = 0, + .gpios = { + PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_60, NATIVE, DEEP, NF1, + HIZCRx1, DISPUPD), /* LPSS_UART0_RXD */ + PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_61, NATIVE, DEEP, NF1, + HIZCRx1, DISPUPD), /* LPSS_UART0_TXD */ + + }, + }, + { + .console_index = 2, + .gpios = { + PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_64, NATIVE, DEEP, NF1, + HIZCRx1, DISPUPD), /* LPSS_UART2_RXD */ + PAD_CFG_NF_IOSSTATE_IOSTERM(GPIO_65, NATIVE, DEEP, NF1, + HIZCRx1, DISPUPD), /* LPSS_UART2_TXD */ + }, + }, #else - PAD_CFG_NF(GPIO_42, NATIVE, DEEP, NF1), /* UART1 RX */ - PAD_CFG_NF(GPIO_43, NATIVE, DEEP, NF1), /* UART1 TX */ - PAD_CFG_NF(GPIO_46, NATIVE, DEEP, NF1), /* UART2 RX */ - PAD_CFG_NF(GPIO_47, NATIVE, DEEP, NF1), /* UART2 TX */ + { + .console_index = 1, + .gpios = { + PAD_CFG_NF(GPIO_42, NATIVE, DEEP, NF1), /* UART1 RX */ + PAD_CFG_NF(GPIO_43, NATIVE, DEEP, NF1), /* UART1 TX */ + }, + }, + { + .console_index = 2, + .gpios = { + PAD_CFG_NF(GPIO_46, NATIVE, DEEP, NF1), /* UART2 RX */ + PAD_CFG_NF(GPIO_47, NATIVE, DEEP, NF1), /* UART2 TX */ + }, + }, #endif }; -static inline int invalid_uart_for_console(void) -{ - /* There are actually only 2 UARTS, and they are named UART1 and - * UART2. They live at pci functions 1 and 2 respectively. */ - if (CONFIG_UART_FOR_CONSOLE > 2 || CONFIG_UART_FOR_CONSOLE < 1) - return 1; - return 0; -} +const int uart_max_index = ARRAY_SIZE(uart_gpio_pads); -void pch_uart_init(void) +struct device *soc_uart_console_to_device(int uart_console) { - uintptr_t base = CONFIG_CONSOLE_UART_BASE_ADDRESS; -#if defined(__SIMPLE_DEVICE__) - pci_devfn_t uart = _PCH_DEV(UART, CONFIG_UART_FOR_CONSOLE & 3); -#else - struct device *uart = _PCH_DEV(UART, CONFIG_UART_FOR_CONSOLE & 3); -#endif - - /* Get a 0-based pad index. See invalid_uart_for_console() above. */ - const int pad_index = CONFIG_UART_FOR_CONSOLE - 1; - - if (invalid_uart_for_console()) - return; - - /* Configure the 2 pads per UART. */ - gpio_configure_pads(&uart_gpios[pad_index * 2], 2); - - /* Program UART2 BAR0, command, reset and clock register */ - uart_common_init(uart, base); - -} - -#if !ENV_SMM -void pch_uart_read_resources(struct device *dev) -{ - pci_dev_read_resources(dev); - - if (IS_ENABLED(CONFIG_SOC_UART_DEBUG) && - uart_is_debug_controller(dev)) { - /* will override existing resource. */ - fixed_mem_resource(dev, PCI_BASE_ADDRESS_0, - CONFIG_CONSOLE_UART_BASE_ADDRESS >> 10, 4, 0); + /* + * if index is valid, this function will return corresponding structure + * for uart console else will return NULL. + */ + switch (uart_console) { + case 0: + return (struct device *)PCH_DEV_UART0; + case 1: + return (struct device *)PCH_DEV_UART1; + case 2: + return (struct device *)PCH_DEV_UART2; + case 3: + return (struct device *)PCH_DEV_UART3; + default: + printk(BIOS_ERR, "Invalid UART console index\n"); + return NULL; } } -#endif - -bool pch_uart_init_debug_controller_on_resume(void) -{ - global_nvs_t *gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS); - - if (gnvs) - return !!gnvs->uior; - - return false; -} - -device_t pch_uart_get_debug_controller(void) -{ - return _PCH_DEV(UART, CONFIG_UART_FOR_CONSOLE); -} - -uintptr_t uart_platform_base(int idx) -{ - return CONFIG_CONSOLE_UART_BASE_ADDRESS; -} diff --git a/src/soc/intel/cannonlake/bootblock/bootblock.c b/src/soc/intel/cannonlake/bootblock/bootblock.c index b7e77976b0..0aac186b42 100644 --- a/src/soc/intel/cannonlake/bootblock/bootblock.c +++ b/src/soc/intel/cannonlake/bootblock/bootblock.c @@ -15,6 +15,7 @@ #include <bootblock_common.h> #include <intelblocks/gspi.h> +#include <intelblocks/uart.h> #include <soc/bootblock.h> #include <soc/iomap.h> #include <soc/pch.h> @@ -31,8 +32,8 @@ void bootblock_soc_early_init(void) bootblock_pch_early_init(); bootblock_cpu_init(); pch_early_iorange_init(); - if (IS_ENABLED(CONFIG_DRIVERS_UART_8250MEM)) - pch_uart_init(); + if (IS_ENABLED(CONFIG_UART_DEBUG)) + uart_bootblock_init(); } void bootblock_soc_init(void) diff --git a/src/soc/intel/cannonlake/bootblock/pch.c b/src/soc/intel/cannonlake/bootblock/pch.c index eb67012781..033f69aaf5 100644 --- a/src/soc/intel/cannonlake/bootblock/pch.c +++ b/src/soc/intel/cannonlake/bootblock/pch.c @@ -80,6 +80,7 @@ void bootblock_pch_early_init(void) gspi_early_bar_init(); p2sb_enable_bar(); p2sb_configure_hpet(); + /* * Enabling PWRM Base for accessing * Global Reset Cause Register. diff --git a/src/soc/intel/cannonlake/include/soc/iomap.h b/src/soc/intel/cannonlake/include/soc/iomap.h index 75f11c0eee..ed9b29ffee 100644 --- a/src/soc/intel/cannonlake/include/soc/iomap.h +++ b/src/soc/intel/cannonlake/include/soc/iomap.h @@ -29,11 +29,13 @@ #define PCH_TRACE_HUB_BASE_ADDRESS 0xfc800000 #define PCH_TRACE_HUB_BASE_SIZE 0x00800000 -#define UART_DEBUG_BASE_0_SIZE 0x1000 +#define UART_BASE_SIZE 0x1000 + #define UART_BASE_0_ADDRESS 0xfe032000 /* Both UART BAR 0 and 1 are 4KB in size */ #define UART_BASE_0_ADDR(x) (UART_BASE_0_ADDRESS + (2 * \ - UART_DEBUG_BASE_0_SIZE * (x))) + UART_BASE_SIZE * (x))) +#define UART_BASE(x) UART_BASE_0_ADDR(x) #define EARLY_I2C_BASE_ADDRESS 0xfe040000 #define EARLY_I2C_BASE(x) (EARLY_I2C_BASE_ADDRESS + (0x1000 * (x))) diff --git a/src/soc/intel/cannonlake/include/soc/pch.h b/src/soc/intel/cannonlake/include/soc/pch.h index 53dd66a908..da64a7a88f 100644 --- a/src/soc/intel/cannonlake/include/soc/pch.h +++ b/src/soc/intel/cannonlake/include/soc/pch.h @@ -29,6 +29,5 @@ #define PCIE_CLK_FREE 0x80 void pch_log_state(void); -void pch_uart_init(void); #endif diff --git a/src/soc/intel/cannonlake/uart.c b/src/soc/intel/cannonlake/uart.c index 80404100fe..d03d21e3c1 100644 --- a/src/soc/intel/cannonlake/uart.c +++ b/src/soc/intel/cannonlake/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,116 +14,73 @@ */ #include <assert.h> -#include <cbmem.h> -#include <console/uart.h> -#include <device/pci.h> #include <device/pci_def.h> #include <intelblocks/gpio.h> #include <intelblocks/lpss.h> #include <intelblocks/pcr.h> #include <intelblocks/uart.h> #include <soc/iomap.h> -#include <soc/nvs.h> #include <soc/pch.h> #include <soc/pci_devs.h> #include <soc/pcr_ids.h> +#include <string.h> -#if !ENV_RAMSTAGE /* Serial IO UART controller legacy mode */ #define PCR_SERIAL_IO_GPPRVRW7 0x618 #define PCR_SIO_PCH_LEGACY_UART(idx) (1 << (idx)) -static const struct port { - struct pad_config pads[2]; /* just TX and RX */ -#if defined(__SIMPLE_DEVICE__) - pci_devfn_t dev; -#else - struct device *dev; -#endif -} uart_ports[] = { - {.dev = PCH_DEV_UART0, - .pads = { PAD_CFG_NF(GPP_C8, NONE, DEEP, NF1), /* RX */ - PAD_CFG_NF(GPP_C9, NONE, DEEP, NF1)} /* TX */ +const struct uart_gpio_pad_config uart_gpio_pads[] = { + { + .console_index = 0, + .gpios = { + PAD_CFG_NF(GPP_C8, NONE, DEEP, NF1), /* UART0 RX */ + PAD_CFG_NF(GPP_C9, NONE, DEEP, NF1), /* UART0 TX */ + }, }, - {.dev = PCH_DEV_UART1, - .pads = { PAD_CFG_NF(GPP_C12, NONE, DEEP, NF1), /* RX */ - PAD_CFG_NF(GPP_C13, NONE, DEEP, NF1)} /* TX */ + { + .console_index = 1, + .gpios = { + PAD_CFG_NF(GPP_C12, NONE, DEEP, NF1), /* UART1 RX */ + PAD_CFG_NF(GPP_C13, NONE, DEEP, NF1), /* UART1 TX */ + }, }, - {.dev = PCH_DEV_UART2, - .pads = { PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1), /* RX */ - PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1)} /* TX */ + { + .console_index = 2, + .gpios = { + PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1), /* UART2 RX */ + PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1), /* UART2 TX */ + }, } }; -void pch_uart_init(void) -{ - uintptr_t base; - const struct port *p; - - assert(CONFIG_UART_FOR_CONSOLE < ARRAY_SIZE(uart_ports)); - p = &uart_ports[CONFIG_UART_FOR_CONSOLE]; - base = uart_platform_base(CONFIG_UART_FOR_CONSOLE); - - uart_common_init(p->dev, base); +const int uart_max_index = ARRAY_SIZE(uart_gpio_pads); - /* Put UART2 in byte access mode for 16550 compatibility */ - if (!IS_ENABLED(CONFIG_DRIVERS_UART_8250MEM_32)) { - pcr_write32(PID_SERIALIO, PCR_SERIAL_IO_GPPRVRW7, - PCR_SIO_PCH_LEGACY_UART(CONFIG_UART_FOR_CONSOLE)); - - /* - * Dummy read after setting any of GPPRVRW7. - * Required for UART 16550 8-bit Legacy mode to become active - */ - lpss_clk_read(base); - } - - gpio_configure_pads(p->pads, ARRAY_SIZE(p->pads)); -} -#endif - -#if IS_ENABLED(CONFIG_DRIVERS_UART_8250MEM) -uintptr_t uart_platform_base(int idx) +void soc_uart_set_legacy_mode(void) { - /* We can only have one serial console at a time */ - return UART_BASE_0_ADDR(idx); + pcr_write32(PID_SERIALIO, PCR_SERIAL_IO_GPPRVRW7, + PCR_SIO_PCH_LEGACY_UART(CONFIG_UART_FOR_CONSOLE)); + /* + * Dummy read after setting any of GPPRVRW7. + * Required for UART 16550 8-bit Legacy mode to become active + */ + lpss_clk_read(UART_BASE(CONFIG_UART_FOR_CONSOLE)); } -#endif -device_t pch_uart_get_debug_controller(void) +struct device *soc_uart_console_to_device(int uart_console) { - switch (CONFIG_UART_FOR_CONSOLE) { + /* + * if index is valid, this function will return corresponding structure + * for uart console else will return NULL. + */ + switch (uart_console) { case 0: - return PCH_DEV_UART0; + return (struct device *)PCH_DEV_UART0; case 1: - return PCH_DEV_UART1; + return (struct device *)PCH_DEV_UART1; case 2: + return (struct device *)PCH_DEV_UART2; default: - return PCH_DEV_UART2; - } -} - -void pch_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_0_ADDR(CONFIG_UART_FOR_CONSOLE); - res->size = UART_DEBUG_BASE_0_SIZE; - res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | - IORESOURCE_FIXED; + printk(BIOS_ERR, "Invalid UART console index\n"); + return NULL; } } - -bool pch_uart_init_debug_controller_on_resume(void) -{ - global_nvs_t *gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS); - - if (gnvs) - return !!gnvs->uior; - - return false; -} 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 */ diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig index 3e0158bbab..9412b03eb9 100644 --- a/src/soc/intel/skylake/Kconfig +++ b/src/soc/intel/skylake/Kconfig @@ -64,6 +64,7 @@ config CPU_SPECIFIC_OPTIONS select SOC_INTEL_COMMON_BLOCK_SGX select SOC_INTEL_COMMON_BLOCK_SMM select SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP + select SOC_INTEL_COMMON_BLOCK_UART select SOC_INTEL_COMMON_BLOCK_VMX select SOC_INTEL_COMMON_PCH_BASE select SOC_INTEL_COMMON_NHLT diff --git a/src/soc/intel/skylake/acpi.c b/src/soc/intel/skylake/acpi.c index 5bed11878c..2c06b4bea1 100644 --- a/src/soc/intel/skylake/acpi.c +++ b/src/soc/intel/skylake/acpi.c @@ -648,7 +648,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); current = acpi_write_hpet(device, current, rsdp); return acpi_align_current(current); diff --git a/src/soc/intel/skylake/bootblock/bootblock.c b/src/soc/intel/skylake/bootblock/bootblock.c index 1803694132..a2bcaaf9af 100644 --- a/src/soc/intel/skylake/bootblock/bootblock.c +++ b/src/soc/intel/skylake/bootblock/bootblock.c @@ -16,6 +16,7 @@ #include <bootblock_common.h> #include <drivers/i2c/designware/dw_i2c.h> #include <intelblocks/gspi.h> +#include <intelblocks/uart.h> #include <soc/bootblock.h> asmlinkage void bootblock_c_entry(uint64_t base_timestamp) @@ -32,7 +33,7 @@ void bootblock_soc_early_init(void) pch_early_iorange_init(); if (IS_ENABLED(CONFIG_UART_DEBUG)) - pch_uart_init(); + uart_bootblock_init(); } void bootblock_soc_init(void) diff --git a/src/soc/intel/skylake/include/soc/bootblock.h b/src/soc/intel/skylake/include/soc/bootblock.h index 59ce92a58d..f5065148d3 100644 --- a/src/soc/intel/skylake/include/soc/bootblock.h +++ b/src/soc/intel/skylake/include/soc/bootblock.h @@ -27,7 +27,6 @@ static inline void bootblock_fsp_temp_ram_init(void) {} /* Bootblock pre console init programming */ void bootblock_cpu_init(void); void bootblock_pch_early_init(void); -void pch_uart_init(void); /* Bootblock post console init programming */ void i2c_early_init(void); diff --git a/src/soc/intel/skylake/include/soc/iomap.h b/src/soc/intel/skylake/include/soc/iomap.h index 475d79db71..628a272a54 100644 --- a/src/soc/intel/skylake/include/soc/iomap.h +++ b/src/soc/intel/skylake/include/soc/iomap.h @@ -25,11 +25,12 @@ #define PCH_PRESERVED_BASE_ADDRESS 0xfc800000 #define PCH_PRESERVED_BASE_SIZE 0x02000000 -#define UART_DEBUG_BASE_0_SIZE 0x1000 +#define UART_BASE_SIZE 0x1000 #define UART_BASE_0_ADDRESS 0xfe030000 /* Both UART BAR 0 and 1 are 4KB in size */ #define UART_BASE_0_ADDR(x) (UART_BASE_0_ADDRESS + (2 * \ - UART_DEBUG_BASE_0_SIZE * (x))) + UART_BASE_SIZE * (x))) +#define UART_BASE(x) UART_BASE_0_ADDR(x) #define EARLY_I2C_BASE_ADDRESS 0xfe040000 #define EARLY_I2C_BASE(x) (EARLY_I2C_BASE_ADDRESS + (0x1000 * (x))) diff --git a/src/soc/intel/skylake/uart.c b/src/soc/intel/skylake/uart.c index 1b4e96eb60..53d408aebc 100644 --- a/src/soc/intel/skylake/uart.c +++ b/src/soc/intel/skylake/uart.c @@ -2,7 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2015 Google Inc. - * Copyright (C) 2015-2017 Intel Corporation + * Copyright (C) 2015-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,106 +14,74 @@ * GNU General Public License for more details. */ -#include <cbmem.h> -#include <console/uart.h> -#include <device/pci.h> +#include <console/console.h> #include <device/pci_def.h> #include <gpio.h> #include <intelblocks/lpss.h> #include <intelblocks/pcr.h> #include <intelblocks/uart.h> #include <soc/bootblock.h> -#include <soc/nvs.h> #include <soc/pci_devs.h> #include <soc/pcr_ids.h> +#include <string.h> /* Serial IO UART controller legacy mode */ #define PCR_SERIAL_IO_GPPRVRW7 0x618 #define PCR_SIO_PCH_LEGACY_UART(idx) (1 << (idx)) /* UART pad configuration. Support RXD and TXD for now. */ -static const struct pad_config uart_pads[][2] = { +const struct uart_gpio_pad_config uart_gpio_pads[] = { { - PAD_CFG_NF(GPP_C8, NONE, DEEP, NF1), /* UART0_RXD */ - PAD_CFG_NF(GPP_C9, NONE, DEEP, NF1), /* UART0_TXD */ + .console_index = 0, + .gpios = { + PAD_CFG_NF(GPP_C8, NONE, DEEP, NF1), /* UART0 RX */ + PAD_CFG_NF(GPP_C9, NONE, DEEP, NF1), /* UART0 TX */ + }, }, { - PAD_CFG_NF(GPP_C12, NONE, DEEP, NF1), /* UART1_RXD */ - PAD_CFG_NF(GPP_C13, NONE, DEEP, NF1), /* UART1_TXD */ + .console_index = 1, + .gpios = { + PAD_CFG_NF(GPP_C12, NONE, DEEP, NF1), /* UART1 RX */ + PAD_CFG_NF(GPP_C13, NONE, DEEP, NF1), /* UART1 TX */ + }, }, { - PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1), /* UART2_RXD */ - PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1), /* UART2_TXD */ + .console_index = 2, + .gpios = { + PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1), /* UART2 RX */ + PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1), /* UART2 TX */ + }, } }; -#if IS_ENABLED(CONFIG_DRIVERS_UART_8250MEM) -uintptr_t uart_platform_base(int idx) -{ - /* Same base address for all debug port usage. In reality UART2 - * is currently only supported. */ - return UART_BASE_0_ADDR(idx); -} -#endif +const int uart_max_index = ARRAY_SIZE(uart_gpio_pads); -void pch_uart_init(void) +void soc_uart_set_legacy_mode(void) { - uintptr_t base = uart_platform_base(CONFIG_UART_FOR_CONSOLE); - - uart_common_init(pch_uart_get_debug_controller(), base); - - /* Put UART in byte access mode for 16550 compatibility */ - if (!IS_ENABLED(CONFIG_DRIVERS_UART_8250MEM_32)) { - pcr_write32(PID_SERIALIO, PCR_SERIAL_IO_GPPRVRW7, - PCR_SIO_PCH_LEGACY_UART(CONFIG_UART_FOR_CONSOLE)); - - /* - * Dummy read after setting any of GPPRVRW7. - * Required for UART 16550 8-bit Legacy mode to become active - */ - lpss_clk_read(base); - } - - gpio_configure_pads(uart_pads[CONFIG_UART_FOR_CONSOLE], - ARRAY_SIZE(uart_pads[CONFIG_UART_FOR_CONSOLE])); -} - -#if !ENV_SMM -void pch_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_0_ADDR(CONFIG_UART_FOR_CONSOLE); - res->size = UART_DEBUG_BASE_0_SIZE; - res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | - IORESOURCE_FIXED; - } -} -#endif - -bool pch_uart_init_debug_controller_on_resume(void) -{ - global_nvs_t *gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS); - - if (gnvs) - return !!gnvs->uior; - - return false; + pcr_write32(PID_SERIALIO, PCR_SERIAL_IO_GPPRVRW7, + PCR_SIO_PCH_LEGACY_UART(CONFIG_UART_FOR_CONSOLE)); + /* + * Dummy read after setting any of GPPRVRW7. + * Required for UART 16550 8-bit Legacy mode to become active + */ + lpss_clk_read(UART_BASE(CONFIG_UART_FOR_CONSOLE)); } -device_t pch_uart_get_debug_controller(void) +struct device *soc_uart_console_to_device(int uart_console) { - switch (CONFIG_UART_FOR_CONSOLE) { + /* + * if index is valid, this function will return corresponding structure + * for uart console else will return NULL. + */ + switch (uart_console) { case 0: - return PCH_DEV_UART0; + return (struct device *)PCH_DEV_UART0; case 1: - return PCH_DEV_UART1; + return (struct device *)PCH_DEV_UART1; case 2: + return (struct device *)PCH_DEV_UART2; default: - return PCH_DEV_UART2; + printk(BIOS_ERR, "Invalid UART console index\n"); + return NULL; } } |