// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2013 Tilera Corporation. All Rights Reserved.
 *
 * TILEGx UART driver.
 */

#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/serial_core.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>

#include <gxio/common.h>
#include <gxio/iorpc_globals.h>
#include <gxio/iorpc_uart.h>
#include <gxio/kiorpc.h>

#include <hv/drv_uart_intf.h>

/*
 * Use device name ttyS, major 4, minor 64-65.
 * This is the usual serial port name, 8250 conventional range.
 */
#define TILEGX_UART_MAJOR	TTY_MAJOR
#define TILEGX_UART_MINOR	64
#define TILEGX_UART_NAME	"ttyS"
#define DRIVER_NAME_STRING	"TILEGx_Serial"
#define TILEGX_UART_REF_CLK	125000000; /* REF_CLK is always 125 MHz. */

struct tile_uart_port {
	/* UART port. */
	struct uart_port	uart;

	/* GXIO device context. */
	gxio_uart_context_t	context;

	/* UART access mutex. */
	struct mutex		mutex;

	/* CPU receiving interrupts. */
	int			irq_cpu;
};

static struct tile_uart_port tile_uart_ports[TILEGX_UART_NR];
static struct uart_driver tilegx_uart_driver;


/*
 * Read UART rx fifo, and insert the chars into tty buffer.
 */
static void receive_chars(struct tile_uart_port *tile_uart,
			  struct tty_struct *tty)
{
	int i;
	char c;
	UART_FIFO_COUNT_t count;
	gxio_uart_context_t *context = &tile_uart->context;
	struct tty_port *port = tty->port;

	count.word = gxio_uart_read(context, UART_FIFO_COUNT);
	for (i = 0; i < count.rfifo_count; i++) {
		c = (char)gxio_uart_read(context, UART_RECEIVE_DATA);
		tty_insert_flip_char(port, c, TTY_NORMAL);
	}
}


/*
 * Drain the Rx FIFO, called by interrupt handler.
 */
static void handle_receive(struct tile_uart_port *tile_uart)
{
	struct tty_port *port = &tile_uart->uart.state->port;
	struct tty_struct *tty = tty_port_tty_get(port);
	gxio_uart_context_t *context = &tile_uart->context;

	if (!tty)
		return;

	/* First read UART rx fifo. */
	receive_chars(tile_uart, tty);

	/* Reset RFIFO_WE interrupt. */
	gxio_uart_write(context, UART_INTERRUPT_STATUS,
			UART_INTERRUPT_MASK__RFIFO_WE_MASK);

	/* Final read, if any chars comes between the first read and
	 * the interrupt reset.
	 */
	receive_chars(tile_uart, tty);

	spin_unlock(&tile_uart->uart.lock);
	tty_flip_buffer_push(port);
	spin_lock(&tile_uart->uart.lock);
	tty_kref_put(tty);
}


/*
 * Push one char to UART Write FIFO.
 * Return 0 on success, -1 if write filo is full.
 */
static int tilegx_putchar(gxio_uart_context_t *context, char c)
{
	UART_FLAG_t flag;
	flag.word = gxio_uart_read(context, UART_FLAG);
	if (flag.wfifo_full)
		return -1;

	gxio_uart_write(context, UART_TRANSMIT_DATA, (unsigned long)c);
	return 0;
}


/*
 * Send chars to UART Write FIFO; called by interrupt handler.
 */
static void handle_transmit(struct tile_uart_port *tile_uart)
{
	unsigned char ch;
	struct uart_port *port;
	struct circ_buf *xmit;
	gxio_uart_context_t *context = &tile_uart->context;

	/* First reset WFIFO_RE interrupt. */
	gxio_uart_write(context, UART_INTERRUPT_STATUS,
			UART_INTERRUPT_MASK__WFIFO_RE_MASK);

	port = &tile_uart->uart;
	xmit = &port->state->xmit;
	if (port->x_char) {
		if (tilegx_putchar(context, port->x_char))
			return;
		port->x_char = 0;
		port->icount.tx++;
	}

	if (uart_circ_empty(xmit) || uart_tx_stopped(port))
		return;

	while (!uart_circ_empty(xmit)) {
		ch = xmit->buf[xmit->tail];
		if (tilegx_putchar(context, ch))
			break;
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		port->icount.tx++;
	}

	/* Reset WFIFO_RE interrupt. */
	gxio_uart_write(context, UART_INTERRUPT_STATUS,
			UART_INTERRUPT_MASK__WFIFO_RE_MASK);

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);
}


