/*
 * Copyright 2013 Freescale Semiconductor, Inc.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <dm.h>
#include <fsl_lpuart.h>
#include <watchdog.h>
#include <asm/io.h>
#include <serial.h>
#include <linux/compiler.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/clock.h>

#define US1_TDRE	(1 << 7)
#define US1_RDRF	(1 << 5)
#define US1_OR		(1 << 3)
#define UC2_TE		(1 << 3)
#define UC2_RE		(1 << 2)
#define CFIFO_TXFLUSH	(1 << 7)
#define CFIFO_RXFLUSH	(1 << 6)
#define SFIFO_RXOF	(1 << 2)
#define SFIFO_RXUF	(1 << 0)

#define STAT_LBKDIF	(1 << 31)
#define STAT_RXEDGIF	(1 << 30)
#define STAT_TDRE	(1 << 23)
#define STAT_RDRF	(1 << 21)
#define STAT_IDLE	(1 << 20)
#define STAT_OR		(1 << 19)
#define STAT_NF		(1 << 18)
#define STAT_FE		(1 << 17)
#define STAT_PF		(1 << 16)
#define STAT_MA1F	(1 << 15)
#define STAT_MA2F	(1 << 14)
#define STAT_FLAGS	(STAT_LBKDIF | STAT_RXEDGIF | STAT_IDLE | STAT_OR | \
			 STAT_NF | STAT_FE | STAT_PF | STAT_MA1F | STAT_MA2F)

#define CTRL_TE		(1 << 19)
#define CTRL_RE		(1 << 18)

#define FIFO_TXFE		0x80
#define FIFO_RXFE		0x40

#define WATER_TXWATER_OFF	1
#define WATER_RXWATER_OFF	16

DECLARE_GLOBAL_DATA_PTR;

#define LPUART_FLAG_REGMAP_32BIT_REG	BIT(0)
#define LPUART_FLAG_REGMAP_ENDIAN_BIG	BIT(1)

enum lpuart_devtype {
	DEV_VF610 = 1,
	DEV_LS1021A,
	DEV_MX7ULP
};

struct lpuart_serial_platdata {
	void *reg;
	enum lpuart_devtype devtype;
	ulong flags;
};

static void lpuart_read32(u32 flags, u32 *addr, u32 *val)
{
	if (flags & LPUART_FLAG_REGMAP_32BIT_REG) {
		if (flags & LPUART_FLAG_REGMAP_ENDIAN_BIG)
			*(u32 *)val = in_be32(addr);
		else
			*(u32 *)val = in_le32(addr);
	}
}

static void lpuart_write32(u32 flags, u32 *addr, u32 val)
{
	if (flags & LPUART_FLAG_REGMAP_32BIT_REG) {
		if (flags & LPUART_FLAG_REGMAP_ENDIAN_BIG)
			out_be32(addr, val);
		else
			out_le32(addr, val);
	}
}


#ifndef CONFIG_SYS_CLK_FREQ
#define CONFIG_SYS_CLK_FREQ	0
#endif

u32 __weak get_lpuart_clk(void)
{
	return CONFIG_SYS_CLK_FREQ;
}

static bool is_lpuart32(struct udevice *dev)
{
	struct lpuart_serial_platdata *plat = dev->platdata;

	return plat->flags & LPUART_FLAG_REGMAP_32BIT_REG;
}

static void _lpuart_serial_setbrg(struct lpuart_serial_platdata *plat,
				  int baudrate)
{
	struct lpuart_fsl *base = plat->reg;
	u32 clk = get_lpuart_clk();
	u16 sbr;

	sbr = (u16)(clk / (16 * baudrate));

	/* place adjustment later - n/32 BRFA */
	__raw_writeb(sbr >> 8, &base->ubdh);
	__raw_writeb(sbr & 0xff, &base->ubdl);
}

static int _lpuart_serial_getc(struct lpuart_serial_platdata *plat)
{
	struct lpuart_fsl *base = plat->reg;
	while (!(__raw_readb(&base->us1) & (US1_RDRF | US1_OR)))
		WATCHDOG_RESET();

	barrier();

	return __raw_readb(&base->ud);
}

static void _lpuart_serial_putc(struct lpuart_serial_platdata *plat,
				const char c)
{
	struct lpuart_fsl *base = plat->reg;

	while (!(__raw_readb(&base->us1) & US1_TDRE))
		WATCHDOG_RESET();

	__raw_writeb(c, &base->ud);
}

/* Test whether a character is in the RX buffer */
static int _lpuart_serial_tstc(struct lpuart_serial_platdata *plat)
{
	struct lpuart_fsl *base = plat->reg;

	if (__raw_readb(&base->urcfifo) == 0)
		return 0;

	return 1;
}

