diff --git a/arch/x86/core/early_serial.c b/arch/x86/core/early_serial.c index 0c102300a51..572b71cf5a0 100644 --- a/arch/x86/core/early_serial.c +++ b/arch/x86/core/early_serial.c @@ -11,7 +11,10 @@ #include -#ifdef CONFIG_UART_NS16550_ACCESS_IOPORT +#define UART_IS_IOPORT_ACCESS \ + DT_NODE_HAS_PROP(DT_CHOSEN(zephyr_console), io_mapped) + +#if UART_IS_IOPORT_ACCESS /* Legacy I/O Port Access to a NS16550 UART */ #define IN(reg) sys_in8(reg + DT_REG_ADDR(DT_CHOSEN(zephyr_console))) #define OUT(reg, val) sys_out8(val, reg + DT_REG_ADDR(DT_CHOSEN(zephyr_console))) @@ -86,7 +89,7 @@ int arch_printk_char_out(int c) void z_x86_early_serial_init(void) { -#if defined(DEVICE_MMIO_IS_IN_RAM) && !defined(CONFIG_UART_NS16550_ACCESS_IOPORT) +#if defined(DEVICE_MMIO_IS_IN_RAM) && !UART_IS_IOPORT_ACCESS #ifdef X86_SOC_EARLY_SERIAL_PCIDEV struct pcie_bar mbar; pcie_get_mbar(X86_SOC_EARLY_SERIAL_PCIDEV, 0, &mbar); diff --git a/boards/x86/intel_adl/Kconfig.defconfig b/boards/x86/intel_adl/Kconfig.defconfig index 0bc114e4693..9e2255a7471 100644 --- a/boards/x86/intel_adl/Kconfig.defconfig +++ b/boards/x86/intel_adl/Kconfig.defconfig @@ -44,10 +44,3 @@ endif # SHELL endif # ACPI endif # BOARD_INTEL_ADL_CRB || BOARD_INTEL_ADL_RVP - -if BOARD_INTEL_ADL_RVP - -config UART_NS16550_ACCESS_IOPORT - default y if UART_NS16550 - -endif # BOARD_INTEL_ADL_RVP diff --git a/boards/x86/qemu_x86/Kconfig.defconfig b/boards/x86/qemu_x86/Kconfig.defconfig index 1ea60480f64..4ed71964aa3 100644 --- a/boards/x86/qemu_x86/Kconfig.defconfig +++ b/boards/x86/qemu_x86/Kconfig.defconfig @@ -81,9 +81,6 @@ config QEMU_ICOUNT config QEMU_ICOUNT_SHIFT default 5 -config UART_NS16550_ACCESS_IOPORT - default y if UART_NS16550 - endif # BOARD_QEMU_X86_LAKEMONT if BOARD_QEMU_X86_TINY diff --git a/boards/x86/qemu_x86/qemu_x86_lakemont.dts b/boards/x86/qemu_x86/qemu_x86_lakemont.dts index 9c6a6da82ec..87056f9cf65 100644 --- a/boards/x86/qemu_x86/qemu_x86_lakemont.dts +++ b/boards/x86/qemu_x86/qemu_x86_lakemont.dts @@ -40,6 +40,7 @@ uart0: uart@3f8 { compatible = "ns16550"; reg = <0x000003f8 0x100>; + io-mapped; clock-frequency = <1843200>; interrupts = <4 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; diff --git a/drivers/serial/Kconfig.ns16550 b/drivers/serial/Kconfig.ns16550 index 22988f5f699..90c29046044 100644 --- a/drivers/serial/Kconfig.ns16550 +++ b/drivers/serial/Kconfig.ns16550 @@ -60,18 +60,6 @@ config UART_NS16550_ACCESS_WORD_ONLY 16550 (DesignWare UART) only allows word access, byte access will raise exception. -config UART_NS16550_ACCESS_IOPORT - bool - help - When enabled, NS16550 will not be a memory mapped device. This option - must be selected at SoC/board level if needed. - -config UART_NS16550_SIMULT_ACCESS - bool - help - When enabled, NS16550 supports IO, MMIO, PCIe UART devices simultaneously. - For io-mapped instances, io-mapped DTS property need to be added in dtsi. - config UART_NS16550_PARENT_INIT_LEVEL bool "Boot level based on parent node" default y if ACPI diff --git a/drivers/serial/uart_ns16550.c b/drivers/serial/uart_ns16550.c index 08bcd4a38c1..b0b7f4e1a26 100644 --- a/drivers/serial/uart_ns16550.c +++ b/drivers/serial/uart_ns16550.c @@ -58,6 +58,21 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE"); #include #endif +/* If any node has property io-mapped set, we need to support IO port + * access in the code and device config struct. + * + * Note that DT_ANY_INST_HAS_PROP_STATUS_OKAY() always returns true + * as io-mapped property is considered always exists and present, + * even if its value is zero. Therefore we cannot use it, and has to + * resort to the follow helper to see if any okay nodes have io-mapped + * as 1. + */ +#define UART_NS16550_DT_PROP_IOMAPPED_HELPER(inst, prop, def) \ + DT_INST_PROP_OR(inst, prop, def) || + +#define UART_NS16550_IOPORT_ENABLED \ + (DT_INST_FOREACH_STATUS_OKAY_VARGS(UART_NS16550_DT_PROP_IOMAPPED_HELPER, io_mapped, 0) 0) + /* register definitions */ #define REG_THR 0x00 /* Transmitter holding reg. */ @@ -249,7 +264,7 @@ struct uart_ns16550_device_config { #if defined(CONFIG_PINCTRL) const struct pinctrl_dev_config *pincfg; #endif -#if defined(CONFIG_UART_NS16550_ACCESS_IOPORT) || defined(CONFIG_UART_NS16550_SIMULT_ACCESS) +#if UART_NS16550_IOPORT_ENABLED bool io_map; #endif #if UART_NS16550_RESET_ENABLED @@ -282,7 +297,7 @@ struct uart_ns16550_dev_data { static void ns16550_outbyte(const struct uart_ns16550_device_config *cfg, uintptr_t port, uint8_t val) { -#if defined(CONFIG_UART_NS16550_ACCESS_IOPORT) || defined(CONFIG_UART_NS16550_SIMULT_ACCESS) +#if UART_NS16550_IOPORT_ENABLED if (cfg->io_map) { if (IS_ENABLED(CONFIG_UART_NS16550_ACCESS_WORD_ONLY)) { sys_out32(val, port); @@ -305,7 +320,7 @@ static void ns16550_outbyte(const struct uart_ns16550_device_config *cfg, static uint8_t ns16550_inbyte(const struct uart_ns16550_device_config *cfg, uintptr_t port) { -#if defined(CONFIG_UART_NS16550_ACCESS_IOPORT) || defined(CONFIG_UART_NS16550_SIMULT_ACCESS) +#if UART_NS16550_IOPORT_ENABLED if (cfg->io_map) { if (IS_ENABLED(CONFIG_UART_NS16550_ACCESS_WORD_ONLY)) { return sys_in32(port); @@ -330,7 +345,7 @@ static uint8_t ns16550_inbyte(const struct uart_ns16550_device_config *cfg, static void ns16550_outword(const struct uart_ns16550_device_config *cfg, uintptr_t port, uint32_t val) { -#if defined(CONFIG_UART_NS16550_ACCESS_IOPORT) || defined(CONFIG_UART_NS16550_SIMULT_ACCESS) +#if UART_NS16550_IOPORT_ENABLED if (cfg->io_map) { sys_out32(val, port); } else { @@ -345,7 +360,7 @@ static void ns16550_outword(const struct uart_ns16550_device_config *cfg, static uint32_t ns16550_inword(const struct uart_ns16550_device_config *cfg, uintptr_t port) { -#if defined(CONFIG_UART_NS16550_ACCESS_IOPORT) || defined(CONFIG_UART_NS16550_SIMULT_ACCESS) +#if UART_NS16550_IOPORT_ENABLED if (cfg->io_map) { return sys_in32(port); } @@ -365,7 +380,7 @@ static inline uint8_t reg_interval(const struct device *dev) static inline uintptr_t get_port(const struct device *dev) { uintptr_t port; -#if defined(CONFIG_UART_NS16550_ACCESS_IOPORT) || defined(CONFIG_UART_NS16550_SIMULT_ACCESS) +#if UART_NS16550_IOPORT_ENABLED const struct uart_ns16550_device_config *config = dev->config; if (config->io_map) { @@ -658,7 +673,7 @@ static int uart_ns16550_init(const struct device *dev) } else #endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(pcie) */ { -#if defined(CONFIG_UART_NS16550_ACCESS_IOPORT) || defined(CONFIG_UART_NS16550_SIMULT_ACCESS) +#if UART_NS16550_IOPORT_ENABLED /* Map directly from DTS */ if (!dev_cfg->io_map) { #else @@ -1257,30 +1272,6 @@ static const struct uart_driver_api uart_ns16550_driver_api = { pcie_irq_enable(dev_cfg->pcie->bdf, irq); \ } -#ifdef CONFIG_UART_NS16550_ACCESS_IOPORT -#define REG_INIT(n) \ - .port = DT_INST_REG_ADDR(n), \ - .io_map = true, -#else -#define REG_INIT_PCIE1(n) -#define REG_INIT_PCIE0(n) DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)), - -#define DEV_REG_PORT_IO_1(n) \ - .port = DT_INST_REG_ADDR(n), -#define DEV_REG_PORT_IO_0(n) \ - _CONCAT(REG_INIT_PCIE, DT_INST_ON_BUS(n, pcie))(n) -#ifdef CONFIG_UART_NS16550_SIMULT_ACCESS -#define DEV_IO_INIT(n) \ - .io_map = DT_INST_PROP(n, io_mapped), -#else -#define DEV_IO_INIT(n) -#endif - -#define REG_INIT(n) \ - _CONCAT(DEV_REG_PORT_IO_, DT_INST_PROP(n, io_mapped))(n) \ - DEV_IO_INIT(n) -#endif - #ifdef CONFIG_UART_INTERRUPT_DRIVEN #define DEV_CONFIG_IRQ_FUNC_INIT(n) \ .irq_config_func = irq_config_func##n, @@ -1316,7 +1307,13 @@ static const struct uart_driver_api uart_ns16550_driver_api = { IF_ENABLED(DT_INST_NODE_HAS_PROP(n, pinctrl_0), \ (PINCTRL_DT_INST_DEFINE(n))); \ static const struct uart_ns16550_device_config uart_ns16550_dev_cfg_##n = { \ - REG_INIT(n) \ + COND_CODE_0(DT_INST_ON_BUS(n, pcie), \ + (COND_CODE_1(DT_INST_PROP_OR(n, io_mapped, 0), \ + (.port = DT_INST_REG_ADDR(n),), \ + (DEVICE_MMIO_ROM_INIT(DT_DRV_INST(n)),))), \ + ()) \ + IF_ENABLED(DT_INST_PROP_OR(n, io_mapped, 0), \ + (.io_map = true,)) \ COND_CODE_1(DT_INST_NODE_HAS_PROP(n, clock_frequency), ( \ .sys_clk_freq = DT_INST_PROP(n, clock_frequency), \ .clock_dev = NULL, \ diff --git a/dts/arc/synopsys/arc_iot.dtsi b/dts/arc/synopsys/arc_iot.dtsi index 1e8a67d443e..7d04321e0ee 100644 --- a/dts/arc/synopsys/arc_iot.dtsi +++ b/dts/arc/synopsys/arc_iot.dtsi @@ -76,6 +76,7 @@ compatible = "ns16550"; clock-frequency = <16000000>; reg = <0x80014000 0x100>; + io-mapped; interrupts = <86 0>; interrupt-parent = <&intc>; dlf = <0x01>; @@ -86,6 +87,7 @@ compatible = "ns16550"; clock-frequency = <16000000>; reg = <0x80014100 0x100>; + io-mapped; interrupts = <87 0>; interrupt-parent = <&intc>; reg-shift = <2>; @@ -96,6 +98,7 @@ compatible = "ns16550"; clock-frequency = <16000000>; reg = <0x80014200 0x1000>; + io-mapped; interrupts = <88 0>; interrupt-parent = <&intc>; reg-shift = <2>; @@ -106,6 +109,7 @@ compatible = "ns16550"; clock-frequency = <144000000>; reg = <0x80014300 0x100>; + io-mapped; interrupts = <89 0>; interrupt-parent = <&intc>; reg-shift = <2>; diff --git a/dts/x86/intel/alder_lake.dtsi b/dts/x86/intel/alder_lake.dtsi index b0cca7e5200..43f552609a4 100644 --- a/dts/x86/intel/alder_lake.dtsi +++ b/dts/x86/intel/alder_lake.dtsi @@ -239,6 +239,7 @@ uart0_legacy: uart@3f8 { compatible = "ns16550"; reg = <0x000003f8 0x100>; + io-mapped; clock-frequency = <1843200>; interrupts = <4 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; diff --git a/dts/x86/intel/atom.dtsi b/dts/x86/intel/atom.dtsi index fe8340163ba..f1aee1502df 100644 --- a/dts/x86/intel/atom.dtsi +++ b/dts/x86/intel/atom.dtsi @@ -49,6 +49,7 @@ uart0: uart@3f8 { compatible = "ns16550"; reg = <0x000003f8 0x100>; + io-mapped; clock-frequency = <1843200>; interrupts = <4 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; @@ -59,6 +60,7 @@ uart1: uart@2f8 { compatible = "ns16550"; reg = <0x000002f8 0x100>; + io-mapped; clock-frequency = <1843200>; interrupts = <3 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; diff --git a/dts/x86/intel/ia32.dtsi b/dts/x86/intel/ia32.dtsi index 6058fff6123..9d1715aa840 100644 --- a/dts/x86/intel/ia32.dtsi +++ b/dts/x86/intel/ia32.dtsi @@ -51,6 +51,7 @@ uart0: uart@3f8 { compatible = "ns16550"; reg = <0x000003f8 0x100>; + io-mapped; clock-frequency = <1843200>; interrupts = <4 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; @@ -61,6 +62,7 @@ uart1: uart@2f8 { compatible = "ns16550"; reg = <0x000002f8 0x100>; + io-mapped; clock-frequency = <1843200>; interrupts = <3 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; diff --git a/dts/x86/intel/raptor_lake.dtsi b/dts/x86/intel/raptor_lake.dtsi index 91a6d933260..bc3c59c2159 100644 --- a/dts/x86/intel/raptor_lake.dtsi +++ b/dts/x86/intel/raptor_lake.dtsi @@ -373,6 +373,7 @@ uart_ec_0: uart@3f8 { compatible = "ns16550"; reg = <0x000003f8 0x100>; + io-mapped; clock-frequency = <1843200>; interrupts = <4 IRQ_TYPE_LOWEST_EDGE_RISING 3>; interrupt-parent = <&intc>; diff --git a/soc/arc/snps_arc_iot/Kconfig.defconfig b/soc/arc/snps_arc_iot/Kconfig.defconfig index 8abaa3382d5..202697a7cf9 100644 --- a/soc/arc/snps_arc_iot/Kconfig.defconfig +++ b/soc/arc/snps_arc_iot/Kconfig.defconfig @@ -34,7 +34,4 @@ config HARVARD config ARC_FIRQ default y -config UART_NS16550_ACCESS_IOPORT - default y - endif # ARC_IOT diff --git a/soc/x86/atom/Kconfig.defconfig b/soc/x86/atom/Kconfig.defconfig index 2658fa7220b..743b43465f4 100644 --- a/soc/x86/atom/Kconfig.defconfig +++ b/soc/x86/atom/Kconfig.defconfig @@ -11,7 +11,4 @@ config SOC config SYS_CLOCK_HW_CYCLES_PER_SEC default 25000000 if HPET_TIMER -config UART_NS16550_ACCESS_IOPORT - default y if UART_NS16550 - endif diff --git a/soc/x86/ia32/Kconfig.defconfig b/soc/x86/ia32/Kconfig.defconfig index cd6f6f20790..87600183a20 100644 --- a/soc/x86/ia32/Kconfig.defconfig +++ b/soc/x86/ia32/Kconfig.defconfig @@ -11,7 +11,4 @@ config SOC config SYS_CLOCK_HW_CYCLES_PER_SEC default 25000000 if HPET_TIMER -config UART_NS16550_ACCESS_IOPORT - default y if UART_NS16550 - endif diff --git a/soc/x86/raptor_lake/Kconfig.defconfig b/soc/x86/raptor_lake/Kconfig.defconfig index 70abc51438b..f9b14da95d0 100644 --- a/soc/x86/raptor_lake/Kconfig.defconfig +++ b/soc/x86/raptor_lake/Kconfig.defconfig @@ -15,7 +15,4 @@ config X86_DYNAMIC_IRQ_STUBS default 16 depends on DYNAMIC_INTERRUPTS -config UART_NS16550_SIMULT_ACCESS - default y if UART_NS16550 - endif # SOC_RAPTOR_LAKE