/*
 * UART Interrupt handler.
 */
static irqreturn_t tilegx_interrupt(int irq, void *dev_id)
{
	unsigned long flags;
	UART_INTERRUPT_STATUS_t intr_stat;
	struct tile_uart_port *tile_uart;
	gxio_uart_context_t *context;
	struct uart_port *port = dev_id;
	irqreturn_t ret = IRQ_NONE;

	spin_lock_irqsave(&port->lock, flags);

	tile_uart = container_of(port, struct tile_uart_port, uart);
	context = &tile_uart->context;
	intr_stat.word = gxio_uart_read(context, UART_INTERRUPT_STATUS);

	if (intr_stat.rfifo_we) {
		handle_receive(tile_uart);
		ret = IRQ_HANDLED;
	}
	if (intr_stat.wfifo_re) {
		handle_transmit(tile_uart);
		ret = IRQ_HANDLED;
	}

	spin_unlock_irqrestore(&port->lock, flags);
	return ret;
}


/*
 * Return TIOCSER_TEMT when transmitter FIFO is empty.
 */
static u_int tilegx_tx_empty(struct uart_port *port)
{
	int ret;
	UART_FLAG_t flag;
	struct tile_uart_port *tile_uart;
	gxio_uart_context_t *context;

	tile_uart = container_of(port, struct tile_uart_port, uart);
	if (!mutex_trylock(&tile_uart->mutex))
		return 0;
	context = &tile_uart->context;

	flag.word = gxio_uart_read(context, UART_FLAG);
	ret = (flag.wfifo_empty) ? TIOCSER_TEMT : 0;
	mutex_unlock(&tile_uart->mutex);

	return ret;
}


/*
 * Set state of the modem control output lines.
 */
static void tilegx_set_mctrl(struct uart_port *port, u_int mctrl)
{
	/* N/A */
}


/*
 * Get state of the modem control input lines.
 */
static u_int tilegx_get_mctrl(struct uart_port *port)
{
	return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
}


/*
 * Stop transmitting.
 */
static void tilegx_stop_tx(struct uart_port *port)
{
	/* N/A */
}


/*
 * Start transmitting.
 */
static void tilegx_start_tx(struct uart_port *port)
{
	unsigned char ch;
	struct circ_buf *xmit;
	struct tile_uart_port *tile_uart;
	gxio_uart_context_t *context;

	tile_uart = container_of(port, struct tile_uart_port, uart);
	if (!mutex_trylock(&tile_uart->mutex))
		return;
	context = &tile_uart->context;
	xmit = &port->state->xmit;
	if (port->x_char) {
		if (tilegx_putchar(context, port->x_char))
			return;
		port->x_char = 0;
		port->icount.tx++;
	}

	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
		mutex_unlock(&tile_uart->mutex);
		return;
	}

	while (!uart_circ_empty(xmit)) {
		ch = xmit->buf[xmit->tail];
		if (tilegx_putchar(context, ch))
			break;
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		port->icount.tx++;
	}

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);

	mutex_unlock(&tile_uart->mutex);
}


/*
 * Stop receiving - port is in process of being closed.
 */
static void tilegx_stop_rx(struct uart_port *port)
{
	int err;
	struct tile_uart_port *tile_uart;
	gxio_uart_context_t *context;
	int cpu;

	tile_uart = container_of(port, struct tile_uart_port, uart);
	if (!mutex_trylock(&tile_uart->mutex))
		return;

	context = &tile_uart->context;
	cpu = tile_uart->irq_cpu;
	err = gxio_uart_cfg_interrupt(context, cpu_x(cpu), cpu_y(cpu),
				      KERNEL_PL, -1);
	mutex_unlock(&tile_uart->mutex);
}