/*
 * 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 _lpuart_serial_init(struct lpuart_serial_platdata *plat)
{
	struct lpuart_fsl *base = (struct lpuart_fsl *)plat->reg;
	u8 ctrl;

	ctrl = __raw_readb(&base->uc2);
	ctrl &= ~UC2_RE;
	ctrl &= ~UC2_TE;
	__raw_writeb(ctrl, &base->uc2);

	__raw_writeb(0, &base->umodem);
	__raw_writeb(0, &base->uc1);

	/* Disable FIFO and flush buffer */
	__raw_writeb(0x0, &base->upfifo);
	__raw_writeb(0x0, &base->utwfifo);
	__raw_writeb(0x1, &base->urwfifo);
	__raw_writeb(CFIFO_TXFLUSH | CFIFO_RXFLUSH, &base->ucfifo);

	/* provide data bits, parity, stop bit, etc */
	_lpuart_serial_setbrg(plat, gd->baudrate);

	__raw_writeb(UC2_RE | UC2_TE, &base->uc2);

	return 0;
}

static void _lpuart32_serial_setbrg_7ulp(struct lpuart_serial_platdata *plat,
					 int baudrate)
{
	struct lpuart_fsl_reg32 *base = plat->reg;
	u32 sbr, osr, baud_diff, tmp_osr, tmp_sbr, tmp_diff, tmp;
	u32 clk = get_lpuart_clk();

	baud_diff = baudrate;
	osr = 0;
	sbr = 0;

	for (tmp_osr = 4; tmp_osr <= 32; tmp_osr++) {
		tmp_sbr = (clk / (baudrate * tmp_osr));

		if (tmp_sbr == 0)
			tmp_sbr = 1;

		/*calculate difference in actual buad w/ current values */
		tmp_diff = (clk / (tmp_osr * tmp_sbr));
		tmp_diff = tmp_diff - baudrate;

		/* select best values between sbr and sbr+1 */
		if (tmp_diff > (baudrate - (clk / (tmp_osr * (tmp_sbr + 1))))) {
			tmp_diff = baudrate - (clk / (tmp_osr * (tmp_sbr + 1)));
			tmp_sbr++;
		}

		if (tmp_diff <= baud_diff) {
			baud_diff = tmp_diff;
			osr = tmp_osr;
			sbr = tmp_sbr;
		}
	}

	/*
	 * TODO: handle buadrate outside acceptable rate
	 * if (baudDiff > ((config->baudRate_Bps / 100) * 3))
	 * {
	 *   Unacceptable baud rate difference of more than 3%
	 *   return kStatus_LPUART_BaudrateNotSupport;
	 * }
	 */
	tmp = in_le32(&base->baud);

	if ((osr > 3) && (osr < 8))
		tmp |= LPUART_BAUD_BOTHEDGE_MASK;

	tmp &= ~LPUART_BAUD_OSR_MASK;
	tmp |= LPUART_BAUD_OSR(osr-1);

	tmp &= ~LPUART_BAUD_SBR_MASK;
	tmp |= LPUART_BAUD_SBR(sbr);

	/* explicitly disable 10 bit mode & set 1 stop bit */
	tmp &= ~(LPUART_BAUD_M10_MASK | LPUART_BAUD_SBNS_MASK);

	out_le32(&base->baud, tmp);
}

static void _lpuart32_serial_setbrg(struct lpuart_serial_platdata *plat,
				    int baudrate)
{
	struct lpuart_fsl_reg32 *base = plat->reg;
	u32 clk = get_lpuart_clk();
	u32 sbr;

	sbr = (clk / (16 * baudrate));

	/* place adjustment later - n/32 BRFA */
	lpuart_write32(plat->flags, &base->baud, sbr);
}

static int _lpuart32_serial_getc(struct lpuart_serial_platdata *plat)
{
	struct lpuart_fsl_reg32 *base = plat->reg;
	u32 stat, val;

	lpuart_read32(plat->flags, &base->stat, &stat);
	while ((stat & STAT_RDRF) == 0) {
		lpuart_write32(plat->flags, &base->stat, STAT_FLAGS);
		WATCHDOG_RESET();
		lpuart_read32(plat->flags, &base->stat, &stat);
	}

	lpuart_read32(plat->flags, &base->data, &val);

	lpuart_read32(plat->flags, &base->stat, &stat);
	if (stat & STAT_OR)
		lpuart_write32(plat->flags, &base->stat, STAT_OR);

	return val & 0x3ff;
}

static void _lpuart32_serial_putc(struct lpuart_serial_platdata *plat,
				  const char c)
{
	struct lpuart_fsl_reg32 *base = plat->reg;
	u32 stat;

	if (c == '\n')
		serial_putc('\r');

	while (true) {
		lpuart_read32(plat->flags, &base->stat, &stat);

		if ((stat & STAT_TDRE))
			break;

		WATCHDOG_RESET();
	}

	lpuart_write32(plat->flags, &base->data, c);
}

/* Test whether a character is in the RX buffer */
static int _lpuart32_serial_tstc(struct lpuart_serial_platdata *plat)
{
	struct lpuart_fsl_reg32 *base = plat->reg;
	u32 water;

	lpuart_read32(plat->flags, &base->water, &water);

	if ((water >> 24) == 0)
		return 0;

	return 1;
}

