/*
 * Copyright (c) 2019-2020 Cobham Gaisler AB
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT gaisler_apbuart

#include <drivers/uart.h>
#include <errno.h>

/* APBUART registers
 *
 * Offset | Name   | Description
 * ------ | ------ | ----------------------------------------
 * 0x0000 | data   | UART data register
 * 0x0004 | status | UART status register
 * 0x0008 | ctrl   | UART control register
 * 0x000c | scaler | UART scaler register
 * 0x0010 | debug  | UART FIFO debug register
 */

struct apbuart_regs {
	/** @brief UART data register
	 *
	 * Bit    | Name   | Description
	 * ------ | ------ | ----------------------------------------
	 * 7-0    | data   | Holding register or FIFO
	 */
	uint32_t data;          /* 0x0000 */

	/** @brief UART status register
	 *
	 * Bit    | Name   | Description
	 * ------ | ------ | ----------------------------------------
	 * 31-26  | RCNT   | Receiver FIFO count
	 * 25-20  | TCNT   | Transmitter FIFO count
	 * 10     | RF     | Receiver FIFO full
	 * 9      | TF     | Transmitter FIFO full
	 * 8      | RH     | Receiver FIFO half-full
	 * 7      | TH     | Transmitter FIFO half-full
	 * 6      | FE     | Framing error
	 * 5      | PE     | Parity error
	 * 4      | OV     | Overrun
	 * 3      | BR     | Break received
	 * 2      | TE     | Transmitter FIFO empty
	 * 1      | TS     | Transmitter shift register empty
	 * 0      | DR     | Data ready
	 */
	uint32_t status;        /* 0x0004 */

	/** @brief UART control register
	 *
	 * Bit    | Name   | Description
	 * ------ | ------ | ----------------------------------------
	 * 31     | FA     | FIFOs available
	 * 14     | SI     | Transmitter shift register empty interrupt enable
	 * 13     | DI     | Delayed interrupt enable
	 * 12     | BI     | Break interrupt enable
	 * 11     | DB     | FIFO debug mode enable
	 * 10     | RF     | Receiver FIFO interrupt enable
	 * 9      | TF     | Transmitter FIFO interrupt enable
	 * 8      | EC     | External clock
	 * 7      | LB     | Loop back
	 * 6      | FL     | Flow control
	 * 5      | PE     | Parity enable
	 * 4      | PS     | Parity select
	 * 3      | TI     | Transmitter interrupt enable
	 * 2      | RI     | Receiver interrupt enable
	 * 1      | TE     | Transmitter enable
	 * 0      | RE     | Receiver enable
	 */
	uint32_t ctrl;          /* 0x0008 */

	/** @brief UART scaler register
	 *
	 * Bit    | Name   | Description
	 * ------ | ------ | ----------------------------------------
	 * 11-0   | RELOAD | Scaler reload value
	 */
	uint32_t scaler;        /* 0x000c */

	/** @brief UART FIFO debug register
	 *
	 * Bit    | Name   | Description
	 * ------ | ------ | ----------------------------------------
	 * 7-0    | data   | Holding register or FIFO
	 */
	uint32_t debug;         /* 0x0010 */
};

/* APBUART register bits. */

/* Control register */
#define APBUART_CTRL_FA         (1 << 31)
#define APBUART_CTRL_DB         (1 << 11)
#define APBUART_CTRL_RF         (1 << 10)
#define APBUART_CTRL_TF         (1 <<  9)
#define APBUART_CTRL_LB         (1 <<  7)
#define APBUART_CTRL_FL         (1 <<  6)
#define APBUART_CTRL_PE         (1 <<  5)
#define APBUART_CTRL_PS         (1 <<  4)
#define APBUART_CTRL_TI         (1 <<  3)
#define APBUART_CTRL_RI         (1 <<  2)
#define APBUART_CTRL_TE         (1 <<  1)
#define APBUART_CTRL_RE         (1 <<  0)

/* Status register */
#define APBUART_STATUS_RF       (1 << 10)
#define APBUART_STATUS_TF       (1 <<  9)
#define APBUART_STATUS_RH       (1 <<  8)
#define APBUART_STATUS_TH       (1 <<  7)
#define APBUART_STATUS_FE       (1 <<  6)
#define APBUART_STATUS_PE       (1 <<  5)
#define APBUART_STATUS_OV       (1 <<  4)
#define APBUART_STATUS_BR       (1 <<  3)
#define APBUART_STATUS_TE       (1 <<  2)
#define APBUART_STATUS_TS       (1 <<  1)
#define APBUART_STATUS_DR       (1 <<  0)