/*
 * Control the transmission of a break signal.
 */
static void tilegx_break_ctl(struct uart_port *port, int break_state)
{
	/* N/A */
}


/*
 * Perform initialization and enable port for reception.
 */
static int tilegx_startup(struct uart_port *port)
{
	struct tile_uart_port *tile_uart;
	gxio_uart_context_t *context;
	int ret = 0;
	int cpu = raw_smp_processor_id();  /* pick an arbitrary cpu */

	tile_uart = container_of(port, struct tile_uart_port, uart);
	if (mutex_lock_interruptible(&tile_uart->mutex))
		return -EBUSY;
	context = &tile_uart->context;

	/* Now open the hypervisor device if we haven't already. */
	if (context->fd < 0) {
		UART_INTERRUPT_MASK_t intr_mask;

		/* Initialize UART device. */
		ret = gxio_uart_init(context, port->line);
		if (ret) {
			ret = -ENXIO;
			goto err;
		}

		/* Create our IRQs. */
		port->irq = irq_alloc_hwirq(-1);
		if (!port->irq)
			goto err_uart_dest;
		tile_irq_activate(port->irq, TILE_IRQ_PERCPU);

		/* Register our IRQs. */
		ret = request_irq(port->irq, tilegx_interrupt, 0,
				  tilegx_uart_driver.driver_name, port);
		if (ret)
			goto err_dest_irq;

		/* Request that the hardware start sending us interrupts. */
		tile_uart->irq_cpu = cpu;
		ret = gxio_uart_cfg_interrupt(context, cpu_x(cpu), cpu_y(cpu),
					      KERNEL_PL, port->irq);
		if (ret)
			goto err_free_irq;

		/* Enable UART Tx/Rx Interrupt. */
		intr_mask.word = gxio_uart_read(context, UART_INTERRUPT_MASK);
		intr_mask.wfifo_re = 0;
		intr_mask.rfifo_we = 0;
		gxio_uart_write(context, UART_INTERRUPT_MASK, intr_mask.word);

		/* Reset the Tx/Rx interrupt in case it's set. */
		gxio_uart_write(context, UART_INTERRUPT_STATUS,
				UART_INTERRUPT_MASK__WFIFO_RE_MASK |
				UART_INTERRUPT_MASK__RFIFO_WE_MASK);
	}

	mutex_unlock(&tile_uart->mutex);
	return ret;

err_free_irq:
	free_irq(port->irq, port);
err_dest_irq:
	irq_free_hwirq(port->irq);
err_uart_dest:
	gxio_uart_destroy(context);
	ret = -ENXIO;
err:
	mutex_unlock(&tile_uart->mutex);
	return ret;
}


/*
 * Release kernel resources if it is the last close, disable the port,
 * free IRQ and close the port.
 */
static void tilegx_shutdown(struct uart_port *port)
{
	int err;
	UART_INTERRUPT_MASK_t intr_mask;
	struct tile_uart_port *tile_uart;
	gxio_uart_context_t *context;
	int cpu;

	tile_uart = container_of(port, struct tile_uart_port, uart);
	if (mutex_lock_interruptible(&tile_uart->mutex))
		return;
	context = &tile_uart->context;

	/* Disable UART Tx/Rx Interrupt. */
	intr_mask.word = gxio_uart_read(context, UART_INTERRUPT_MASK);
	intr_mask.wfifo_re = 1;
	intr_mask.rfifo_we = 1;
	gxio_uart_write(context, UART_INTERRUPT_MASK, intr_mask.word);

	/* Request that the hardware stop sending us interrupts. */
	cpu = tile_uart->irq_cpu;
	err = gxio_uart_cfg_interrupt(context, cpu_x(cpu), cpu_y(cpu),
				      KERNEL_PL, -1);

	if (port->irq > 0) {
		free_irq(port->irq, port);
		irq_free_hwirq(port->irq);
		port->irq = 0;
	}

	gxio_uart_destroy(context);

	mutex_unlock(&tile_uart->mutex);
}


