uart: ns16550: use io-mapped DT property for IO port access

The old CONFIG_UART_NS16550_ACCESS_IOPORT has been used to
indicate whether to access the NS16550 UART via IO port
before device tree is used to describe hardware. Now we have
device tree, and we can specify whether a particular UART
needs to be accessed via IO port using property io-mapped.
Therefore, CONFIG_UART_NS16550_ACCESS_IOPORT is no longer
needed (and thus also CONFIG_UART_NS16550_SIMULT_ACCESS).
Remove these two kconfigs and modify code to use device tree
to figure out how to access the UART hardware.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
Daniel Leung 2023-09-21 17:17:13 -07:00 committed by Carles Cufí
commit 9f9b4a8afa
15 changed files with 45 additions and 68 deletions

View file

@ -11,7 +11,10 @@
#include <soc.h>
#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);

View file

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

View file

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

View file

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

View file

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

View file

@ -58,6 +58,21 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_PCIE), "NS16550(s) in DT need CONFIG_PCIE");
#include <zephyr/drivers/reset.h>
#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, \

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -34,7 +34,4 @@ config HARVARD
config ARC_FIRQ
default y
config UART_NS16550_ACCESS_IOPORT
default y
endif # ARC_IOT

View file

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

View file

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

View file

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