diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 5eef4eab5ff..f06224b2e4e 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_library() -zephyr_library_sources_ifdef(CONFIG_UART_ALTERA_JTAG uart_altera_jtag_hal.c) +zephyr_library_sources_ifdef(CONFIG_UART_ALTERA_JTAG uart_altera_jtag.c) zephyr_library_sources_ifdef(CONFIG_UART_TELINK_B91 uart_b91.c) zephyr_library_sources_ifdef(CONFIG_UART_IMX uart_imx.c) zephyr_library_sources_ifdef(CONFIG_UART_ITE_IT8XXX2 uart_ite_it8xxx2.c) diff --git a/drivers/serial/Kconfig.altera_jtag b/drivers/serial/Kconfig.altera_jtag index 9ea84c0300a..c81b84d4af0 100644 --- a/drivers/serial/Kconfig.altera_jtag +++ b/drivers/serial/Kconfig.altera_jtag @@ -9,3 +9,7 @@ config UART_ALTERA_JTAG help Enable the Altera JTAG UART driver, built in to many Nios II CPU designs. + +config UART_ALTERA_JTAG_HAL + bool "JTAG UART driver using Altera HAL API" + depends on UART_ALTERA_JTAG diff --git a/drivers/serial/uart_altera_jtag.c b/drivers/serial/uart_altera_jtag.c new file mode 100644 index 00000000000..eb5cf2b0905 --- /dev/null +++ b/drivers/serial/uart_altera_jtag.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +#include +#include +#include +#include + +#define DT_DRV_COMPAT altr_jtag_uart + +#define UART_ALTERA_JTAG_DATA_OFFSET 0x00 /* DATA : Register offset */ +#define UART_ALTERA_JTAG_CTRL_OFFSET 0x04 /* CTRL : Register offset */ +#define UART_IE_TX (1 << 0) /* CTRL : TX Interrupt Enable */ +#define UART_IE_RX (1 << 1) /* CTRL : RX Interrupt Enable */ +#define UART_DATA_MASK 0xFF /* DATA : Data Mask */ +#define UART_WFIFO_MASK 0xFFFF0000 /* CTRL : Transmit FIFO Mask */ + +#ifdef CONFIG_UART_ALTERA_JTAG_HAL +#include "altera_avalon_jtag_uart.h" +#include "altera_avalon_jtag_uart_regs.h" + +extern int altera_avalon_jtag_uart_read(altera_avalon_jtag_uart_state *sp, + char *buffer, int space, int flags); +extern int altera_avalon_jtag_uart_write(altera_avalon_jtag_uart_state *sp, + const char *ptr, int count, int flags); +#else + +/* device data */ +struct uart_altera_jtag_device_data { + struct k_spinlock lock; +}; + +/* device config */ +struct uart_altera_jtag_device_config { + mm_reg_t base; +}; +#endif /* CONFIG_UART_ALTERA_JTAG_HAL */ + +static void uart_altera_jtag_poll_out(const struct device *dev, + unsigned char c) +{ +#ifdef CONFIG_UART_ALTERA_JTAG_HAL + altera_avalon_jtag_uart_state ustate; + + ustate.base = JTAG_UART_0_BASE; + altera_avalon_jtag_uart_write(&ustate, &c, 1, 0); +#else + const struct uart_altera_jtag_device_config *config = dev->config; + struct uart_altera_jtag_device_data *data = dev->data; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + /* While TX FIFO full */ + while (!(sys_read32(config->base + UART_ALTERA_JTAG_CTRL_OFFSET) & UART_WFIFO_MASK)) { + } + + uint32_t data_val = sys_read32(config->base + UART_ALTERA_JTAG_DATA_OFFSET); + + data_val &= ~UART_DATA_MASK; + data_val |= c; + sys_write32(data_val, config->base + UART_ALTERA_JTAG_DATA_OFFSET); + + k_spin_unlock(&data->lock, key); +#endif /* CONFIG_UART_ALTERA_JTAG_HAL */ +} + +static int uart_altera_jtag_init(const struct device *dev) +{ + /* + * Work around to clear interrupt enable bits + * as it is not being done by HAL driver explicitly. + */ +#ifdef CONFIG_UART_ALTERA_JTAG_HAL + IOWR_ALTERA_AVALON_JTAG_UART_CONTROL(JTAG_UART_0_BASE, 0); +#else + const struct uart_altera_jtag_device_config *config = dev->config; + uint32_t ctrl_val = sys_read32(config->base + UART_ALTERA_JTAG_CTRL_OFFSET); + + ctrl_val &= ~(UART_IE_TX | UART_IE_RX); + sys_write32(ctrl_val, sys_read32(config->base + UART_ALTERA_JTAG_CTRL_OFFSET)); +#endif /* CONFIG_UART_ALTERA_JTAG_HAL */ + return 0; +} + +static const struct uart_driver_api uart_altera_jtag_driver_api = { + .poll_in = NULL, + .poll_out = &uart_altera_jtag_poll_out, + .err_check = NULL, +}; + +#ifdef CONFIG_UART_ALTERA_JTAG_HAL +DEVICE_DT_INST_DEFINE(0, uart_altera_jtag_init, NULL, NULL, NULL, PRE_KERNEL_1, + CONFIG_SERIAL_INIT_PRIORITY, + &uart_altera_jtag_driver_api); +#else +static struct uart_altera_jtag_device_data uart_altera_jtag_dev_data_0 = { +}; + +static const struct uart_altera_jtag_device_config uart_altera_jtag_dev_cfg_0 = { + .base = DT_INST_REG_ADDR(0), +}; +DEVICE_DT_INST_DEFINE(0, + uart_altera_jtag_init, + NULL, + &uart_altera_jtag_dev_data_0, + &uart_altera_jtag_dev_cfg_0, + PRE_KERNEL_1, + CONFIG_SERIAL_INIT_PRIORITY, + &uart_altera_jtag_driver_api); +#endif /* CONFIG_UART_ALTERA_JTAG_HAL */ diff --git a/drivers/serial/uart_altera_jtag_hal.c b/drivers/serial/uart_altera_jtag_hal.c deleted file mode 100644 index 08de68e8b3b..00000000000 --- a/drivers/serial/uart_altera_jtag_hal.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2017 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - - -#include -#include -#include -#include - -#include "altera_avalon_jtag_uart.h" -#include "altera_avalon_jtag_uart_regs.h" - -#define DT_DRV_COMPAT altr_jtag_uart - -#define UART_ALTERA_JTAG_DATA_REG 0 -#define UART_ALTERA_JTAG_CONTROL_REG 1 - -extern int altera_avalon_jtag_uart_read(altera_avalon_jtag_uart_state *sp, - char *buffer, int space, int flags); -extern int altera_avalon_jtag_uart_write(altera_avalon_jtag_uart_state *sp, - const char *ptr, int count, int flags); - -static void uart_altera_jtag_poll_out(const struct device *dev, - unsigned char c) -{ - altera_avalon_jtag_uart_state ustate; - - ustate.base = JTAG_UART_0_BASE; - altera_avalon_jtag_uart_write(&ustate, &c, 1, 0); -} - -static int uart_altera_jtag_init(const struct device *dev) -{ - /* - * Work around to clear interrupt enable bits - * as it is not being done by HAL driver explicitly. - */ - IOWR_ALTERA_AVALON_JTAG_UART_CONTROL(JTAG_UART_0_BASE, 0); - return 0; -} - -static const struct uart_driver_api uart_altera_jtag_driver_api = { - .poll_in = NULL, - .poll_out = &uart_altera_jtag_poll_out, - .err_check = NULL, -}; - -DEVICE_DT_INST_DEFINE(0, uart_altera_jtag_init, NULL, NULL, NULL, PRE_KERNEL_1, - CONFIG_SERIAL_INIT_PRIORITY, - &uart_altera_jtag_driver_api); diff --git a/dts/nios2/nios2f.dtsi b/dts/nios2/nios2f.dtsi index d9739417420..0d09a8949da 100644 --- a/dts/nios2/nios2f.dtsi +++ b/dts/nios2/nios2f.dtsi @@ -44,6 +44,14 @@ status = "disabled"; }; + jtag_uart: uart@201000 { + compatible = "altr,jtag-uart"; + reg = <0x201000 0x8>; + label = "JTAG_UART"; + + status = "disabled"; + }; + i2c0: i2c@100200 { compatible = "altr,nios2-i2c"; clock-frequency = ;