/*
 * Flush the buffer.
 */
static void tilegx_flush_buffer(struct uart_port *port)
{
	/* N/A */
}


/*
 * Change the port parameters.
 */
static void tilegx_set_termios(struct uart_port *port,
			       struct ktermios *termios, struct ktermios *old)
{
	int err;
	UART_DIVISOR_t divisor;
	UART_TYPE_t type;
	unsigned int baud;
	struct tile_uart_port *tile_uart;
	gxio_uart_context_t *context;

	tile_uart = container_of(port, struct tile_uart_port, uart);
	if (!mutex_trylock(&tile_uart->mutex))
		return;
	context = &tile_uart->context;

	/* Open the hypervisor device if we haven't already. */
	if (context->fd < 0) {
		err = gxio_uart_init(context, port->line);
		if (err) {
			mutex_unlock(&tile_uart->mutex);
			return;
		}
	}

	divisor.word = gxio_uart_read(context, UART_DIVISOR);
	type.word = gxio_uart_read(context, UART_TYPE);

	/* Divisor. */
	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
	divisor.divisor = uart_get_divisor(port, baud);

	/* Byte size. */
	if ((termios->c_cflag & CSIZE) == CS7)
		type.dbits = UART_TYPE__DBITS_VAL_SEVEN_DBITS;
	else
		type.dbits = UART_TYPE__DBITS_VAL_EIGHT_DBITS;

	/* Parity. */
	if (termios->c_cflag & PARENB) {
		/* Mark or Space parity. */
		if (termios->c_cflag & CMSPAR)
			if (termios->c_cflag & PARODD)
				type.ptype = UART_TYPE__PTYPE_VAL_MARK;
			else
				type.ptype = UART_TYPE__PTYPE_VAL_SPACE;
		else if (termios->c_cflag & PARODD)
			type.ptype = UART_TYPE__PTYPE_VAL_ODD;
		else
			type.ptype = UART_TYPE__PTYPE_VAL_EVEN;
	} else
		type.ptype = UART_TYPE__PTYPE_VAL_NONE;

	/* Stop bits. */
	if (termios->c_cflag & CSTOPB)
		type.sbits = UART_TYPE__SBITS_VAL_TWO_SBITS;
	else
		type.sbits = UART_TYPE__SBITS_VAL_ONE_SBITS;

	/* Set the uart paramters. */
	gxio_uart_write(context, UART_DIVISOR, divisor.word);
	gxio_uart_write(context, UART_TYPE, type.word);

	mutex_unlock(&tile_uart->mutex);
}


/*
 * Return string describing the specified port.
 */
static const char *tilegx_type(struct uart_port *port)
{
	return port->type == PORT_TILEGX ? DRIVER_NAME_STRING : NULL;
}


/*
 * Release the resources being used by 'port'.
 */
static void tilegx_release_port(struct uart_port *port)
{
	/* Nothing to release. */
}


/*
 * Request the resources being used by 'port'.
 */
static int tilegx_request_port(struct uart_port *port)
{
	/* Always present. */
	return 0;
}


/*
 * Configure/autoconfigure the port.
 */
static void tilegx_config_port(struct uart_port *port, int flags)
{
	if (flags & UART_CONFIG_TYPE)
		port->type = PORT_TILEGX;
}


/*
 * Verify the new serial_struct (for TIOCSSERIAL).
 */
static int tilegx_verify_port(struct uart_port *port,
			      struct serial_struct *ser)
{
	if ((ser->type != PORT_UNKNOWN) && (ser->type != PORT_TILEGX))
		return -EINVAL;

	return 0;
}

#ifdef CONFIG_CONSOLE_POLL

/*
 * Console polling routines for writing and reading from the uart while
 * in an interrupt or debug context.
 */

