Patrick Rudolph has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/40405 )
Change subject: soc/intel/cannonlake: Add support for UART2 on PCH-H ......................................................................
soc/intel/cannonlake: Add support for UART2 on PCH-H
On PCH-H the UART2 can't be used as PCI device as the parent multi function device isn't available.
As workaround add an ACPI driver for PCH-H UART2 that generates ACPI code for the Intel LPSS ACPI driver.
Tested on Linux with Sunrise Point ACPI ID for UART2.
Change-Id: I838d16322be38f5421c1f63b457a0af552e0ed96 Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com --- M src/soc/intel/cannonlake/Makefile.inc M src/soc/intel/cannonlake/acpi/serialio.asl A src/soc/intel/cannonlake/pch_h.c M src/soc/intel/common/block/include/intelblocks/uart.h M src/soc/intel/common/block/uart/uart.c 5 files changed, 98 insertions(+), 4 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/05/40405/1
diff --git a/src/soc/intel/cannonlake/Makefile.inc b/src/soc/intel/cannonlake/Makefile.inc index c744e99..e263264 100644 --- a/src/soc/intel/cannonlake/Makefile.inc +++ b/src/soc/intel/cannonlake/Makefile.inc @@ -54,6 +54,11 @@ ramstage-y += vr_config.c ramstage-y += sd.c ramstage-y += xhci.c +ifeq ($(CONFIG_HAVE_ACPI_TABLES),y) +ifeq ($(CONFIG_SOC_INTEL_COMMON_BLOCK_LPSS),y) +ramstage-$(CONFIG_SOC_INTEL_CANNONLAKE_PCH_H) += pch_h.c +endif +endif
smm-y += elog.c smm-y += p2sb.c diff --git a/src/soc/intel/cannonlake/acpi/serialio.asl b/src/soc/intel/cannonlake/acpi/serialio.asl index 2785e3d..5e28b98 100644 --- a/src/soc/intel/cannonlake/acpi/serialio.asl +++ b/src/soc/intel/cannonlake/acpi/serialio.asl @@ -69,8 +69,11 @@ Name (_DDN, "Serial IO UART Controller 1") }
+ +#if !CONFIG(SOC_INTEL_CANNONLAKE_PCH_H) Device (UAR2) { Name (_ADR, 0x00190002) Name (_DDN, "Serial IO UART Controller 2") } +#endif diff --git a/src/soc/intel/cannonlake/pch_h.c b/src/soc/intel/cannonlake/pch_h.c new file mode 100644 index 0000000..84a75e8 --- /dev/null +++ b/src/soc/intel/cannonlake/pch_h.c @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* This file is part of the coreboot project. */ +#include <arch/acpi.h> +#include <arch/acpigen.h> +#include <device/device.h> +#include <device/pci.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <soc/irq.h> +#include <intelblocks/uart.h> +#include <console/console.h> + +/* + * On PCH-H the I2C4 0:19.0 device isn't usable and thus 0:19.2 isn't detected + * using standard PCI probing. + * Generate an ACPI entry if the device is enabled in devicetree for the ACPI + * LPSS driver. + */ +static void pch_h_uart2_fill_ssdt(struct device *dev) +{ + struct acpi_irq irq = ACPI_IRQ_LEVEL_LOW(LPSS_UART2_IRQ); + const char *scope = acpi_device_scope(dev); + printk(BIOS_ERR, "ACPIGEN: %s\n", acpi_device_name(dev)); + struct resource *res; + if (!scope) + return; + + res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (!res) + return; + + /* Device */ + acpigen_write_scope(scope); + acpigen_write_device(acpi_device_name(dev)); + acpigen_write_name_string("_HID", acpi_device_hid(dev)); + /* + * INT344A is the Sunrise Point HID, as the Linux kernel doesn't support + * CannonPoint yet... + */ + acpigen_write_name_string("_CID", "INT344A"); + acpi_device_write_uid(dev); + acpigen_write_name_string("_DDN", "LPSS ACPI UART"); + acpigen_write_STA(acpi_device_status(dev)); + + /* Resources */ + acpigen_write_name("_CRS"); + acpigen_write_resourcetemplate_header(); + + acpi_device_write_interrupt(&irq); + acpigen_write_mem32fixed(1, res->base, res->size); + + acpigen_write_resourcetemplate_footer(); + + acpigen_pop_len(); /* Device */ + acpigen_pop_len(); /* Scope */ +} + +static const char *pch_h_uart2_acpi_hid(const struct device *dev) +{ + return "INT34BA"; +} + +static struct device_operations device_ops_cnp_h = { + .read_resources = uart_common_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = uart_common_enable_resources, + .ops_pci = &pci_dev_ops_pci, + .acpi_hid = pch_h_uart2_acpi_hid, + .acpi_fill_ssdt_generator = pch_h_uart2_fill_ssdt, +}; + +static const struct pci_driver pch_h_uart __pci_driver = { + .ops = &device_ops_cnp_h, + .vendor = PCI_VENDOR_ID_INTEL, + .device = PCI_DEVICE_ID_INTEL_CNP_H_UART2, +}; diff --git a/src/soc/intel/common/block/include/intelblocks/uart.h b/src/soc/intel/common/block/include/intelblocks/uart.h index cc27f0e..a51a739 100644 --- a/src/soc/intel/common/block/include/intelblocks/uart.h +++ b/src/soc/intel/common/block/include/intelblocks/uart.h @@ -31,6 +31,16 @@ void uart_common_init(const struct device *dev, uintptr_t baseaddr);
/* + * Common routine to enable UART resources in PCI config space. + */ +void uart_common_enable_resources(struct device *dev); + +/* + * Common routine to read UART resources in PCI config space. + */ +void uart_common_read_resources(struct device *dev); + +/* * Check if UART debug controller is initialized * Returns: * true = If debug controller PCI config space is initialized and device is diff --git a/src/soc/intel/common/block/uart/uart.c b/src/soc/intel/common/block/uart/uart.c index 7d75bdd..3464571 100644 --- a/src/soc/intel/common/block/uart/uart.c +++ b/src/soc/intel/common/block/uart/uart.c @@ -143,7 +143,7 @@
#if ENV_RAMSTAGE
-static void uart_read_resources(struct device *dev) +void uart_common_read_resources(struct device *dev) { pci_dev_read_resources(dev);
@@ -213,7 +213,7 @@ return pch_uart_init_debug_controller_on_resume(); }
-static void uart_common_enable_resources(struct device *dev) +void uart_common_enable_resources(struct device *dev) { pci_dev_enable_resources(dev);
@@ -227,7 +227,7 @@ }
static struct device_operations device_ops = { - .read_resources = uart_read_resources, + .read_resources = uart_common_read_resources, .set_resources = pci_dev_set_resources, .enable_resources = uart_common_enable_resources, .ops_pci = &pci_dev_ops_pci, @@ -256,7 +256,6 @@ PCI_DEVICE_ID_INTEL_GLK_UART3, PCI_DEVICE_ID_INTEL_CNP_H_UART0, PCI_DEVICE_ID_INTEL_CNP_H_UART1, - PCI_DEVICE_ID_INTEL_CNP_H_UART2, PCI_DEVICE_ID_INTEL_ICP_UART0, PCI_DEVICE_ID_INTEL_ICP_UART1, PCI_DEVICE_ID_INTEL_ICP_UART2,