drivers/serial: Extend Altera Jtag Uart driver support

Extend Altera Jtag Uart driver support without Altera HAL driver
by default. uart_altera_jtag_hal.c renamed to uart_altera_jtag.c and
new config, CONFIG_UART_ALTERA_JTAG_HAL is introduced to allow driver
to use Altera HAL driver when needed.

Signed-off-by: Khor Swee Aun <swee.aun.khor@intel.com>
This commit is contained in:
Khor Swee Aun 2022-04-04 16:18:49 +08:00 committed by Anas Nashif
commit 0431d10b10
5 changed files with 127 additions and 54 deletions

View file

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

View file

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

View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <kernel.h>
#include <arch/cpu.h>
#include <drivers/uart.h>
#include <sys/sys_io.h>
#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 */

View file

@ -1,53 +0,0 @@
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <kernel.h>
#include <arch/cpu.h>
#include <drivers/uart.h>
#include <sys/sys_io.h>
#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);

View file

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