/* For APBUART implemented without FIFO */
#define APBUART_STATUS_HOLD_REGISTER_EMPTY (1 << 2)

struct apbuart_dev_cfg {
	struct apbuart_regs *regs;
	int interrupt;
};

struct apbuart_dev_data {
	int usefifo;
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	uart_irq_callback_user_data_t cb;
	void *cb_data;
#endif
};

#define DEV_CFG(dev) \
	((const struct apbuart_dev_cfg *const)(dev)->config)
#define DEV_DATA(dev) \
	((struct apbuart_dev_data *const)(dev)->data)

/*
 * This routine waits for the TX holding register or TX FIFO to be ready and
 * then it writes a character to the data register.
 */
static void apbuart_poll_out(const struct device *dev, unsigned char x)
{
	volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;

	if (DEV_DATA(dev)->usefifo) {
		/* Transmitter FIFO full flag is available. */
		while (regs->status & APBUART_STATUS_TF) {
			;
		}
	} else {
		/*
		 * Transmitter "hold register empty" AKA "FIFO empty" flag is
		 * available.
		 */
		while (!(regs->status & APBUART_STATUS_HOLD_REGISTER_EMPTY)) {
			;
		}
	}

	regs->data = x & 0xff;
}

static int apbuart_poll_in(const struct device *dev, unsigned char *c)
{
	volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;

	if ((regs->status & APBUART_STATUS_DR) == 0) {
		return -1;
	}
	*c = regs->data & 0xff;

	return 0;
}

static int apbuart_err_check(const struct device *dev)
{
	volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;
	const uint32_t status = regs->status;
	int err = 0;

	if (status & APBUART_STATUS_FE) {
		err |= UART_ERROR_FRAMING;
	}
	if (status & APBUART_STATUS_PE) {
		err |= UART_ERROR_PARITY;
	}
	if (status & APBUART_STATUS_OV) {
		err |= UART_ERROR_OVERRUN;
	}
	if (status & APBUART_STATUS_BR) {
		err |= UART_BREAK;
	}

	return err;
}

static int get_baud(volatile struct apbuart_regs *const regs)
{
	unsigned int core_clk_hz;
	unsigned int scaler;

	scaler = regs->scaler;
	core_clk_hz = sys_clock_hw_cycles_per_sec();

	/* Calculate baud rate from generator "scaler" number */
	return core_clk_hz / ((scaler + 1) * 8);
}

static void set_baud(volatile struct apbuart_regs *const regs, uint32_t baud)
{
	unsigned int core_clk_hz;
	unsigned int scaler;

	if (baud == 0) {
		return;
	}

	core_clk_hz = sys_clock_hw_cycles_per_sec();

	/* Calculate Baud rate generator "scaler" number */
	scaler = (((core_clk_hz * 10) / (baud * 8)) - 5) / 10;

	/* Set new baud rate by setting scaler */
	regs->scaler = scaler;
}

static int apbuart_configure(const struct device *dev,
			     const struct uart_config *cfg)
{
	volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;
	uint32_t ctrl = 0;
	uint32_t newctrl = 0;

	switch (cfg->parity) {
	case UART_CFG_PARITY_NONE:
		break;
	case UART_CFG_PARITY_EVEN:
		newctrl |= APBUART_CTRL_PE;
		break;
	case UART_CFG_PARITY_ODD:
		newctrl |= APBUART_CTRL_PE | APBUART_CTRL_PS;
		break;
	default:
		return -ENOTSUP;
	}

	if (cfg->stop_bits != UART_CFG_STOP_BITS_1) {
		return -ENOTSUP;
	}

	if (cfg->data_bits != UART_CFG_DATA_BITS_8) {
		return -ENOTSUP;
	}

	switch (cfg->flow_ctrl) {
	case UART_CFG_FLOW_CTRL_NONE:
		break;
	case UART_CFG_FLOW_CTRL_RTS_CTS:
		newctrl |= APBUART_CTRL_FL;
		break;
	default:
		return -ENOTSUP;
	}

	set_baud(regs, cfg->baudrate);

	ctrl = regs->ctrl;
	ctrl &= ~(APBUART_CTRL_PE | APBUART_CTRL_PS | APBUART_CTRL_FL);
	regs->ctrl = ctrl | newctrl;

	return 0;
}