static int tilegx_poll_get_char(struct uart_port *port)
{
	UART_FIFO_COUNT_t count;
	gxio_uart_context_t *context;
	struct tile_uart_port *tile_uart;

	tile_uart = container_of(port, struct tile_uart_port, uart);
	context = &tile_uart->context;
	count.word = gxio_uart_read(context, UART_FIFO_COUNT);
	if (count.rfifo_count == 0)
		return NO_POLL_CHAR;
	return (char)gxio_uart_read(context, UART_RECEIVE_DATA);
}

static void tilegx_poll_put_char(struct uart_port *port, unsigned char c)
{
	gxio_uart_context_t *context;
	struct tile_uart_port *tile_uart;

	tile_uart = container_of(port, struct tile_uart_port, uart);
	context = &tile_uart->context;
	gxio_uart_write(context, UART_TRANSMIT_DATA, (unsigned long)c);
}

#endif /* CONFIG_CONSOLE_POLL */


static const struct uart_ops tilegx_ops = {
	.tx_empty	= tilegx_tx_empty,
	.set_mctrl	= tilegx_set_mctrl,
	.get_mctrl	= tilegx_get_mctrl,
	.stop_tx	= tilegx_stop_tx,
	.start_tx	= tilegx_start_tx,
	.stop_rx	= tilegx_stop_rx,
	.break_ctl	= tilegx_break_ctl,
	.startup	= tilegx_startup,
	.shutdown	= tilegx_shutdown,
	.flush_buffer	= tilegx_flush_buffer,
	.set_termios	= tilegx_set_termios,
	.type		= tilegx_type,
	.release_port	= tilegx_release_port,
	.request_port	= tilegx_request_port,
	.config_port	= tilegx_config_port,
	.verify_port	= tilegx_verify_port,
#ifdef CONFIG_CONSOLE_POLL
	.poll_get_char	= tilegx_poll_get_char,
	.poll_put_char	= tilegx_poll_put_char,
#endif
};


static void tilegx_init_ports(void)
{
	int i;
	struct uart_port *port;

	for (i = 0; i < TILEGX_UART_NR; i++) {
		port = &tile_uart_ports[i].uart;
		port->ops = &tilegx_ops;
		port->line = i;
		port->type = PORT_TILEGX;
		port->uartclk = TILEGX_UART_REF_CLK;
		port->flags = UPF_BOOT_AUTOCONF;

		tile_uart_ports[i].context.fd = -1;
		mutex_init(&tile_uart_ports[i].mutex);
	}
}


static struct uart_driver tilegx_uart_driver = {
	.owner		= THIS_MODULE,
	.driver_name	= DRIVER_NAME_STRING,
	.dev_name	= TILEGX_UART_NAME,
	.major		= TILEGX_UART_MAJOR,
	.minor		= TILEGX_UART_MINOR,
	.nr		= TILEGX_UART_NR,
};


static int __init tilegx_init(void)
{
	int i;
	int ret;
	struct tty_driver *tty_drv;

	ret = uart_register_driver(&tilegx_uart_driver);
	if (ret)
		return ret;
	tty_drv = tilegx_uart_driver.tty_driver;
	tty_drv->init_termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
	tty_drv->init_termios.c_ispeed = 115200;
	tty_drv->init_termios.c_ospeed = 115200;

	tilegx_init_ports();

	for (i = 0; i < TILEGX_UART_NR; i++) {
		struct uart_port *port = &tile_uart_ports[i].uart;
		ret = uart_add_one_port(&tilegx_uart_driver, port);
	}

	return 0;
}


static void __exit tilegx_exit(void)
{
	int i;
	struct uart_port *port;

	for (i = 0; i < TILEGX_UART_NR; i++) {
		port = &tile_uart_ports[i].uart;
		uart_remove_one_port(&tilegx_uart_driver, port);
	}

	uart_unregister_driver(&tilegx_uart_driver);
}


module_init(tilegx_init);
module_exit(tilegx_exit);

MODULE_AUTHOR("Tilera Corporation");
MODULE_DESCRIPTION("TILEGx serial port driver");
MODULE_LICENSE("GPL");
