diff --git a/CODEOWNERS b/CODEOWNERS index 49647556135..27a8ae80705 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -29,6 +29,7 @@ /arch/x86/ @andrewboie @ramakrishnapallala /arch/x86/core/ @andrewboie /arch/x86/core/crt0.S @ramakrishnapallala @nashif +/arch/x86/core/pcie.c @gnuless /soc/x86/ @andrewboie @ramakrishnapallala /soc/x86/intel_quark/quark_d2000/ @nashif /soc/x86/intel_quark/quark_se/ @nashif @@ -119,6 +120,7 @@ /drivers/led_strip/ @mbolivar /drivers/modem/ @mike-scott /drivers/pci/ @gnuless +/drivers/pcie/ @gnuless /drivers/pinmux/stm32/ @rsalveti @idlethread /drivers/sensor/ @bogdan-davidoaia @MaureenHelm /drivers/sensor/hts*/ @avisconti @@ -126,6 +128,7 @@ /drivers/sensor/lps*/ @avisconti /drivers/sensor/lsm*/ @avisconti /drivers/serial/uart_altera_jtag_hal.c @ramakrishnapallala +/drivers/serial/*ns16550* @gnuless /drivers/net/slip.c @jukkar @tbursztyka /drivers/spi/ @tbursztyka /drivers/spi/spi_ll_stm32.* @superna9999 @@ -142,6 +145,7 @@ /dts/arm/nxp/ @MaureenHelm /dts/bindings/ @galak /dts/bindings/can/ @alexanderwachter +/dts/bindings/serial/ns16550.yaml @gnuless /dts/bindings/*/nordic* @anangl /dts/bindings/*/nxp* @MaureenHelm /ext/fs/ @nashif @ramakrishnapallala @@ -181,6 +185,9 @@ /include/drivers/ioapic.h @andrewboie /include/drivers/loapic.h @andrewboie /include/drivers/mvic.h @andrewboie +/include/drivers/pcie/ @gnuless +/include/drivers/serial/uart_ns16550.h @gnuless +/include/dt-bindings/pcie/ @gnuless /include/fs.h @nashif @ramakrishnapallala /include/fs/ @nashif @ramakrishnapallala /include/hwinfo.h @alexanderwachter diff --git a/arch/x86/core/CMakeLists.txt b/arch/x86/core/CMakeLists.txt index 876ca4bff00..3c4a9f15638 100644 --- a/arch/x86/core/CMakeLists.txt +++ b/arch/x86/core/CMakeLists.txt @@ -32,6 +32,7 @@ zephyr_library_sources( zephyr_library_sources_if_kconfig( irq_offload.c) zephyr_library_sources_if_kconfig( x86_mmu.c) zephyr_library_sources_if_kconfig( reboot_rst_cnt.c) +zephyr_library_sources_if_kconfig( pcie.c) zephyr_library_sources_ifdef(CONFIG_LAZY_FP_SHARING float.c) zephyr_library_sources_ifdef(CONFIG_X86_USERSPACE userspace.S) diff --git a/arch/x86/core/pcie.c b/arch/x86/core/pcie.c new file mode 100644 index 00000000000..7be9b8e1a1e --- /dev/null +++ b/arch/x86/core/pcie.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2019 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#ifdef CONFIG_PCIE_MSI +#include +#endif + +/* + * The Configuration Mechanism (previously, Configuration Mechanism #1) + * uses two 32-bit ports in the I/O space, here called CAP and CDP. + * + * N.B.: this code relies on the fact that the PCIE_BDF() format (as + * defined in dt-bindings/pcie/pcie.h) and the CAP agree on the bus/dev/func + * bitfield positions and sizes. + */ + +#define PCIE_X86_CAP 0xCF8U /* Configuration Address Port */ +#define PCIE_X86_CAP_BDF_MASK 0x00FFFF00U /* b/d/f bits */ +#define PCIE_X86_CAP_EN 0x80000000U /* enable bit */ +#define PCIE_X86_CAP_WORD_MASK 0x3FU /* 6-bit word index .. */ +#define PCIE_X86_CAP_WORD_SHIFT 2U /* .. is in CAP[7:2] */ + +#define PCIE_X86_CDP 0xCFCU /* Configuration Data Port */ + +/* + * Helper function for exported configuration functions. Configuration access + * ain't atomic, so spinlock to keep drivers from clobbering each other. + */ +static void pcie_conf(pcie_bdf_t bdf, unsigned int reg, bool write, u32_t *data) +{ + static struct k_spinlock lock; + k_spinlock_key_t k; + + bdf &= PCIE_X86_CAP_BDF_MASK; + bdf |= PCIE_X86_CAP_EN; + bdf |= (reg & PCIE_X86_CAP_WORD_MASK) << PCIE_X86_CAP_WORD_SHIFT; + + k = k_spin_lock(&lock); + sys_out32(bdf, PCIE_X86_CAP); + + if (write) { + sys_out32(*data, PCIE_X86_CDP); + } else { + *data = sys_in32(PCIE_X86_CDP); + } + + sys_out32(0U, PCIE_X86_CAP); + k_spin_unlock(&lock, k); +} + +/* these functions are explained in include/drivers/pcie/pcie.h */ + +u32_t pcie_conf_read(pcie_bdf_t bdf, unsigned int reg) +{ + u32_t data; + + pcie_conf(bdf, reg, false, &data); + return data; +} + +void pcie_conf_write(pcie_bdf_t bdf, unsigned int reg, u32_t data) +{ + pcie_conf(bdf, reg, true, &data); +} + +#ifdef CONFIG_PCIE_MSI + +/* these functions are explained in include/drivers/pcie/msi.h */ + +u32_t pcie_msi_map(unsigned int irq) +{ + ARG_UNUSED(irq); + return 0xFEE00000U; /* standard delivery to BSP local APIC */ +} + +u16_t pcie_msi_mdr(unsigned int irq) +{ + unsigned char vector = _irq_to_interrupt_vector[irq]; + + return 0x4000U | vector; /* edge triggered */ +} + +#endif diff --git a/boards/x86/galileo/galileo_defconfig b/boards/x86/galileo/galileo_defconfig index e150a5c7acb..b4d35263157 100644 --- a/boards/x86/galileo/galileo_defconfig +++ b/boards/x86/galileo/galileo_defconfig @@ -1,6 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 CONFIG_X86=y +CONFIG_PCIE=y CONFIG_SOC_QUARK_X1000=y CONFIG_SOC_SERIES_QUARK_X1000=y CONFIG_BOARD_GALILEO=y diff --git a/boards/x86/up_squared/dts_fixup.h b/boards/x86/up_squared/dts_fixup.h index 126353a582b..6a76124f8ec 100644 --- a/boards/x86/up_squared/dts_fixup.h +++ b/boards/x86/up_squared/dts_fixup.h @@ -6,42 +6,32 @@ /* Board level DTS fixup file */ -#ifdef CONFIG_SBL_FIXUP +#define DT_UART_NS16550_PORT_0_BASE_ADDR DT_NS16550_0_BASE_ADDRESS +#define DT_UART_NS16550_PORT_0_SIZE DT_NS16550_0_SIZE +#define DT_UART_NS16550_PORT_0_BAUD_RATE DT_NS16550_0_CURRENT_SPEED +#define DT_UART_NS16550_PORT_0_NAME DT_NS16550_0_LABEL +#define DT_UART_NS16550_PORT_0_IRQ DT_NS16550_0_IRQ_0 +#define DT_UART_NS16550_PORT_0_IRQ_PRI DT_NS16550_0_IRQ_0_PRIORITY +#define DT_UART_NS16550_PORT_0_IRQ_FLAGS DT_NS16550_0_IRQ_0_SENSE +#define DT_UART_NS16550_PORT_0_CLK_FREQ DT_NS16550_0_CLOCK_FREQUENCY +#define DT_UART_NS16550_PORT_0_PCIE DT_NS16550_0_PCIE -#define DT_UART_NS16550_PORT_0_BASE_ADDR DT_NS16550_81434000_BASE_ADDRESS -#define DT_UART_NS16550_PORT_0_BAUD_RATE DT_NS16550_81434000_CURRENT_SPEED -#define DT_UART_NS16550_PORT_0_NAME DT_NS16550_81434000_LABEL -#define DT_UART_NS16550_PORT_0_IRQ DT_NS16550_81434000_IRQ_0 -#define DT_UART_NS16550_PORT_0_IRQ_PRI DT_NS16550_81434000_IRQ_0_PRIORITY -#define DT_UART_NS16550_PORT_0_IRQ_FLAGS DT_NS16550_81434000_IRQ_0_SENSE -#define DT_UART_NS16550_PORT_0_CLK_FREQ DT_NS16550_81434000_CLOCK_FREQUENCY +#ifdef DT_NS16550_0_PCP +#define DT_UART_NS16550_PORT_0_PCP DT_NS16550_0_PCP +#endif -#define DT_UART_NS16550_PORT_1_BASE_ADDR DT_NS16550_81432000_BASE_ADDRESS -#define DT_UART_NS16550_PORT_1_BAUD_RATE DT_NS16550_81432000_CURRENT_SPEED -#define DT_UART_NS16550_PORT_1_NAME DT_NS16550_81432000_LABEL -#define DT_UART_NS16550_PORT_1_IRQ DT_NS16550_81432000_IRQ_0 -#define DT_UART_NS16550_PORT_1_IRQ_PRI DT_NS16550_81432000_IRQ_0_PRIORITY -#define DT_UART_NS16550_PORT_1_IRQ_FLAGS DT_NS16550_81432000_IRQ_0_SENSE -#define DT_UART_NS16550_PORT_1_CLK_FREQ DT_NS16550_81432000_CLOCK_FREQUENCY - -#else - -#define DT_UART_NS16550_PORT_0_BASE_ADDR DT_NS16550_91524000_BASE_ADDRESS -#define DT_UART_NS16550_PORT_0_BAUD_RATE DT_NS16550_91524000_CURRENT_SPEED -#define DT_UART_NS16550_PORT_0_NAME DT_NS16550_91524000_LABEL -#define DT_UART_NS16550_PORT_0_IRQ DT_NS16550_91524000_IRQ_0 -#define DT_UART_NS16550_PORT_0_IRQ_PRI DT_NS16550_91524000_IRQ_0_PRIORITY -#define DT_UART_NS16550_PORT_0_IRQ_FLAGS DT_NS16550_91524000_IRQ_0_SENSE -#define DT_UART_NS16550_PORT_0_CLK_FREQ DT_NS16550_91524000_CLOCK_FREQUENCY - -#define DT_UART_NS16550_PORT_1_BASE_ADDR DT_NS16550_91522000_BASE_ADDRESS -#define DT_UART_NS16550_PORT_1_BAUD_RATE DT_NS16550_91522000_CURRENT_SPEED -#define DT_UART_NS16550_PORT_1_NAME DT_NS16550_91522000_LABEL -#define DT_UART_NS16550_PORT_1_IRQ DT_NS16550_91522000_IRQ_0 -#define DT_UART_NS16550_PORT_1_IRQ_PRI DT_NS16550_91522000_IRQ_0_PRIORITY -#define DT_UART_NS16550_PORT_1_IRQ_FLAGS DT_NS16550_91522000_IRQ_0_SENSE -#define DT_UART_NS16550_PORT_1_CLK_FREQ DT_NS16550_91522000_CLOCK_FREQUENCY +#define DT_UART_NS16550_PORT_1_BASE_ADDR DT_NS16550_1_BASE_ADDRESS +#define DT_UART_NS16550_PORT_1_SIZE DT_NS16550_1_SIZE +#define DT_UART_NS16550_PORT_1_BAUD_RATE DT_NS16550_1_CURRENT_SPEED +#define DT_UART_NS16550_PORT_1_NAME DT_NS16550_1_LABEL +#define DT_UART_NS16550_PORT_1_IRQ DT_NS16550_1_IRQ_0 +#define DT_UART_NS16550_PORT_1_IRQ_PRI DT_NS16550_1_IRQ_0_PRIORITY +#define DT_UART_NS16550_PORT_1_IRQ_FLAGS DT_NS16550_1_IRQ_0_SENSE +#define DT_UART_NS16550_PORT_1_CLK_FREQ DT_NS16550_1_CLOCK_FREQUENCY +#define DT_UART_NS16550_PORT_1_PCIE DT_NS16550_1_PCIE +#ifdef DT_NS16550_1_PCP +#define DT_UART_NS16550_PORT_1_PCP DT_NS16550_1_PCP #endif /* End of Board Level DTS fixup file */ diff --git a/boards/x86/up_squared/up_squared.dts b/boards/x86/up_squared/up_squared.dts index 2e86b269e13..0842d919e95 100644 --- a/boards/x86/up_squared/up_squared.dts +++ b/boards/x86/up_squared/up_squared.dts @@ -13,6 +13,7 @@ #include #include +#include / { model = "up_squared"; @@ -29,24 +30,29 @@ }; soc { - uart0: uart@91524000 { + uart0: uart@0 { compatible = "ns16550"; - reg = <0x91524000 0x1000>; + + pcie; + reg = ; + label = "UART_0"; clock-frequency = <1843200>; interrupts = <4 IRQ_TYPE_LEVEL_LOW 3>; interrupt-parent = <&intc>; - status = "ok"; current-speed = <115200>; }; - uart1: uart@91522000 { + uart1: uart@1 { compatible = "ns16550"; - reg = <0x91522000 0x1000>; + + pcie; + reg = ; + label = "UART_1"; clock-frequency = <1843200>; - interrupts = <5 IRQ_TYPE_LEVEL_LOW 3>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW 3>; interrupt-parent = <&intc>; status = "ok"; diff --git a/boards/x86/up_squared/up_squared_defconfig b/boards/x86/up_squared/up_squared_defconfig index a55170494d7..7d4b33cf90d 100644 --- a/boards/x86/up_squared/up_squared_defconfig +++ b/boards/x86/up_squared/up_squared_defconfig @@ -13,4 +13,5 @@ CONFIG_UART_NS16550=y CONFIG_UART_CONSOLE=y CONFIG_I2C=y CONFIG_PCI=y +CONFIG_PCIE=y CONFIG_PCI_ENUMERATION=y diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index 3da125b8dee..aa770c1049c 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -21,6 +21,7 @@ add_subdirectory_if_kconfig(led) add_subdirectory_if_kconfig(led_strip) add_subdirectory_if_kconfig(modem) add_subdirectory_if_kconfig(pci) +add_subdirectory_if_kconfig(pcie) add_subdirectory_if_kconfig(pinmux) add_subdirectory_if_kconfig(pwm) add_subdirectory_if_kconfig(rtc) diff --git a/drivers/Kconfig b/drivers/Kconfig index 94b898722b6..662c02f7baa 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -29,6 +29,8 @@ source "drivers/entropy/Kconfig" source "drivers/pci/Kconfig" +source "drivers/pcie/Kconfig" + source "drivers/gpio/Kconfig" source "drivers/interrupt_controller/Kconfig.shared_irq" diff --git a/drivers/pcie/CMakeLists.txt b/drivers/pcie/CMakeLists.txt new file mode 100644 index 00000000000..c6443fcb6ab --- /dev/null +++ b/drivers/pcie/CMakeLists.txt @@ -0,0 +1,3 @@ +zephyr_sources(pcie.c) +zephyr_sources_ifdef(CONFIG_PCIE_MSI msi.c) +zephyr_sources_ifdef(CONFIG_PCIE_SHELL shell.c) diff --git a/drivers/pcie/Kconfig b/drivers/pcie/Kconfig new file mode 100644 index 00000000000..12af0fb204a --- /dev/null +++ b/drivers/pcie/Kconfig @@ -0,0 +1,34 @@ +# Kconfig - PCIe/new PCI configuration options + +# +# Copyright (c) 2019 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +menuconfig PCIE + bool "Enable new PCI/PCIe support" + depends on X86 + help + This option enables support for new PCI(e) drivers. + +if PCIE + +config PCIE_MSI + bool "Enable support for PCI(e) MSI" + default n + help + Use Message-Signaled Interrupts where possible. With this option + enabled, PCI(e) devices which support MSI will be configured (at + runtime) to use them. This is typically required for PCIe devices + to generate interrupts at all. + +config PCIE_SHELL + bool "Enable PCIe/new PCI Shell" + default n + depends on SHELL + help + Enable commands for debugging PCI(e) using the built-in shell. + +endif # PCIE + diff --git a/drivers/pcie/msi.c b/drivers/pcie/msi.c new file mode 100644 index 00000000000..a6a855f4e42 --- /dev/null +++ b/drivers/pcie/msi.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2019 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +/* functions documented in include/drivers/pcie/msi.h */ + +u32_t pcie_get_cap(pcie_bdf_t bdf, u32_t cap_id) +{ + u32_t reg = 0U; + u32_t data; + + data = pcie_conf_read(bdf, PCIE_CONF_CMDSTAT); + if (data & PCIE_CONF_CMDSTAT_CAPS) { + data = pcie_conf_read(bdf, PCIE_CONF_CAPPTR); + reg = PCIE_CONF_CAPPTR_FIRST(data); + } + + while (reg) { + data = pcie_conf_read(bdf, reg); + + if (PCIE_CONF_CAP_ID(data) == cap_id) + break; + + reg = PCIE_CONF_CAP_NEXT(data); + } + + return reg; +} + +bool pcie_set_msi(pcie_bdf_t bdf, unsigned int irq) +{ + bool success = false; /* keepin' the MISRA peeps employed */ + u32_t base; + u32_t mcr; + u32_t map; + u32_t mdr; + + map = pcie_msi_map(irq); + mdr = pcie_msi_mdr(irq); + base = pcie_get_cap(bdf, PCIE_MSI_CAP_ID); + + if (base != 0U) { + mcr = pcie_conf_read(bdf, base + PCIE_MSI_MCR); + pcie_conf_write(bdf, base + PCIE_MSI_MAP0, map); + + if (mcr & PCIE_MSI_MCR_64) { + pcie_conf_write(bdf, base + PCIE_MSI_MAP1_64, 0U); + pcie_conf_write(bdf, base + PCIE_MSI_MDR_64, mdr); + } else { + pcie_conf_write(bdf, base + PCIE_MSI_MDR_32, mdr); + } + + mcr |= PCIE_MSI_MCR_EN; + mcr &= ~PCIE_MSI_MCR_MME; /* only 1 IRQ please */ + pcie_conf_write(bdf, base + PCIE_MSI_MCR, mcr); + pcie_set_cmd(bdf, PCIE_CONF_CMDSTAT_MASTER, true); + success = true; + } + + return success; +} diff --git a/drivers/pcie/pcie.c b/drivers/pcie/pcie.c new file mode 100644 index 00000000000..928708471f0 --- /dev/null +++ b/drivers/pcie/pcie.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2019 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +/* functions documented in drivers/pcie/pcie.h */ + +bool pcie_probe(pcie_bdf_t bdf, pcie_id_t id) +{ + u32_t data; + + data = pcie_conf_read(bdf, PCIE_CONF_ID); + + if (data == PCIE_ID_NONE) { + return false; + } + + if (id == PCIE_ID_NONE) { + return true; + } + + return (id == data); +} + +void pcie_set_cmd(pcie_bdf_t bdf, u32_t bits, bool on) +{ + u32_t cmdstat; + + cmdstat = pcie_conf_read(bdf, PCIE_CONF_CMDSTAT); + + if (on) { + cmdstat |= bits; + } else { + cmdstat &= ~bits; + } + + pcie_conf_write(bdf, PCIE_CONF_CMDSTAT, cmdstat); +} + +static u32_t pcie_get_bar(pcie_bdf_t bdf, unsigned int index, bool io) +{ + int bar; + u32_t data; + + for (bar = PCIE_CONF_BAR0; bar <= PCIE_CONF_BAR5; ++bar) { + data = pcie_conf_read(bdf, bar); + if (data == PCIE_CONF_BAR_NONE) { + continue; + } + + if ((PCIE_CONF_BAR_IO(data) && io) || + (PCIE_CONF_BAR_MEM(data) && !io)) { + if (index == 0) { + return PCIE_CONF_BAR_ADDR(data); + } + + --index; + } + + if (PCIE_CONF_BAR_64(data)) { + ++bar; + } + } + + return PCIE_CONF_BAR_NONE; +} + +u32_t pcie_get_mbar(pcie_bdf_t bdf, unsigned int index) +{ + return pcie_get_bar(bdf, index, false); +} + +u32_t pcie_get_iobar(pcie_bdf_t bdf, unsigned int index) +{ + return pcie_get_bar(bdf, index, true); +} diff --git a/drivers/pcie/shell.c b/drivers/pcie/shell.c new file mode 100644 index 00000000000..ce6b08fc2b6 --- /dev/null +++ b/drivers/pcie/shell.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2019 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#ifdef CONFIG_PCIE_MSI +#include +#endif + +#define MAX_BUS (0xFFFFFFFF & PCIE_BDF_BUS_MASK) +#define MAX_DEV (0xFFFFFFFF & PCIE_BDF_DEV_MASK) +#define MAX_FUNC (0xFFFFFFFF & PCIE_BDF_FUNC_MASK) + +static void show_msi(const struct shell *shell, pcie_bdf_t bdf) +{ +#ifdef CONFIG_PCIE_MSI + u32_t msi; + u32_t data; + + msi = pcie_get_cap(bdf, PCIE_MSI_CAP_ID); + + if (msi) { + data = pcie_conf_read(bdf, msi + PCIE_MSI_MCR); + shell_fprintf(shell, SHELL_NORMAL, " MSI support%s%s\n", + (data & PCIE_MSI_MCR_64) ? ", 64-bit" : "", + (data & PCIE_MSI_MCR_EN) ? ", enabled" : ""); + } +#endif +} + +static void show_bars(const struct shell *shell, pcie_bdf_t bdf) +{ + u32_t data; + int bar; + + for (bar = PCIE_CONF_BAR0; bar <= PCIE_CONF_BAR5; ++bar) { + data = pcie_conf_read(bdf, bar); + if (data == PCIE_CONF_BAR_NONE) { + continue; + } + + shell_fprintf(shell, SHELL_NORMAL, " bar %d: %s%s %x\n", + bar - PCIE_CONF_BAR0, + PCIE_CONF_BAR_IO(data) ? "I/O" : "MEM", + PCIE_CONF_BAR_64(data) ? ", 64-bit" : "", + PCIE_CONF_BAR_ADDR(data)); + + if (PCIE_CONF_BAR_64(data)) { + ++bar; + } + } +} + +static void show(const struct shell *shell, pcie_bdf_t bdf) +{ + u32_t data; + + data = pcie_conf_read(bdf, PCIE_CONF_ID); + + if (data == PCIE_ID_NONE) { + return; + } + + shell_fprintf(shell, SHELL_NORMAL, "%d:%x.%d ID %x:%x ", + PCIE_BDF_TO_BUS(bdf), + PCIE_BDF_TO_DEV(bdf), + PCIE_BDF_TO_FUNC(bdf), + PCIE_ID_TO_VEND(data), + PCIE_ID_TO_DEV(data)); + + data = pcie_conf_read(bdf, PCIE_CONF_CLASSREV); + shell_fprintf(shell, SHELL_NORMAL, + "class %x subclass %x prog i/f %x rev %x", + PCIE_CONF_CLASSREV_CLASS(data), + PCIE_CONF_CLASSREV_SUBCLASS(data), + PCIE_CONF_CLASSREV_PROGIF(data), + PCIE_CONF_CLASSREV_REV(data)); + + data = pcie_conf_read(bdf, PCIE_CONF_TYPE); + + if (PCIE_CONF_TYPE_BRIDGE(data)) { + shell_fprintf(shell, SHELL_NORMAL, " [bridge]\n"); + } else { + shell_fprintf(shell, SHELL_NORMAL, "\n"); + show_bars(shell, bdf); + show_msi(shell, bdf); + } +} + +static int cmd_lspcie(const struct shell *shell, size_t argc, char **argv) +{ + int bus; + int dev; + int func; + + for (bus = 0; bus <= MAX_BUS; ++bus) { + for (dev = 0; dev <= MAX_DEV; ++dev) { + for (func = 0; func <= MAX_FUNC; ++func) { + show(shell, PCIE_BDF(bus, dev, func)); + } + } + } + + return 0; +} + +SHELL_CMD_REGISTER(lspcie, NULL, "List PCI(e) devices", cmd_lspcie); diff --git a/drivers/serial/Kconfig.ns16550 b/drivers/serial/Kconfig.ns16550 index 07d6714216e..9cd88d08a1b 100644 --- a/drivers/serial/Kconfig.ns16550 +++ b/drivers/serial/Kconfig.ns16550 @@ -9,34 +9,6 @@ menuconfig UART_NS16550 This driver can be used for the serial hardware available on x86 boards. -config UART_NS16550_PCI - bool "Enable PCI Support" - depends on PCI && UART_NS16550 - help - This enables NS16550 to probe for PCI-based serial devices. - - This option enables the driver to auto-detect the device - configuration required to access those ports. - -config UART_NS16550_DLF - bool "Enable Divisor Latch Fraction (DLF) support" - depends on UART_NS16550 - help - This enables support for divisor latch fraction (DLF). - It is used to limit frequency error. - - Says n if you are not sure if hardware supports this. - -config UART_NS16550_PCP - bool "Enable Apollo Lake PRV_CLOCK_PARAMS (PCP) support" - depends on SOC_APOLLO_LAKE && UART_NS16550 - help - This enables configuration of the clock blocks that feed - the UARTs on Apollo Lake SoCs, allowing the generation of - custom baud rates. - - Say n unless you know you need this feature. - config UART_NS16550_LINE_CTRL bool "Enable Serial Line Control for Apps" depends on UART_LINE_CTRL && UART_NS16550 @@ -76,29 +48,6 @@ config UART_NS16550_PORT_0_OPTIONS help Options used for port initialization. -config UART_NS16550_PORT_0_DLF - hex "Port 0 DLF value" - default 0x0 - depends on UART_NS16550_PORT_0 && UART_NS16550_DLF - help - Value for DLF register. - -config UART_NS16550_PORT_0_PCP - hex "Port 0 PCP value" - default 0 - depends on UART_NS16550_PORT_0 && UART_NS16550_PCP - help - Value for PRV_CLOCK_PARAMS register. If left at its default - value (0), then the kernel will not attempt to set the PCP - for this UART; otherwise be sure the device tree for this - port has sys_clk_freq set accordingly. - -config UART_NS16550_PORT_0_PCI - bool "Port 0 is PCI-based" - depends on UART_NS16550_PCI && UART_NS16550_PORT_0 - help - Obtain port information from PCI. - # ---------- Port 1 ---------- menuconfig UART_NS16550_PORT_1 @@ -115,29 +64,6 @@ config UART_NS16550_PORT_1_OPTIONS help Options used for port initialization. -config UART_NS16550_PORT_1_DLF - hex "Port 1 DLF value" - default 0x0 - depends on UART_NS16550_PORT_1 && UART_NS16550_DLF - help - Value for DLF register. - -config UART_NS16550_PORT_1_PCP - hex "Port 1 PCP value" - default 0 - depends on UART_NS16550_PORT_1 && UART_NS16550_PCP - help - Value for PRV_CLOCK_PARAMS register. If left at its default - value (0), then the kernel will not attempt to set the PCP - for this UART; otherwise be sure the device tree for this - port has sys_clk_freq set accordingly. - -config UART_NS16550_PORT_1_PCI - bool "Port 1 is PCI-based" - depends on UART_NS16550_PCI && UART_NS16550_PORT_1 - help - Obtain port information from PCI. - # ---------- Port 2 ---------- menuconfig UART_NS16550_PORT_2 @@ -155,29 +81,6 @@ config UART_NS16550_PORT_2_OPTIONS help Options used for port initialization. -config UART_NS16550_PORT_2_DLF - hex "Port 2 DLF value" - default 0x0 - depends on UART_NS16550_PORT_2 && UART_NS16550_DLF - help - Value for DLF register. - -config UART_NS16550_PORT_2_PCP - hex "Port 2 PCP value" - default 0 - depends on UART_NS16550_PORT_2 && UART_NS16550_PCP - help - Value for PRV_CLOCK_PARAMS register. If left at its default - value (0), then the kernel will not attempt to set the PCP - for this UART; otherwise be sure the device tree for this - port has sys_clk_freq set accordingly. - -config UART_NS16550_PORT_2_PCI - bool "Port 2 is PCI-based" - depends on UART_NS16550_PCI && UART_NS16550_PORT_2 - help - Obtain port information from PCI. - # ---------- Port 3 ---------- menuconfig UART_NS16550_PORT_3 @@ -193,26 +96,3 @@ config UART_NS16550_PORT_3_OPTIONS depends on UART_NS16550_PORT_3 help Options used for port initialization. - -config UART_NS16550_PORT_3_DLF - hex "Port 3 DLF value" - default 0x0 - depends on UART_NS16550_PORT_3 && UART_NS16550_DLF - help - Value for DLF register. - -config UART_NS16550_PORT_3_PCP - hex "Port 3 PCP value" - default 0 - depends on UART_NS16550_PORT_3 && UART_NS16550_PCP - help - Value for PRV_CLOCK_PARAMS register. If left at its default - value (0), then the kernel will not attempt to set the PCP - for this UART; otherwise be sure the device tree for this - port has sys_clk_freq set accordingly. - -config UART_NS16550_PORT_3_PCI - bool "Port 3 is PCI-based" - depends on UART_NS16550_PCI && UART_NS16550_PORT_3 - help - Obtain port information from PCI. diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index 224e13177f0..60ba9b50d4a 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -20,7 +20,6 @@ * UART_REG_ADDR_INTERVAL */ - #include #include #include @@ -33,13 +32,39 @@ #include #include -#ifdef CONFIG_PCI -#include -#include -#endif /* CONFIG_PCI */ - #include +/* + * If PCP is set for any of the ports, enable support. + * Ditto for DLF and PCI(e). + */ + +#if defined(DT_UART_NS16550_PORT_0_PCP) || \ + defined(DT_UART_NS16550_PORT_1_PCP) || \ + defined(DT_UART_NS16550_PORT_2_PCP) || \ + defined(DT_UART_NS16550_PORT_3_PCP) +#define UART_NS16550_PCP_ENABLED +#endif + +#if defined(DT_UART_NS16550_PORT_0_DLF) || \ + defined(DT_UART_NS16550_PORT_1_DLF) || \ + defined(DT_UART_NS16550_PORT_2_DLF) || \ + defined(DT_UART_NS16550_PORT_3_DLF) +#define UART_NS16550_DLF_ENABLED +#endif + +#if DT_UART_NS16550_PORT_0_PCIE || \ + DT_UART_NS16550_PORT_1_PCIE || \ + DT_UART_NS16550_PORT_2_PCIE || \ + DT_UART_NS16550_PORT_3_PCIE +BUILD_ASSERT_MSG(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE"); +#define UART_NS16550_PCIE_ENABLED +#include +#ifdef CONFIG_PCIE_MSI +#include +#endif +#endif + /* register definitions */ #define REG_THR 0x00 /* Transmitter holding reg. */ @@ -227,9 +252,15 @@ struct uart_ns16550_device_config { uart_irq_config_func_t irq_config_func; #endif -#ifdef CONFIG_UART_NS16550_PCP +#ifdef UART_NS16550_PCP_ENABLED u32_t pcp; #endif + +#ifdef UART_NS16550_PCIE_ENABLED + bool pcie; + pcie_bdf_t pcie_bdf; + pcie_id_t pcie_id; +#endif }; /** Device data structure */ @@ -238,47 +269,19 @@ struct uart_ns16550_dev_data_t { u32_t baud_rate; /**< Baud rate */ u8_t options; /**< Serial port options */ -#ifdef CONFIG_PCI - struct pci_dev_info pci_dev; -#endif /* CONFIG_PCI */ - #ifdef CONFIG_UART_INTERRUPT_DRIVEN u8_t iir_cache; /**< cache of IIR since it clears when read */ - uart_irq_callback_user_data_t cb; /**< Callback function pointer */ + uart_irq_callback_user_data_t cb; /**< Callback function pointer */ void *cb_data; /**< Callback function arg */ #endif -#ifdef CONFIG_UART_NS16550_DLF +#ifdef UART_NS16550_DLF_ENABLED u8_t dlf; /**< DLF value */ #endif }; static const struct uart_driver_api uart_ns16550_driver_api; -#ifdef CONFIG_UART_NS16550_DLF -static inline void set_dlf(struct device *dev, u32_t val) -{ - struct uart_ns16550_dev_data_t * const dev_data = DEV_DATA(dev); - - OUTBYTE(DLF(dev), val); - dev_data->dlf = val; -} -#endif - -#ifdef CONFIG_UART_NS16550_PCP -static inline void set_pcp(struct device *dev) -{ - const struct uart_ns16550_device_config * const dev_cfg = DEV_CFG(dev); - u32_t pcp = dev_cfg->pcp; - - if (pcp) { - pcp |= PCP_EN; - OUTWORD(PCP(dev), pcp & ~PCP_UPDATE); - OUTWORD(PCP(dev), pcp | PCP_UPDATE); - } -} -#endif - static void set_baud_rate(struct device *dev, u32_t baud_rate) { const struct uart_ns16550_device_config * const dev_cfg = DEV_CFG(dev); @@ -307,36 +310,6 @@ static void set_baud_rate(struct device *dev, u32_t baud_rate) } } -#if defined(CONFIG_UART_NS16550_PCI) -static inline int ns16550_pci_uart_scan(struct device *dev) -{ - struct uart_ns16550_dev_data_t * const dev_data = DEV_DATA(dev); - - if (dev_data->pci_dev.vendor_id == 0x0000) { - return -EINVAL; - } - - pci_bus_scan_init(); - - if (!pci_bus_scan(&dev_data->pci_dev)) { - return 0; - } - -#ifdef CONFIG_PCI_ENUMERATION - dev_data->port = dev_data->pci_dev.addr; -#endif - - pci_enable_regs(&dev_data->pci_dev); - - return 1; -} - -#else - -#define ns16550_pci_uart_scan(_unused_) (1) - -#endif /* CONFIG_UART_NS16550_PCI */ - /** * @brief Initialize individual UART port * @@ -349,14 +322,23 @@ static inline int ns16550_pci_uart_scan(struct device *dev) static int uart_ns16550_init(struct device *dev) { struct uart_ns16550_dev_data_t * const dev_data = DEV_DATA(dev); + const struct uart_ns16550_device_config * const dev_cfg = DEV_CFG(dev); unsigned int old_level; /* old interrupt lock level */ u8_t mdc = 0U; - if (!ns16550_pci_uart_scan(dev)) { - dev->driver_api = NULL; - return -ENOTSUP; + ARG_UNUSED(dev_cfg); + +#ifdef UART_NS16550_PCIE_ENABLED + if (dev_cfg->pcie) { + if (!pcie_probe(dev_cfg->pcie_bdf, dev_cfg->pcie_id)) { + return -EINVAL; + } + + dev_data->port = pcie_get_mbar(dev_cfg->pcie_bdf, 0); + pcie_set_cmd(dev_cfg->pcie_bdf, PCIE_CONF_CMDSTAT_MEM, true); } +#endif #ifdef CONFIG_UART_INTERRUPT_DRIVEN dev_data->iir_cache = 0U; @@ -364,12 +346,18 @@ static int uart_ns16550_init(struct device *dev) old_level = irq_lock(); -#ifdef CONFIG_UART_NS16550_DLF - set_dlf(dev, dev_data->dlf); +#ifdef UART_NS16550_DLF_ENABLED + OUTBYTE(DLF(dev), dev_data->dlf); #endif -#ifdef CONFIG_UART_NS16550_PCP - set_pcp(dev); +#ifdef UART_NS16550_PCP_ENABLED + u32_t pcp = dev_cfg->pcp; + + if (pcp) { + pcp |= PCP_EN; + OUTWORD(PCP(dev), pcp & ~PCP_UPDATE); + OUTWORD(PCP(dev), pcp | PCP_UPDATE); + } #endif set_baud_rate(dev, dev_data->baud_rate); @@ -738,11 +726,16 @@ static int uart_ns16550_line_ctrl_set(struct device *dev, */ static int uart_ns16550_drv_cmd(struct device *dev, u32_t cmd, u32_t p) { + struct uart_ns16550_dev_data_t * const dev_data = DEV_DATA(dev); + + ARG_UNUSED(dev_data); + switch (cmd) { -#ifdef CONFIG_UART_NS16550_DLF +#ifdef UART_NS16550_DLF_ENABLED case CMD_SET_DLF: - set_dlf(dev, p); + dev_data->dlf = p; + OUTBYTE(DLF(dev), dev_data->dlf); return 0; #endif @@ -799,28 +792,24 @@ static const struct uart_ns16550_device_config uart_ns16550_dev_cfg_0 = { .irq_config_func = irq_config_func_0, #endif -#ifdef CONFIG_UART_NS16550_PORT_0_PCP - .pcp = CONFIG_UART_NS16550_PORT_0_PCP +#ifdef DT_UART_NS16550_PORT_0_PCP + .pcp = DT_UART_NS16550_PORT_0_PCP, +#endif + +#if DT_UART_NS16550_PORT_0_PCIE + .pcie = true, + .pcie_bdf = DT_UART_NS16550_PORT_0_BASE_ADDR, + .pcie_id = DT_UART_NS16550_PORT_0_SIZE, #endif }; static struct uart_ns16550_dev_data_t uart_ns16550_dev_data_0 = { -#ifdef CONFIG_UART_NS16550_PORT_0_PCI - .pci_dev.class_type = UART_NS16550_PORT_0_PCI_CLASS, - .pci_dev.bus = UART_NS16550_PORT_0_PCI_BUS, - .pci_dev.dev = UART_NS16550_PORT_0_PCI_DEV, - .pci_dev.vendor_id = UART_NS16550_PORT_0_PCI_VENDOR_ID, - .pci_dev.device_id = UART_NS16550_PORT_0_PCI_DEVICE_ID, - .pci_dev.function = UART_NS16550_PORT_0_PCI_FUNC, - .pci_dev.bar = UART_NS16550_PORT_0_PCI_BAR, -#endif /* CONFIG_UART_NS16550_PORT_0_PCI */ - .port = DT_UART_NS16550_PORT_0_BASE_ADDR, .baud_rate = DT_UART_NS16550_PORT_0_BAUD_RATE, .options = CONFIG_UART_NS16550_PORT_0_OPTIONS, -#ifdef CONFIG_UART_NS16550_PORT_0_DLF - .dlf = CONFIG_UART_NS16550_PORT_0_DLF, +#ifdef DT_UART_NS16550_PORT_0_DLF + .dlf = DT_UART_NS16550_PORT_0_DLF, #endif }; @@ -839,6 +828,12 @@ static void irq_config_func_0(struct device *dev) uart_ns16550_isr, DEVICE_GET(uart_ns16550_0), DT_UART_NS16550_PORT_0_IRQ_FLAGS); irq_enable(DT_UART_NS16550_PORT_0_IRQ); +#if defined(UART_NS16550_PCIE_ENABLED) && CONFIG_PCIE_MSI + if (DEV_CFG(dev)->pcie) { + pcie_set_msi(DT_UART_NS16550_PORT_0_BASE_ADDR, + DT_UART_NS16550_PORT_0_IRQ); + } +#endif } #endif @@ -857,28 +852,24 @@ static const struct uart_ns16550_device_config uart_ns16550_dev_cfg_1 = { .irq_config_func = irq_config_func_1, #endif -#ifdef CONFIG_UART_NS16550_PORT_1_PCP - .pcp = CONFIG_UART_NS16550_PORT_1_PCP +#ifdef DT_UART_NS16550_PORT_1_PCP + .pcp = DT_UART_NS16550_PORT_1_PCP, +#endif + +#if DT_UART_NS16550_PORT_1_PCIE + .pcie = true, + .pcie_bdf = DT_UART_NS16550_PORT_1_BASE_ADDR, + .pcie_id = DT_UART_NS16550_PORT_1_SIZE, #endif }; static struct uart_ns16550_dev_data_t uart_ns16550_dev_data_1 = { -#ifdef CONFIG_UART_NS16550_PORT_1_PCI - .pci_dev.class_type = UART_NS16550_PORT_1_PCI_CLASS, - .pci_dev.bus = UART_NS16550_PORT_1_PCI_BUS, - .pci_dev.dev = UART_NS16550_PORT_1_PCI_DEV, - .pci_dev.vendor_id = UART_NS16550_PORT_1_PCI_VENDOR_ID, - .pci_dev.device_id = UART_NS16550_PORT_1_PCI_DEVICE_ID, - .pci_dev.function = UART_NS16550_PORT_1_PCI_FUNC, - .pci_dev.bar = UART_NS16550_PORT_1_PCI_BAR, -#endif /* CONFIG_UART_NS16550_PORT_1_PCI */ - .port = DT_UART_NS16550_PORT_1_BASE_ADDR, .baud_rate = DT_UART_NS16550_PORT_1_BAUD_RATE, .options = CONFIG_UART_NS16550_PORT_1_OPTIONS, -#ifdef CONFIG_UART_NS16550_PORT_1_DLF - .dlf = CONFIG_UART_NS16550_PORT_1_DLF, +#ifdef DT_UART_NS16550_PORT_1_DLF + .dlf = DT_UART_NS16550_PORT_1_DLF, #endif }; @@ -897,6 +888,12 @@ static void irq_config_func_1(struct device *dev) uart_ns16550_isr, DEVICE_GET(uart_ns16550_1), DT_UART_NS16550_PORT_1_IRQ_FLAGS); irq_enable(DT_UART_NS16550_PORT_1_IRQ); +#if defined(UART_NS16550_PCIE_ENABLED) && CONFIG_PCIE_MSI + if (DEV_CFG(dev)->pcie) { + pcie_set_msi(DT_UART_NS16550_PORT_1_BASE_ADDR, + DT_UART_NS16550_PORT_1_IRQ); + } +#endif } #endif @@ -915,28 +912,24 @@ static const struct uart_ns16550_device_config uart_ns16550_dev_cfg_2 = { .irq_config_func = irq_config_func_2, #endif -#ifdef CONFIG_UART_NS16550_PORT_2_PCP - .pcp = CONFIG_UART_NS16550_PORT_2_PCP +#ifdef DT_UART_NS16550_PORT_2_PCP + .pcp = DT_UART_NS16550_PORT_2_PCP, +#endif + +#if DT_UART_NS16550_PORT_2_PCIE + .pcie = true, + .pcie_bdf = DT_UART_NS16550_PORT_2_BASE_ADDR, + .pcie_id = DT_UART_NS16550_PORT_2_SIZE, #endif }; static struct uart_ns16550_dev_data_t uart_ns16550_dev_data_2 = { -#ifdef CONFIG_UART_NS16550_PORT_2_PCI - .pci_dev.class_type = UART_NS16550_PORT_2_PCI_CLASS, - .pci_dev.bus = UART_NS16550_PORT_2_PCI_BUS, - .pci_dev.dev = UART_NS16550_PORT_2_PCI_DEV, - .pci_dev.vendor_id = UART_NS16550_PORT_2_PCI_VENDOR_ID, - .pci_dev.device_id = UART_NS16550_PORT_2_PCI_DEVICE_ID, - .pci_dev.function = UART_NS16550_PORT_2_PCI_FUNC, - .pci_dev.bar = UART_NS16550_PORT_2_PCI_BAR, -#endif /* CONFIG_UART_NS16550_PORT_2_PCI */ - .port = DT_UART_NS16550_PORT_2_BASE_ADDR, .baud_rate = DT_UART_NS16550_PORT_2_BAUD_RATE, .options = CONFIG_UART_NS16550_PORT_2_OPTIONS, -#ifdef CONFIG_UART_NS16550_PORT_2_DLF - .dlf = CONFIG_UART_NS16550_PORT_2_DLF, +#ifdef DT_UART_NS16550_PORT_2_DLF + .dlf = DT_UART_NS16550_PORT_2_DLF, #endif }; @@ -954,7 +947,14 @@ static void irq_config_func_2(struct device *dev) DT_UART_NS16550_PORT_2_IRQ_PRI, uart_ns16550_isr, DEVICE_GET(uart_ns16550_2), DT_UART_NS16550_PORT_2_IRQ_FLAGS); + irq_enable(DT_UART_NS16550_PORT_2_IRQ); +#if defined(UART_NS16550_PCIE_ENABLED) && CONFIG_PCIE_MSI + if (DEV_CFG(dev)->pcie) { + pcie_set_msi(DT_UART_NS16550_PORT_2_BASE_ADDR, + DT_UART_NS16550_PORT_2_IRQ); + } +#endif } #endif @@ -973,28 +973,24 @@ static const struct uart_ns16550_device_config uart_ns16550_dev_cfg_3 = { .irq_config_func = irq_config_func_3, #endif -#ifdef CONFIG_UART_NS16550_PORT_3_PCP - .pcp = CONFIG_UART_NS16550_PORT_3_PCP +#ifdef DT_UART_NS16550_PORT_3_PCP + .pcp = DT_UART_NS16550_PORT_3_PCP, +#endif + +#if DT_UART_NS16550_PORT_3_PCIE + .pcie = true, + .pcie_bdf = DT_UART_NS16550_PORT_3_BASE_ADDR, + .pcie_id = DT_UART_NS16550_PORT_3_SIZE, #endif }; static struct uart_ns16550_dev_data_t uart_ns16550_dev_data_3 = { -#ifdef CONFIG_UART_NS16550_PORT_3_PCI - .pci_dev.class_type = UART_NS16550_PORT_3_PCI_CLASS, - .pci_dev.bus = UART_NS16550_PORT_3_PCI_BUS, - .pci_dev.dev = UART_NS16550_PORT_3_PCI_DEV, - .pci_dev.vendor_id = UART_NS16550_PORT_3_PCI_VENDOR_ID, - .pci_dev.device_id = UART_NS16550_PORT_3_PCI_DEVICE_ID, - .pci_dev.function = UART_NS16550_PORT_3_PCI_FUNC, - .pci_dev.bar = UART_NS16550_PORT_3_PCI_BAR, -#endif /* CONFIG_UART_NS16550_PORT_3_PCI */ - .port = DT_UART_NS16550_PORT_3_BASE_ADDR, .baud_rate = DT_UART_NS16550_PORT_3_BAUD_RATE, .options = CONFIG_UART_NS16550_PORT_3_OPTIONS, -#ifdef CONFIG_UART_NS16550_PORT_3_DLF - .dlf = CONFIG_UART_NS16550_PORT_3_DLF, +#ifdef DT_UART_NS16550_PORT_3_DLF + .dlf = DT_UART_NS16550_PORT_3_DLF, #endif }; @@ -1013,6 +1009,12 @@ static void irq_config_func_3(struct device *dev) uart_ns16550_isr, DEVICE_GET(uart_ns16550_3), DT_UART_NS16550_PORT_3_IRQ_FLAGS); irq_enable(DT_UART_NS16550_PORT_3_IRQ); +#if defined(UART_NS16550_PCIE_ENABLED) && CONFIG_PCIE_MSI + if (DEV_CFG(dev)->pcie) { + pcie_set_msi(DT_UART_NS16550_PORT_3_BASE_ADDR, + DT_UART_NS16550_PORT_3_IRQ); + } +#endif } #endif diff --git a/dts/arc/arc_iot.dtsi b/dts/arc/arc_iot.dtsi index a891938b6b5..b9390400cec 100644 --- a/dts/arc/arc_iot.dtsi +++ b/dts/arc/arc_iot.dtsi @@ -65,6 +65,7 @@ label = "UART_0"; interrupts = <86 0>; interrupt-parent = <&intc>; + dlf = <0x01>; }; uart1: uart@80014100 { diff --git a/dts/bindings/serial/ns16550.yaml b/dts/bindings/serial/ns16550.yaml index cce1bd33184..81dd39f2d4c 100644 --- a/dts/bindings/serial/ns16550.yaml +++ b/dts/bindings/serial/ns16550.yaml @@ -29,4 +29,22 @@ properties: category: required description: required interrupts generation: define + + pcp: + type: int + category: optional + description: custom clock (PRV_CLOCK_PARAMS, if supported) + generation: define + + dlf: + type: int + category: optional + description: divisor latch fraction (DLF, if supported) + generation: define + + pcie: + type: boolean + category: optional + description: attached via PCI(e) bus + generation: define ... diff --git a/dts/x86/quark_x1000.dtsi b/dts/x86/quark_x1000.dtsi index 33ad72e3fd9..acf6639de91 100644 --- a/dts/x86/quark_x1000.dtsi +++ b/dts/x86/quark_x1000.dtsi @@ -7,6 +7,7 @@ #include "skeleton.dtsi" #include #include +#include / { cpus { @@ -46,9 +47,9 @@ ranges; - uart0: uart@9000f000 { + uart0: uart@0 { compatible = "ns16550"; - reg = <0x9000f000 0x400>; + pcie; reg = ; label = "UART_0"; clock-frequency = <44236800>; interrupts = <0 IRQ_TYPE_LEVEL_LOW 0>; @@ -57,9 +58,9 @@ status = "disabled"; }; - uart1: uart@9000b000 { + uart1: uart@1 { compatible = "ns16550"; - reg = <0x9000b000 0x400>; + pcie; reg = ; label = "UART_1"; clock-frequency = <44236800>; interrupts = <17 IRQ_TYPE_LEVEL_LOW 3>; diff --git a/include/drivers/pcie/msi.h b/include/drivers/pcie/msi.h new file mode 100644 index 00000000000..4be2db081a5 --- /dev/null +++ b/include/drivers/pcie/msi.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2019 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_PCIE_MSI_H_ +#define ZEPHYR_INCLUDE_DRIVERS_PCIE_MSI_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Find a PCI(e) capability in an endpoint's configuration space. + * + * @param bdf the PCI endpoint to examine + * @param cap_id the capability ID of interest + * @return the index of the configuration word, or 0 if no capability. + * + * Note: PCI(e) capabilities are only used in the MSI code, so for + * now, capabilities-related code is only included when MSI is. It + * can easily be separated out if/when its use spreads. + */ +extern u32_t pcie_get_cap(pcie_bdf_t bdf, u32_t cap_id); + +/* + * Configuration word 13 contains the head of the capabilities list. + */ + +#define PCIE_CONF_CAPPTR 13U /* capabilities pointer */ +#define PCIE_CONF_CAPPTR_FIRST(w) (((w) >> 2) & 0x3FU) + +/* + * The first word of every capability contains a capability identifier, + * and a link to the next capability (or 0) in configuration space. + */ + +#define PCIE_CONF_CAP_ID(w) ((w) & 0xFFU) +#define PCIE_CONF_CAP_NEXT(w) (((w) >> 10) & 0x3FU) + +/** + * @brief Compute the target address for an MSI posted write. + * + * This function is exported by the arch, board or SoC code. + * + * @param irq The IRQ we wish to trigger via MSI. + * @return A (32-bit) value for the MSI MAP register. + */ +extern u32_t pcie_msi_map(unsigned int irq); + +/** + * @brief Compute the data for an MSI posted write. + * + * This function is exported by the arch, board or SoC code. + * + * @param irq The IRQ we wish to trigger via MSI. + * @return A (16-bit) value for MSI MDR register. + */ +extern u16_t pcie_msi_mdr(unsigned int irq); + +/** + * @brief Configure the given PCI endpoint to generate MSIs. + * + * @param bdf the target PCI endpoint + * @param irq the IRQ which should be generated + * @return true if the endpoint supports MSI, false otherwise. + */ +extern bool pcie_set_msi(pcie_bdf_t bdf, unsigned int irq); + +/* + * MSI capability ID in the PCI configuration capability list. + */ + +#define PCIE_MSI_CAP_ID 05U + +/* + * The first word of the MSI capability is shared with the + * capability ID and list link. The high 16 bits are the MCR. + */ + +#define PCIE_MSI_MCR 0U + +#define PCIE_MSI_MCR_EN 0x00010000U /* enable MSI */ +#define PCIE_MSI_MCR_MME 0x00700000U /* mask of # of enabled IRQs */ +#define PCIE_MSI_MCR_64 0x00800000U /* 64-bit MSI */ + +/* + * The MAP follows the MCR. If PCIE_MSI_MCR_64, then the MAP + * is two words long. The MDR follows immediately after the MAP. + */ + +#define PCIE_MSI_MAP0 1U +#define PCIE_MSI_MAP1_64 2U +#define PCIE_MSI_MDR_32 2U +#define PCIE_MSI_MDR_64 3U + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_PCIE_MSI_H_ */ diff --git a/include/drivers/pcie/pcie.h b/include/drivers/pcie/pcie.h new file mode 100644 index 00000000000..56a739fe575 --- /dev/null +++ b/include/drivers/pcie/pcie.h @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2019 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_PCIE_PCIE_H_ +#define ZEPHYR_INCLUDE_DRIVERS_PCIE_PCIE_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @typedef pcie_bdf_t + * @brief A unique PCI(e) endpoint (bus, device, function). + * + * A PCI(e) endpoint is uniquely identified topologically using a + * (bus, device, function) tuple. The internal structure is documented + * in include/dt-bindings/pcie/pcie.h: see PCIE_BDF() and friends, since + * these tuples are referenced from devicetree. + */ +typedef u32_t pcie_bdf_t; + +/** + * @typedef pcie_id_t + * @brief A unique PCI(e) identifier (vendor ID, device ID). + * + * The PCIE_CONF_ID register for each endpoint is a (vendor ID, device ID) + * pair, which is meant to tell the system what the PCI(e) endpoint is. Again, + * look to PCIE_ID_* macros in include/dt-bindings/pcie/pcie.h for more. + */ +typedef u32_t pcie_id_t; + +/* + * These functions are arch-, board-, or SoC-specific. + */ + +/** + * @brief Read a 32-bit word from an endpoint's configuration space. + * + * This function is exported by the arch/SoC/board code. + * + * @param bdf PCI(e) endpoint + * @param reg the configuration word index (not address) + * @return the word read (0xFFFFFFFFU if nonexistent endpoint or word) + */ +extern u32_t pcie_conf_read(pcie_bdf_t bdf, unsigned int reg); + +/** + * @brief Write a 32-bit word to an endpoint's configuration space. + * + * This function is exported by the arch/SoC/board code. + * + * @param bdf PCI(e) endpoint + * @param reg the configuration word index (not address) + * @param data the value to write + */ +extern void pcie_conf_write(pcie_bdf_t bdf, unsigned int reg, u32_t data); + +/** + * @brief Probe for the presence of a PCI(e) endpoint. + * + * @param bdf the endpoint to probe + * @param id the endpoint ID to expect, or PCI_ID_ANY for "any device" + * @return true if the device is present, false otherwise + */ +extern bool pcie_probe(pcie_bdf_t bdf, pcie_id_t id); + +/** + * @brief Get the nth MMIO address assigned to an endpoint. + * @param bdf the PCI(e) endpoint + * @param index (0-based) index + * @return the (32-bit) address, or PCI_CONF_BAR_NONE if nonexistent. + * + * A PCI(e) endpoint has 0 or more memory-mapped regions. This function + * allows the caller to enumerate them by calling with index=0..n. If + * PCI_CONF_BAR_NONE is returned, there are no further regions. The indices + * are order-preserving with respect to the endpoint BARs: e.g., index 0 + * will return the lowest-numbered memory BAR on the endpoint. + */ +extern u32_t pcie_get_mbar(pcie_bdf_t bdf, unsigned int index); + +/** + * @brief Get the nth I/O address assigned to an endpoint. + * @param bdf the PCI(e) endpoint + * @param index (0-based) index + * @return the (32-bit) address, or PCI_CONF_BAR_NONE if nonexistent. + * + * Analogous to pcie_get_mbar(), except returns I/O region data. + */ +extern u32_t pcie_get_iobar(pcie_bdf_t bdf, unsigned int index); + +/** + * @brief Set or reset bits in the endpoint command/status register. + * + * @param bdf the PCI(e) endpoint + * @param bits the powerset of bits of interest + * @param on use true to set bits, false to reset them + */ +extern void pcie_set_cmd(pcie_bdf_t bdf, u32_t bits, bool on); + +/* + * Configuration word 0 aligns directly with pcie_id_t. + */ + +#define PCIE_CONF_ID 0U + +/* + * Configuration word 1 contains command and status bits. + */ + +#define PCIE_CONF_CMDSTAT 1U /* command/status register */ + +#define PCIE_CONF_CMDSTAT_IO 0x00000001U /* I/O access enable */ +#define PCIE_CONF_CMDSTAT_MEM 0x00000002U /* mem access enable */ +#define PCIE_CONF_CMDSTAT_MASTER 0x00000004U /* bus master enable */ +#define PCIE_CONF_CMDSTAT_CAPS 0x00100000U /* capabilities list */ + +/* + * Configuration word 2 has additional function identification that + * we only care about for debug output (PCIe shell commands). + */ + +#define PCIE_CONF_CLASSREV 2U /* class/revision register */ + +#define PCIE_CONF_CLASSREV_CLASS(w) (((w) >> 24) & 0xFFU) +#define PCIE_CONF_CLASSREV_SUBCLASS(w) (((w) >> 16) & 0xFFU) +#define PCIE_CONF_CLASSREV_PROGIF(w) (((w) >> 8) & 0xFFU) +#define PCIE_CONF_CLASSREV_REV(w) ((w) & 0xFFU) + +/* + * The only part of configuration word 3 that is of interest to us is + * the header type, as we use it to distinguish functional endpoints + * from bridges (which are, for our purposes, transparent). + */ + +#define PCIE_CONF_TYPE 3U + +#define PCIE_CONF_TYPE_BRIDGE(w) (((w) & 0x007F0000U) != 0U) + +/* + * Words 4-9 are BARs are I/O or memory decoders. Memory decoders may + * be 64-bit decoders, in which case the next configuration word holds + * the high-order bits (and is, thus, not a BAR itself). + */ + +#define PCIE_CONF_BAR0 4U +#define PCIE_CONF_BAR1 5U +#define PCIE_CONF_BAR2 6U +#define PCIE_CONF_BAR3 7U +#define PCIE_CONF_BAR4 8U +#define PCIE_CONF_BAR5 9U + +#define PCIE_CONF_BAR_IO(w) (((w) & 0x00000001U) == 0x00000001U) +#define PCIE_CONF_BAR_MEM(w) (((w) & 0x00000001U) != 0x00000001U) +#define PCIE_CONF_BAR_64(w) (((w) & 0x00000006U) == 0x00000004U) +#define PCIE_CONF_BAR_ADDR(w) ((w) & 0xFFFFFFF0U) +#define PCIE_CONF_BAR_NONE 0U + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_DRIVERS_PCIE_PCIE_H_ */ diff --git a/include/dt-bindings/pcie/pcie.h b/include/dt-bindings/pcie/pcie.h new file mode 100644 index 00000000000..0930469f749 --- /dev/null +++ b/include/dt-bindings/pcie/pcie.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2019 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PCIE_PCIE_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PCIE_PCIE_H_ + +/* + * We represent a PCI device ID as [31:16] device ID, [15:0] vendor ID. Not + * coincidentally, this is same representation used in PCI configuration space. + */ + +#define PCIE_ID_VEND_SHIFT 0U +#define PCIE_ID_VEND_MASK 0xFFFFU +#define PCIE_ID_DEV_SHIFT 16U +#define PCIE_ID_DEV_MASK 0xFFFFU + +#define PCIE_ID(vend, dev) \ + ((((vend) & PCIE_ID_VEND_MASK) << PCIE_ID_VEND_SHIFT) | \ + (((dev) & PCIE_ID_DEV_MASK) << PCIE_ID_DEV_SHIFT)) + +#define PCIE_ID_TO_VEND(id) (((id) >> PCIE_ID_VEND_SHIFT) & PCIE_ID_VEND_MASK) +#define PCIE_ID_TO_DEV(id) (((id) >> PCIE_ID_DEV_SHIFT) & PCIE_ID_DEV_MASK) + +#define PCIE_ID_NONE PCIE_ID(0xFFFF, 0xFFFF) + +/* + * Since our internal representation of bus/device/function is arbitrary, + * we choose the same format employed in the x86 Configuration Address Port: + * + * [23:16] bus number, [15:11] device number, [10:8] function number + * + * All other bits must be zero. + * + * The x86 (the only arch, at present, that supports PCI) takes advantage + * of this shared format to avoid unnecessary layers of abstraction. + */ + +#define PCIE_BDF_BUS_SHIFT 16U +#define PCIE_BDF_BUS_MASK 0xFFU +#define PCIE_BDF_DEV_SHIFT 11U +#define PCIE_BDF_DEV_MASK 0x1FU +#define PCIE_BDF_FUNC_SHIFT 8U +#define PCIE_BDF_FUNC_MASK 0x7U + +#define PCIE_BDF(bus, dev, func) \ + ((((bus) & PCIE_BDF_BUS_MASK) << PCIE_BDF_BUS_SHIFT) | \ + (((dev) & PCIE_BDF_DEV_MASK) << PCIE_BDF_DEV_SHIFT) | \ + (((func) & PCIE_BDF_FUNC_MASK) << PCIE_BDF_FUNC_SHIFT)) + +#define PCIE_BDF_TO_BUS(bdf) (((bdf) >> PCIE_BDF_BUS_SHIFT) & PCIE_BDF_BUS_MASK) +#define PCIE_BDF_TO_DEV(bdf) (((bdf) >> PCIE_BDF_DEV_SHIFT) & PCIE_BDF_DEV_MASK) + +#define PCIE_BDF_TO_FUNC(bdf) \ + (((bdf) >> PCIE_BDF_FUNC_SHIFT) & PCIE_BDF_FUNC_MASK) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PCIE_PCIE_H_ */ diff --git a/soc/arc/snps_arc_iot/Kconfig.defconfig b/soc/arc/snps_arc_iot/Kconfig.defconfig index ebbd9dabb6b..8c657e681d5 100644 --- a/soc/arc/snps_arc_iot/Kconfig.defconfig +++ b/soc/arc/snps_arc_iot/Kconfig.defconfig @@ -37,9 +37,6 @@ if SERIAL config UART_NS16550 def_bool y -config UART_NS16550_DLF - def_bool y - endif # SERIAL if UART_CONSOLE @@ -47,9 +44,6 @@ if UART_CONSOLE config UART_NS16550_PORT_0 def_bool y -config UART_NS16550_PORT_0_DLF - default 1 - endif # UART_CONSOLE endif #ARC_IOT diff --git a/soc/arc/snps_arc_iot/dts_fixup.h b/soc/arc/snps_arc_iot/dts_fixup.h index def132ed948..2b4f72ee3ff 100644 --- a/soc/arc/snps_arc_iot/dts_fixup.h +++ b/soc/arc/snps_arc_iot/dts_fixup.h @@ -23,6 +23,10 @@ #define DT_UART_NS16550_PORT_0_NAME DT_NS16550_80014000_LABEL #define DT_UART_NS16550_PORT_0_IRQ_PRI DT_NS16550_80014000_IRQ_0_PRIORITY +#ifdef DT_NS16550_80014000_DLF +#define DT_UART_NS16550_PORT_0_DLF DT_NS16550_80014000_DLF +#endif + #define DT_UART_NS16550_PORT_1_BASE_ADDR DT_NS16550_80014100_BASE_ADDRESS #define DT_UART_NS16550_PORT_1_IRQ DT_NS16550_80014100_IRQ_0 #define DT_UART_NS16550_PORT_1_CLK_FREQ DT_NS16550_80014100_CLOCK_FREQUENCY @@ -30,6 +34,10 @@ #define DT_UART_NS16550_PORT_1_NAME DT_NS16550_80014100_LABEL #define DT_UART_NS16550_PORT_1_IRQ_PRI DT_NS16550_80014100_IRQ_0_PRIORITY +#ifdef DT_NS16550_80014100_DLF +#define DT_UART_NS16550_PORT_1_DLF DT_NS16550_80014100_DLF +#endif + #define DT_UART_NS16550_PORT_2_BASE_ADDR DT_NS16550_80014200_BASE_ADDRESS #define DT_UART_NS16550_PORT_2_IRQ DT_NS16550_80014200_IRQ_0 #define DT_UART_NS16550_PORT_2_CLK_FREQ DT_NS16550_80014200_CLOCK_FREQUENCY @@ -37,6 +45,9 @@ #define DT_UART_NS16550_PORT_2_NAME DT_NS16550_80014200_LABEL #define DT_UART_NS16550_PORT_2_IRQ_PRI DT_NS16550_80014200_IRQ_0_PRIORITY +#ifdef DT_NS16550_80014200_DLF +#define DT_UART_NS16550_PORT_2_DLF DT_NS16550_80014200_DLF +#endif #define DT_UART_NS16550_PORT_3_BASE_ADDR DT_NS16550_80014300_BASE_ADDRESS #define DT_UART_NS16550_PORT_3_IRQ DT_NS16550_80014300_IRQ_0 @@ -45,5 +56,8 @@ #define DT_UART_NS16550_PORT_3_NAME DT_NS16550_80014300_LABEL #define DT_UART_NS16550_PORT_3_IRQ_PRI DT_NS16550_80014300_IRQ_0_PRIORITY +#ifdef DT_NS16550_80014300_DLF +#define DT_UART_NS16550_PORT_3_DLF DT_NS16550_80014300_DLF +#endif /* End of SoC Level DTS fixup file */ diff --git a/soc/nios2/nios2f-zephyr/Kconfig.defconfig b/soc/nios2/nios2f-zephyr/Kconfig.defconfig index a729ac3c129..0e3cabb22b2 100644 --- a/soc/nios2/nios2f-zephyr/Kconfig.defconfig +++ b/soc/nios2/nios2f-zephyr/Kconfig.defconfig @@ -43,9 +43,6 @@ endif # DMA_NIOS2_MSGDMA if UART_NS16550 -config UART_NS16550_PCI - default n - config UART_NS16550_PORT_0 default y diff --git a/soc/x86/apollo_lake/Kconfig.defconfig b/soc/x86/apollo_lake/Kconfig.defconfig index bf4c6502cd3..c99b72651be 100644 --- a/soc/x86/apollo_lake/Kconfig.defconfig +++ b/soc/x86/apollo_lake/Kconfig.defconfig @@ -21,9 +21,6 @@ config CLFLUSH_DETECT if UART_NS16550 -config UART_NS16550_PCI - default y if PCI - config UART_NS16550_PORT_0 default y @@ -32,9 +29,6 @@ if UART_NS16550_PORT_0 config UART_NS16550_PORT_0_OPTIONS default 0 -config UART_NS16550_PORT_0_PCI - default y if PCI - endif # UART_NS16550_PORT_0 config UART_NS16550_PORT_1 @@ -45,9 +39,6 @@ if UART_NS16550_PORT_1 config UART_NS16550_PORT_1_OPTIONS default 0 -config UART_NS16550_PORT_1_PCI - default y if PCI - endif # UART_NS16550_PORT_1 if UART_NS16550_PORT_2 @@ -55,9 +46,6 @@ if UART_NS16550_PORT_2 config UART_NS16550_PORT_2_OPTIONS default 0 -config UART_NS16550_PORT_2_PCI - default y if PCI - endif # UART_NS16550_PORT_2 if UART_NS16550_PORT_3 @@ -65,9 +53,6 @@ if UART_NS16550_PORT_3 config UART_NS16550_PORT_3_OPTIONS default 0 -config UART_NS16550_PORT_3_PCI - default y if PCI - endif # UART_NS16550_PORT_3 endif # UART_NS16550 diff --git a/soc/x86/apollo_lake/soc.h b/soc/x86/apollo_lake/soc.h index 5efe6f33d0a..b51656c4817 100644 --- a/soc/x86/apollo_lake/soc.h +++ b/soc/x86/apollo_lake/soc.h @@ -45,60 +45,6 @@ */ #define pci_pin2irq(bus, dev, pin) (pin) - -/* UARTs */ -#ifdef CONFIG_UART_NS16550_PCI - -#ifdef CONFIG_UART_NS16550_PORT_0_PCI - -#define UART_NS16550_PORT_0_PCI_CLASS 0x11 -#define UART_NS16550_PORT_0_PCI_BUS 0 -#define UART_NS16550_PORT_0_PCI_DEV 18 -#define UART_NS16550_PORT_0_PCI_VENDOR_ID 0x8086 -#define UART_NS16550_PORT_0_PCI_DEVICE_ID 0x5abc -#define UART_NS16550_PORT_0_PCI_FUNC 0 -#define UART_NS16550_PORT_0_PCI_BAR 0 - -#endif /* CONFIG_UART_NS16550_PORT_0_PCI */ - -#ifdef CONFIG_UART_NS16550_PORT_1_PCI - -#define UART_NS16550_PORT_1_PCI_CLASS 0x11 -#define UART_NS16550_PORT_1_PCI_BUS 0 -#define UART_NS16550_PORT_1_PCI_DEV 18 -#define UART_NS16550_PORT_1_PCI_VENDOR_ID 0x8086 -#define UART_NS16550_PORT_1_PCI_DEVICE_ID 0x5abe -#define UART_NS16550_PORT_1_PCI_FUNC 1 -#define UART_NS16550_PORT_1_PCI_BAR 0 - -#endif /* CONFIG_UART_NS16550_PORT_1_PCI */ - -#ifdef CONFIG_UART_NS16550_PORT_2_PCI - -#define UART_NS16550_PORT_2_PCI_CLASS 0x11 -#define UART_NS16550_PORT_2_PCI_BUS 0 -#define UART_NS16550_PORT_2_PCI_DEV 18 -#define UART_NS16550_PORT_2_PCI_VENDOR_ID 0x8086 -#define UART_NS16550_PORT_2_PCI_DEVICE_ID 0x5ac0 -#define UART_NS16550_PORT_2_PCI_FUNC 2 -#define UART_NS16550_PORT_2_PCI_BAR 0 - -#endif /* CONFIG_UART_NS16550_PORT_2_PCI */ - -#ifdef CONFIG_UART_NS16550_PORT_3_PCI - -#define UART_NS16550_PORT_3_PCI_CLASS 0x11 -#define UART_NS16550_PORT_3_PCI_BUS 0 -#define UART_NS16550_PORT_3_PCI_DEV 18 -#define UART_NS16550_PORT_3_PCI_VENDOR_ID 0x8086 -#define UART_NS16550_PORT_3_PCI_DEVICE_ID 0x5aee -#define UART_NS16550_PORT_3_PCI_FUNC 3 -#define UART_NS16550_PORT_3_PCI_BAR 0 - -#endif /* CONFIG_UART_NS16550_PORT_3_PCI */ - -#endif /* CONFIG_UART_NS16550_PCI */ - /* I2C controllers */ #define I2C_DW_0_PCI_VENDOR_ID 0x8086 #define I2C_DW_0_PCI_DEVICE_ID 0x5aac diff --git a/soc/x86/atom/Kconfig.defconfig b/soc/x86/atom/Kconfig.defconfig index d604b8d0f9c..0c3ab15f97f 100644 --- a/soc/x86/atom/Kconfig.defconfig +++ b/soc/x86/atom/Kconfig.defconfig @@ -20,9 +20,6 @@ config CLFLUSH_DETECT if UART_NS16550 -config UART_NS16550_PCI - default n - config UART_NS16550_PORT_0 default y diff --git a/soc/x86/ia32/Kconfig.defconfig b/soc/x86/ia32/Kconfig.defconfig index 4856c24c2e7..b97608e834f 100644 --- a/soc/x86/ia32/Kconfig.defconfig +++ b/soc/x86/ia32/Kconfig.defconfig @@ -20,9 +20,6 @@ config CLFLUSH_DETECT if UART_NS16550 -config UART_NS16550_PCI - default n - config UART_NS16550_PORT_0 default y diff --git a/soc/x86/intel_quark/quark_x1000/Kconfig.defconfig.series b/soc/x86/intel_quark/quark_x1000/Kconfig.defconfig.series index a3484df78a4..fa06e143b5f 100644 --- a/soc/x86/intel_quark/quark_x1000/Kconfig.defconfig.series +++ b/soc/x86/intel_quark/quark_x1000/Kconfig.defconfig.series @@ -133,9 +133,6 @@ endif # SPI if UART_NS16550 -config UART_NS16550_PCI - default y if PCI - config UART_NS16550_PORT_0 default y @@ -144,9 +141,6 @@ if UART_NS16550_PORT_0 config UART_NS16550_PORT_0_OPTIONS default 0 -config UART_NS16550_PORT_0_PCI - default y if UART_NS16550_PCI - endif # UART_NS16550_PORT_0 config UART_NS16550_PORT_1 @@ -157,9 +151,6 @@ if UART_NS16550_PORT_1 config UART_NS16550_PORT_1_OPTIONS default 0 -config UART_NS16550_PORT_1_PCI - default y if UART_NS16550_PCI - endif # UART_NS16550_PORT_1 endif # UART_NS16550 diff --git a/soc/x86/intel_quark/quark_x1000/dts_fixup.h b/soc/x86/intel_quark/quark_x1000/dts_fixup.h index b6b153a117a..dd6feeadb2b 100644 --- a/soc/x86/intel_quark/quark_x1000/dts_fixup.h +++ b/soc/x86/intel_quark/quark_x1000/dts_fixup.h @@ -1,20 +1,24 @@ /* SPDX-License-Identifier: Apache-2.0 */ -#define DT_UART_NS16550_PORT_0_BASE_ADDR DT_NS16550_9000F000_BASE_ADDRESS -#define DT_UART_NS16550_PORT_0_BAUD_RATE DT_NS16550_9000F000_CURRENT_SPEED -#define DT_UART_NS16550_PORT_0_NAME DT_NS16550_9000F000_LABEL -#define DT_UART_NS16550_PORT_0_IRQ DT_NS16550_9000F000_IRQ_0 -#define DT_UART_NS16550_PORT_0_IRQ_PRI DT_NS16550_9000F000_IRQ_0_PRIORITY -#define DT_UART_NS16550_PORT_0_IRQ_FLAGS DT_NS16550_9000F000_IRQ_0_SENSE -#define DT_UART_NS16550_PORT_0_CLK_FREQ DT_NS16550_9000F000_CLOCK_FREQUENCY +#define DT_UART_NS16550_PORT_0_BASE_ADDR DT_NS16550_0_BASE_ADDRESS +#define DT_UART_NS16550_PORT_0_SIZE DT_NS16550_0_SIZE +#define DT_UART_NS16550_PORT_0_BAUD_RATE DT_NS16550_0_CURRENT_SPEED +#define DT_UART_NS16550_PORT_0_NAME DT_NS16550_0_LABEL +#define DT_UART_NS16550_PORT_0_IRQ DT_NS16550_0_IRQ_0 +#define DT_UART_NS16550_PORT_0_IRQ_PRI DT_NS16550_0_IRQ_0_PRIORITY +#define DT_UART_NS16550_PORT_0_IRQ_FLAGS DT_NS16550_0_IRQ_0_SENSE +#define DT_UART_NS16550_PORT_0_CLK_FREQ DT_NS16550_0_CLOCK_FREQUENCY +#define DT_UART_NS16550_PORT_0_PCIE DT_NS16550_0_PCIE -#define DT_UART_NS16550_PORT_1_BASE_ADDR DT_NS16550_9000B000_BASE_ADDRESS -#define DT_UART_NS16550_PORT_1_BAUD_RATE DT_NS16550_9000B000_CURRENT_SPEED -#define DT_UART_NS16550_PORT_1_NAME DT_NS16550_9000B000_LABEL -#define DT_UART_NS16550_PORT_1_IRQ DT_NS16550_9000B000_IRQ_0 -#define DT_UART_NS16550_PORT_1_IRQ_PRI DT_NS16550_9000B000_IRQ_0_PRIORITY -#define DT_UART_NS16550_PORT_1_IRQ_FLAGS DT_NS16550_9000B000_IRQ_0_SENSE -#define DT_UART_NS16550_PORT_1_CLK_FREQ DT_NS16550_9000B000_CLOCK_FREQUENCY +#define DT_UART_NS16550_PORT_1_BASE_ADDR DT_NS16550_1_BASE_ADDRESS +#define DT_UART_NS16550_PORT_1_SIZE DT_NS16550_1_SIZE +#define DT_UART_NS16550_PORT_1_BAUD_RATE DT_NS16550_1_CURRENT_SPEED +#define DT_UART_NS16550_PORT_1_NAME DT_NS16550_1_LABEL +#define DT_UART_NS16550_PORT_1_IRQ DT_NS16550_1_IRQ_0 +#define DT_UART_NS16550_PORT_1_IRQ_PRI DT_NS16550_1_IRQ_0_PRIORITY +#define DT_UART_NS16550_PORT_1_IRQ_FLAGS DT_NS16550_1_IRQ_0_SENSE +#define DT_UART_NS16550_PORT_1_CLK_FREQ DT_NS16550_1_CLOCK_FREQUENCY +#define DT_UART_NS16550_PORT_1_PCIE DT_NS16550_1_PCIE #define DT_PHYS_RAM_ADDR CONFIG_SRAM_BASE_ADDRESS @@ -24,22 +28,22 @@ #define DT_ROM_SIZE CONFIG_FLASH_SIZE -#define DT_IOAPIC_BASE_ADDRESS DT_INTEL_IOAPIC_FEC00000_BASE_ADDRESS +#define DT_IOAPIC_BASE_ADDRESS DT_INTEL_IOAPIC_FEC00000_BASE_ADDRESS -#define DT_SPI_0_BASE_ADDRESS DT_INTEL_INTEL_SPI_90009000_BASE_ADDRESS -#define DT_SPI_0_IRQ DT_INTEL_INTEL_SPI_90009000_IRQ_0 -#define DT_SPI_0_IRQ_FLAGS DT_INTEL_INTEL_SPI_90009000_IRQ_0_SENSE -#define DT_SPI_0_IRQ_PRI DT_INTEL_INTEL_SPI_90009000_IRQ_0_PRIORITY -#define DT_SPI_0_NAME DT_INTEL_INTEL_SPI_90009000_LABEL +#define DT_SPI_0_BASE_ADDRESS DT_INTEL_INTEL_SPI_90009000_BASE_ADDRESS +#define DT_SPI_0_IRQ DT_INTEL_INTEL_SPI_90009000_IRQ_0 +#define DT_SPI_0_IRQ_FLAGS DT_INTEL_INTEL_SPI_90009000_IRQ_0_SENSE +#define DT_SPI_0_IRQ_PRI DT_INTEL_INTEL_SPI_90009000_IRQ_0_PRIORITY +#define DT_SPI_0_NAME DT_INTEL_INTEL_SPI_90009000_LABEL -#define DT_SPI_1_BASE_ADDRESS DT_INTEL_INTEL_SPI_90008000_BASE_ADDRESS -#define DT_SPI_1_IRQ DT_INTEL_INTEL_SPI_90008000_IRQ_0 -#define DT_SPI_1_IRQ_FLAGS DT_INTEL_INTEL_SPI_90008000_IRQ_0_SENSE -#define DT_SPI_1_IRQ_PRI DT_INTEL_INTEL_SPI_90008000_IRQ_0_PRIORITY -#define DT_SPI_1_NAME DT_INTEL_INTEL_SPI_90008000_LABEL +#define DT_SPI_1_BASE_ADDRESS DT_INTEL_INTEL_SPI_90008000_BASE_ADDRESS +#define DT_SPI_1_IRQ DT_INTEL_INTEL_SPI_90008000_IRQ_0 +#define DT_SPI_1_IRQ_FLAGS DT_INTEL_INTEL_SPI_90008000_IRQ_0_SENSE +#define DT_SPI_1_IRQ_PRI DT_INTEL_INTEL_SPI_90008000_IRQ_0_PRIORITY +#define DT_SPI_1_NAME DT_INTEL_INTEL_SPI_90008000_LABEL #ifdef CONFIG_I2C_0 -#define DT_I2C_DW_0_IRQ_SHARED_NAME DT_SHARED_IRQ_SHAREDIRQ0_LABEL +#define DT_I2C_DW_0_IRQ_SHARED_NAME DT_SHARED_IRQ_SHAREDIRQ0_LABEL #endif #ifdef CONFIG_GPIO_DW_0 diff --git a/soc/x86/intel_quark/quark_x1000/soc.h b/soc/x86/intel_quark/quark_x1000/soc.h index 1d4a62bd331..ecf4ea11327 100644 --- a/soc/x86/intel_quark/quark_x1000/soc.h +++ b/soc/x86/intel_quark/quark_x1000/soc.h @@ -97,25 +97,6 @@ #define I2C_DW_0_PCI_FUNCTION 2 #define I2C_DW_0_PCI_BAR 0 -/* - * UART - */ -#define UART_NS16550_PORT_0_PCI_CLASS 0x07 -#define UART_NS16550_PORT_0_PCI_BUS 0 -#define UART_NS16550_PORT_0_PCI_DEV 20 -#define UART_NS16550_PORT_0_PCI_VENDOR_ID 0x8086 -#define UART_NS16550_PORT_0_PCI_DEVICE_ID 0x0936 -#define UART_NS16550_PORT_0_PCI_FUNC 1 -#define UART_NS16550_PORT_0_PCI_BAR 0 - -#define UART_NS16550_PORT_1_PCI_CLASS 0x07 -#define UART_NS16550_PORT_1_PCI_BUS 0 -#define UART_NS16550_PORT_1_PCI_DEV 20 -#define UART_NS16550_PORT_1_PCI_VENDOR_ID 0x8086 -#define UART_NS16550_PORT_1_PCI_DEVICE_ID 0x0936 -#define UART_NS16550_PORT_1_PCI_FUNC 5 -#define UART_NS16550_PORT_1_PCI_BAR 0 - #ifdef CONFIG_IOAPIC #define UART_IRQ_FLAGS (IOAPIC_LEVEL | IOAPIC_LOW) #endif /* CONFIG_IOAPIC */