/*
 * 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 _lpuart32_serial_init(struct lpuart_serial_platdata *plat)
{
	struct lpuart_fsl_reg32 *base = (struct lpuart_fsl_reg32 *)plat->reg;
	u32 ctrl;

	lpuart_read32(plat->flags, &base->ctrl, &ctrl);
	ctrl &= ~CTRL_RE;
	ctrl &= ~CTRL_TE;
	lpuart_write32(plat->flags, &base->ctrl, ctrl);

	lpuart_write32(plat->flags, &base->modir, 0);
	lpuart_write32(plat->flags, &base->fifo, ~(FIFO_TXFE | FIFO_RXFE));

	lpuart_write32(plat->flags, &base->match, 0);

	if (plat->devtype == DEV_MX7ULP) {
		_lpuart32_serial_setbrg_7ulp(plat, gd->baudrate);
	} else {
		/* provide data bits, parity, stop bit, etc */
		_lpuart32_serial_setbrg(plat, gd->baudrate);
	}

	lpuart_write32(plat->flags, &base->ctrl, CTRL_RE | CTRL_TE);

	return 0;
}

static int lpuart_serial_setbrg(struct udevice *dev, int baudrate)
{
	struct lpuart_serial_platdata *plat = dev->platdata;

	if (is_lpuart32(dev)) {
		if (plat->devtype == DEV_MX7ULP)
			_lpuart32_serial_setbrg_7ulp(plat, baudrate);
		else
			_lpuart32_serial_setbrg(plat, baudrate);
	} else {
		_lpuart_serial_setbrg(plat, baudrate);
	}

	return 0;
}

static int lpuart_serial_getc(struct udevice *dev)
{
	struct lpuart_serial_platdata *plat = dev->platdata;

	if (is_lpuart32(dev))
		return _lpuart32_serial_getc(plat);

	return _lpuart_serial_getc(plat);
}

static int lpuart_serial_putc(struct udevice *dev, const char c)
{
	struct lpuart_serial_platdata *plat = dev->platdata;

	if (is_lpuart32(dev))
		_lpuart32_serial_putc(plat, c);
	else
		_lpuart_serial_putc(plat, c);

	return 0;
}

static int lpuart_serial_pending(struct udevice *dev, bool input)
{
	struct lpuart_serial_platdata *plat = dev->platdata;
	struct lpuart_fsl *reg = plat->reg;
	struct lpuart_fsl_reg32 *reg32 = plat->reg;
	u32 stat;

	if (is_lpuart32(dev)) {
		if (input) {
			return _lpuart32_serial_tstc(plat);
		} else {
			lpuart_read32(plat->flags, &reg32->stat, &stat);
			return stat & STAT_TDRE ? 0 : 1;
		}
	}

	if (input)
		return _lpuart_serial_tstc(plat);
	else
		return __raw_readb(&reg->us1) & US1_TDRE ? 0 : 1;
}

static int lpuart_serial_probe(struct udevice *dev)
{
	struct lpuart_serial_platdata *plat = dev->platdata;

	if (is_lpuart32(dev))
		return _lpuart32_serial_init(plat);
	else
		return _lpuart_serial_init(plat);
}

static int lpuart_serial_ofdata_to_platdata(struct udevice *dev)
{
	struct lpuart_serial_platdata *plat = dev->platdata;
	const void *blob = gd->fdt_blob;
	int node = dev_of_offset(dev);
	fdt_addr_t addr;

	addr = devfdt_get_addr(dev);
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;

	plat->reg = (void *)addr;
	plat->flags = dev_get_driver_data(dev);

	if (!fdt_node_check_compatible(blob, node, "fsl,ls1021a-lpuart"))
		plat->devtype = DEV_LS1021A;
	else if (!fdt_node_check_compatible(blob, node, "fsl,imx7ulp-lpuart"))
		plat->devtype = DEV_MX7ULP;
	else if (!fdt_node_check_compatible(blob, node, "fsl,vf610-lpuart"))
		plat->devtype = DEV_VF610;

	return 0;
}

static const struct dm_serial_ops lpuart_serial_ops = {
	.putc = lpuart_serial_putc,
	.pending = lpuart_serial_pending,
	.getc = lpuart_serial_getc,
	.setbrg = lpuart_serial_setbrg,
};

static const struct udevice_id lpuart_serial_ids[] = {
	{ .compatible = "fsl,ls1021a-lpuart", .data =
		LPUART_FLAG_REGMAP_32BIT_REG | LPUART_FLAG_REGMAP_ENDIAN_BIG },
	{ .compatible = "fsl,imx7ulp-lpuart",
		.data = LPUART_FLAG_REGMAP_32BIT_REG },
	{ .compatible = "fsl,vf610-lpuart"},
	{ }
};

U_BOOT_DRIVER(serial_lpuart) = {
	.name	= "serial_lpuart",
	.id	= UCLASS_SERIAL,
	.of_match = lpuart_serial_ids,
	.ofdata_to_platdata = lpuart_serial_ofdata_to_platdata,
	.platdata_auto_alloc_size = sizeof(struct lpuart_serial_platdata),
	.probe = lpuart_serial_probe,
	.ops	= &lpuart_serial_ops,
	.flags = DM_FLAG_PRE_RELOC,
};