static int apbuart_config_get(const struct device *dev, struct uart_config *cfg)
{
	volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;
	const uint32_t ctrl = regs->ctrl;

	cfg->parity = UART_CFG_PARITY_NONE;
	if (ctrl & APBUART_CTRL_PE) {
		if (ctrl & APBUART_CTRL_PS) {
			cfg->parity = UART_CFG_PARITY_ODD;
		} else {
			cfg->parity = UART_CFG_PARITY_EVEN;
		}
	}

	cfg->flow_ctrl = UART_CFG_FLOW_CTRL_NONE;
	if (ctrl & APBUART_CTRL_FL) {
		cfg->flow_ctrl = UART_CFG_FLOW_CTRL_RTS_CTS;
	}

	cfg->baudrate = get_baud(regs);

	cfg->data_bits = UART_CFG_DATA_BITS_8;
	cfg->stop_bits = UART_CFG_STOP_BITS_1;

	return 0;
}

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
static void apbuart_isr(const struct device *dev);

static int apbuart_fifo_fill(const struct device *dev, const uint8_t *tx_data,
			     int size)
{
	volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;
	int i;

	if (DEV_DATA(dev)->usefifo) {
		/* Transmitter FIFO full flag is available. */
		for (
			i = 0;
			(i < size) && !(regs->status & APBUART_STATUS_TF);
			i++
		) {
			regs->data = tx_data[i];
		}
		return i;
	}
	for (i = 0; (i < size) && (regs->status & APBUART_STATUS_TE); i++) {
		regs->data = tx_data[i];
	}

	return i;
}

static int apbuart_fifo_read(const struct device *dev, uint8_t *rx_data,
			     const int size)
{
	volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;
	int i;

	for (i = 0; (i < size) && (regs->status & APBUART_STATUS_DR); i++) {
		rx_data[i] = regs->data & 0xff;
	}

	return i;
}

static void apbuart_irq_tx_enable(const struct device *dev)
{
	volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;
	unsigned int key;

	if (DEV_DATA(dev)->usefifo) {
		/* Enable the FIFO level interrupt */
		regs->ctrl |= APBUART_CTRL_TF;
		return;
	}

	regs->ctrl |= APBUART_CTRL_TI;
	/*
	 * The "TI" interrupt is an edge interrupt.  It fires each time the TX
	 * holding register (or FIFO if implemented) moves from non-empty to
	 * empty.
	 *
	 * When the APBUART is implemented _without_ FIFO, the TI interrupt is
	 * the only TX interrupt we have. When the APBUART is implemented
	 * _with_ FIFO, the TI will fire on each TX byte.
	 */
	regs->ctrl |= APBUART_CTRL_TI;
	/* Fire the first "TI" edge interrupt to get things going. */
	key = irq_lock();
	apbuart_isr(dev);
	irq_unlock(key);
}

static void apbuart_irq_tx_disable(const struct device *dev)
{
	volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;

	regs->ctrl &= ~(APBUART_CTRL_TF | APBUART_CTRL_TI);
}

static int apbuart_irq_tx_ready(const struct device *dev)
{
	volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;

	if (DEV_DATA(dev)->usefifo) {
		return !(regs->status & APBUART_STATUS_TF);
	}
	return !!(regs->status & APBUART_STATUS_TE);
}

static int apbuart_irq_tx_complete(const struct device *dev)
{
	volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;

	return !!(regs->status & APBUART_STATUS_TS);
}

static void apbuart_irq_rx_enable(const struct device *dev)
{
	volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;

	regs->ctrl |= APBUART_CTRL_RI;
}

static void apbuart_irq_rx_disable(const struct device *dev)
{
	volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;

	regs->ctrl &= ~APBUART_CTRL_RI;
}

static int apbuart_irq_rx_ready(const struct device *dev)
{
	volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;

	return !!(regs->status & APBUART_STATUS_DR);
}

