uart/ns16550, drivers/pcie: add PCI(e) support

A parallel PCI implementation ("pcie") is added with features for PCIe.
In particular, message-signaled interrupts (MSI) are supported, which
are essential to the use of any non-trivial PCIe device.

The NS16550 UART driver is modified to use pcie.

pcie is a complete replacement for the old PCI support ("pci"). It is
smaller, by an order of magnitude, and cleaner. Both pci and pcie can
(and do) coexist in the same builds, but the intent is to rework any
existing drivers that depend on pci and ultimately remove pci entirely.

This patch is large, but things in mirror are smaller than they appear.
Most of the modified files are configuration-related, and are changed
only slightly to accommodate the modified UART driver.

Deficiencies:

64-bit support is minimal. The code works fine with 64-bit capable
devices, but will not cooperate with MMIO regions (or MSI targets) that
have high bits set. This is not needed on any current boards, and is
unlikely to be needed in the future. Only superficial changes would
be required if we change our minds.

The method specifying PCI endpoints in devicetree is somewhat kludgey.
The "right" way would be to hang PCI devices off a topological tree;
while this would be more aesthetically pleasing, I don't think it's
worth the effort, given our non-standard use of devicetree.

Signed-off-by: Charles E. Youse <charles.youse@intel.com>
This commit is contained in:
Charles E. Youse 2019-04-02 10:06:07 -07:00 committed by Andrew Boie
parent 4cf4040af0
commit e039053546
32 changed files with 968 additions and 433 deletions

View file

@ -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

View file

@ -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)

90
arch/x86/core/pcie.c Normal file
View file

@ -0,0 +1,90 @@
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <kernel.h>
#include <drivers/pcie/pcie.h>
#include <arch/x86/arch.h>
#ifdef CONFIG_PCIE_MSI
#include <drivers/pcie/msi.h>
#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

View file

@ -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

View file

@ -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 */

View file

@ -13,6 +13,7 @@
#include <apollo_lake.dtsi>
#include <dt-bindings/i2c/i2c.h>
#include <dt-bindings/pcie/pcie.h>
/ {
model = "up_squared";
@ -29,24 +30,29 @@
};
soc {
uart0: uart@91524000 {
uart0: uart@0 {
compatible = "ns16550";
reg = <0x91524000 0x1000>;
pcie;
reg = <PCIE_BDF(0,0x18,0) PCIE_ID(0x8086,0x5abc)>;
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 = <PCIE_BDF(0,0x18,1) PCIE_ID(0x8086,0x5abe)>;
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";

View file

@ -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

View file

@ -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)

View file

@ -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"

View file

@ -0,0 +1,3 @@
zephyr_sources(pcie.c)
zephyr_sources_ifdef(CONFIG_PCIE_MSI msi.c)
zephyr_sources_ifdef(CONFIG_PCIE_SHELL shell.c)

34
drivers/pcie/Kconfig Normal file
View file

@ -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

67
drivers/pcie/msi.c Normal file
View file

@ -0,0 +1,67 @@
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdbool.h>
#include <drivers/pcie/pcie.h>
#include <drivers/pcie/msi.h>
/* 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;
}

80
drivers/pcie/pcie.c Normal file
View file

@ -0,0 +1,80 @@
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdbool.h>
#include <drivers/pcie/pcie.h>
/* 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);
}

111
drivers/pcie/shell.c Normal file
View file

@ -0,0 +1,111 @@
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <shell/shell.h>
#include <drivers/pcie/pcie.h>
#ifdef CONFIG_PCIE_MSI
#include <drivers/pcie/msi.h>
#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);

View file

@ -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.

View file

@ -20,7 +20,6 @@
* UART_REG_ADDR_INTERVAL
*/
#include <errno.h>
#include <kernel.h>
#include <arch/cpu.h>
@ -33,13 +32,39 @@
#include <uart.h>
#include <sys_io.h>
#ifdef CONFIG_PCI
#include <pci/pci.h>
#include <pci/pci_mgr.h>
#endif /* CONFIG_PCI */
#include <drivers/serial/uart_ns16550.h>
/*
* 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 <drivers/pcie/pcie.h>
#ifdef CONFIG_PCIE_MSI
#include <drivers/pcie/msi.h>
#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

View file

@ -65,6 +65,7 @@
label = "UART_0";
interrupts = <86 0>;
interrupt-parent = <&intc>;
dlf = <0x01>;
};
uart1: uart@80014100 {

View file

@ -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
...

View file

@ -7,6 +7,7 @@
#include "skeleton.dtsi"
#include <dt-bindings/interrupt-controller/intel-ioapic.h>
#include <dt-bindings/i2c/i2c.h>
#include <dt-bindings/pcie/pcie.h>
/ {
cpus {
@ -46,9 +47,9 @@
ranges;
uart0: uart@9000f000 {
uart0: uart@0 {
compatible = "ns16550";
reg = <0x9000f000 0x400>;
pcie; reg = <PCIE_BDF(0,0x14,1) PCIE_ID(0x8086,0x936)>;
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 = <PCIE_BDF(0,0x14,5) PCIE_ID(0x8086,0x936)>;
label = "UART_1";
clock-frequency = <44236800>;
interrupts = <17 IRQ_TYPE_LEVEL_LOW 3>;

106
include/drivers/pcie/msi.h Normal file
View file

@ -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 <drivers/pcie/pcie.h>
#include <zephyr/types.h>
#include <stdbool.h>
#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_ */

168
include/drivers/pcie/pcie.h Normal file
View file

@ -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 <dt-bindings/pcie/pcie.h>
#include <zephyr/types.h>
#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_ */

View file

@ -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_ */

View file

@ -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

View file

@ -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 */

View file

@ -43,9 +43,6 @@ endif # DMA_NIOS2_MSGDMA
if UART_NS16550
config UART_NS16550_PCI
default n
config UART_NS16550_PORT_0
default y

View file

@ -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

View file

@ -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

View file

@ -20,9 +20,6 @@ config CLFLUSH_DETECT
if UART_NS16550
config UART_NS16550_PCI
default n
config UART_NS16550_PORT_0
default y

View file

@ -20,9 +20,6 @@ config CLFLUSH_DETECT
if UART_NS16550
config UART_NS16550_PCI
default n
config UART_NS16550_PORT_0
default y

View file

@ -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

View file

@ -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

View file

@ -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 */