/*
 * (c) 2004 Sascha Hauer <sascha@saschahauer.de>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <asm/arch/imx-regs.h>
#include <serial.h>
#include <linux/compiler.h>

#if defined CONFIG_IMX_SERIAL1
#define UART_BASE IMX_UART1_BASE
#elif defined CONFIG_IMX_SERIAL2
#define UART_BASE IMX_UART2_BASE
#else
#error "define CONFIG_IMX_SERIAL1, CONFIG_IMX_SERIAL2 or CONFIG_IMX_SERIAL_NONE"
#endif

struct imx_serial {
	volatile uint32_t urxd[16];
	volatile uint32_t utxd[16];
	volatile uint32_t ucr1;
	volatile uint32_t ucr2;
	volatile uint32_t ucr3;
	volatile uint32_t ucr4;
	volatile uint32_t ufcr;
	volatile uint32_t usr1;
	volatile uint32_t usr2;
	volatile uint32_t uesc;
	volatile uint32_t utim;
	volatile uint32_t ubir;
	volatile uint32_t ubmr;
	volatile uint32_t ubrc;
	volatile uint32_t bipr[4];
	volatile uint32_t bmpr[4];
	volatile uint32_t uts;
};

DECLARE_GLOBAL_DATA_PTR;

static void imx_serial_setbrg(void)
{
	serial_init();
}

extern void imx_gpio_mode(int gpio_mode);

/*
 * Initialise the serial port with the given baudrate. The settings
 * are always 8 data bits, no parity, 1 stop bit, no start bits.
 *
 */
static int imx_serial_init(void)
{
	volatile struct imx_serial* base = (struct imx_serial *)UART_BASE;
	unsigned int ufcr_rfdiv;
	unsigned int refclk;

#ifdef CONFIG_IMX_SERIAL1
	imx_gpio_mode(PC11_PF_UART1_TXD);
	imx_gpio_mode(PC12_PF_UART1_RXD);
#else
	imx_gpio_mode(PB30_PF_UART2_TXD);
	imx_gpio_mode(PB31_PF_UART2_RXD);
#endif

	/* Disable UART */
	base->ucr1 &= ~UCR1_UARTEN;

	/* Set to default POR state */

	base->ucr1 = 0x00000004;
	base->ucr2 = 0x00000000;
	base->ucr3 = 0x00000000;
	base->ucr4 = 0x00008040;
	base->uesc = 0x0000002B;
	base->utim = 0x00000000;
	base->ubir = 0x00000000;
	base->ubmr = 0x00000000;
	base->uts  = 0x00000000;
	/* Set clocks */
	base->ucr4 |= UCR4_REF16;

	/* Configure FIFOs */
	base->ufcr = 0xa81;

	/* set the baud rate.
	 *
	 * baud * 16   x
	 * --------- = -
	 *  refclk     y
	 *
	 * x - 1 = UBIR
	 * y - 1 = UBMR
	 *
	 * each register is 16 bits wide. refclk max is 96 MHz
	 *
	 */

	ufcr_rfdiv = ((base->ufcr) & UFCR_RFDIV) >> 7;
	if (ufcr_rfdiv == 6)
		ufcr_rfdiv = 7;
	else
		ufcr_rfdiv = 6 - ufcr_rfdiv;

	refclk = get_PERCLK1();
	refclk /= ufcr_rfdiv;

	/* Set the numerator value minus one of the BRM ratio */
	base->ubir = (gd->baudrate / 100) - 1;

	/* Set the denominator value minus one of the BRM ratio	*/
	base->ubmr = (refclk/(16 * 100)) - 1;

	/* Set to 8N1 */
	base->ucr2 &= ~UCR2_PREN;
	base->ucr2 |= UCR2_WS;
	base->ucr2 &= ~UCR2_STPB;

	/* Ignore RTS */
	base->ucr2 |= UCR2_IRTS;

	/* Enable UART */
	base->ucr1 |= UCR1_UARTEN | UCR1_UARTCLKEN;

	/* Enable FIFOs */
	base->ucr2 |= UCR2_SRST | UCR2_RXEN | UCR2_TXEN;

	/* Clear status flags */
	base->usr2 |= USR2_ADET  |
		      USR2_DTRF  |
		      USR2_IDLE  |
		      USR2_IRINT |
		      USR2_WAKE  |
		      USR2_RTSF  |
		      USR2_BRCD  |
		      USR2_ORE;

	/* Clear status flags */
	base->usr1 |= USR1_PARITYERR |
		      USR1_RTSD      |
		      USR1_ESCF      |
		      USR1_FRAMERR   |
		      USR1_AIRINT    |
		      USR1_AWAKE;
	return (0);
}

/*
 * Read a single byte from the serial port. Returns 1 on success, 0
 * otherwise. When the function is successful, the character read is
 * written into its argument c.
 */
static int imx_serial_getc(void)
{
	volatile struct imx_serial* base = (struct imx_serial *)UART_BASE;
	unsigned char ch;

	while(base->uts & UTS_RXEMPTY);

	ch = (char)base->urxd[0];

	return ch;
}

#ifdef CONFIG_HWFLOW
static int hwflow = 0; /* turned off by default */
int hwflow_onoff(int on)
{
}
#endif

/*
 * Output a single byte to the serial port.
 */
static void imx_serial_putc(const char c)
{
	volatile struct imx_serial* base = (struct imx_serial *)UART_BASE;

	/* Wait for Tx FIFO not full */
	while (base->uts & UTS_TXFULL);

	base->utxd[0] = c;

	/* If \n, also do \r */
	if (c == '\n')
		serial_putc ('\r');
}

/*
 * Test whether a character is in the RX buffer
 */
static int imx_serial_tstc(void)
{
	volatile struct imx_serial* base = (struct imx_serial *)UART_BASE;

	/* If receive fifo is empty, return false */
	if (base->uts & UTS_RXEMPTY)
		return 0;
	return 1;
}

static struct serial_device imx_serial_drv = {
	.name	= "imx_serial",
	.start	= imx_serial_init,
	.stop	= NULL,
	.setbrg	= imx_serial_setbrg,
	.putc	= imx_serial_putc,
	.puts	= default_serial_puts,
	.getc	= imx_serial_getc,
	.tstc	= imx_serial_tstc,
};

void imx_serial_initialize(void)
{
	serial_register(&imx_serial_drv);
}

__weak struct serial_device *default_serial_console(void)
{
	return &imx_serial_drv;
}