static int apbuart_irq_is_pending(const struct device *dev)
{
	volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;
	uint32_t status = regs->status;
	uint32_t ctrl = regs->ctrl;

	if ((ctrl & APBUART_CTRL_RI) && (status & APBUART_STATUS_DR)) {
		return 1;
	}

	if (DEV_DATA(dev)->usefifo) {
		/* TH is the TX FIFO half-empty flag */
		if (status & APBUART_STATUS_TH) {
			return 1;
		}
	} else {
		if ((ctrl & APBUART_CTRL_TI) && (status & APBUART_STATUS_TE)) {
			return 1;
		}
	}

	return 0;
}

static int apbuart_irq_update(const struct device *dev)
{
	return 1;
}

static void apbuart_irq_callback_set(const struct device *dev,
				     uart_irq_callback_user_data_t cb,
				     void *cb_data)
{
	struct apbuart_dev_data *const dev_data = DEV_DATA(dev);

	dev_data->cb = cb;
	dev_data->cb_data = cb_data;
}

static void apbuart_isr(const struct device *dev)
{
	struct apbuart_dev_data *const dev_data = DEV_DATA(dev);

	if (dev_data->cb) {
		dev_data->cb(dev, dev_data->cb_data);
	}
}
#endif /* CONFIG_UART_INTERRUPT_DRIVEN */

static int apbuart_init(const struct device *dev)
{
	volatile struct apbuart_regs *regs = (void *) DEV_CFG(dev)->regs;
	const uint32_t APBUART_DEBUG_MASK = APBUART_CTRL_DB | APBUART_CTRL_FL;
	uint32_t dm;
	uint32_t ctrl;

	ctrl = regs->ctrl;
	DEV_DATA(dev)->usefifo = !!(ctrl & APBUART_CTRL_FA);
	/* NOTE: CTRL_FL has reset value 0. CTRL_DB has no reset value. */
	dm = ctrl & APBUART_DEBUG_MASK;
	if (dm == APBUART_DEBUG_MASK) {
		/* Debug mode enabled so assume APBUART already initialized. */
		;
	} else {
		regs->ctrl = APBUART_CTRL_TE | APBUART_CTRL_RE;
	}

	regs->status = 0;

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	irq_connect_dynamic(DEV_CFG(dev)->interrupt,
			    0, (void (*)(const void *))apbuart_isr, dev, 0);
	irq_enable(DEV_CFG(dev)->interrupt);
#endif

	return 0;
}

/* Driver API defined in uart.h */
static const struct uart_driver_api apbuart_driver_api = {
	.poll_in                = apbuart_poll_in,
	.poll_out               = apbuart_poll_out,
	.err_check              = apbuart_err_check,
	.configure              = apbuart_configure,
	.config_get             = apbuart_config_get,
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
	.fifo_fill              = apbuart_fifo_fill,
	.fifo_read              = apbuart_fifo_read,
	.irq_tx_enable          = apbuart_irq_tx_enable,
	.irq_tx_disable         = apbuart_irq_tx_disable,
	.irq_tx_ready           = apbuart_irq_tx_ready,
	.irq_rx_enable          = apbuart_irq_rx_enable,
	.irq_rx_disable         = apbuart_irq_rx_disable,
	.irq_tx_complete        = apbuart_irq_tx_complete,
	.irq_rx_ready           = apbuart_irq_rx_ready,
	.irq_is_pending         = apbuart_irq_is_pending,
	.irq_update             = apbuart_irq_update,
	.irq_callback_set       = apbuart_irq_callback_set,
#endif
};

#define APBUART_INIT(index)						\
	static const struct apbuart_dev_cfg apbuart##index##_config = {	\
		.regs           = (struct apbuart_regs *)		\
				  DT_INST_REG_ADDR(index),		\
		.interrupt      = DT_INST_IRQN(index),			\
	};								\
									\
	static struct apbuart_dev_data apbuart##index##_data = {	\
		.usefifo        = 0,					\
	};								\
									\
	DEVICE_DT_INST_DEFINE(index,					\
			    &apbuart_init,				\
			    device_pm_control_nop,			\
			    &apbuart##index##_data,			\
			    &apbuart##index##_config,			\
			    PRE_KERNEL_1,				\
			    CONFIG_KERNEL_INIT_PRIORITY_DEVICE,		\
			    &apbuart_driver_api);

DT_INST_FOREACH_STATUS_OKAY(APBUART_INIT)
