// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
 * Copyright (C) 2011-2012 Xilinx, Inc. All rights reserved.
 */

#include <clk.h>
#include <common.h>
#include <debug_uart.h>
#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
#include <log.h>
#include <watchdog.h>
#include <asm/io.h>
#include <dm/device_compat.h>
#include <linux/bitops.h>
#include <linux/compiler.h>
#include <serial.h>
#include <linux/err.h>

#define ZYNQ_UART_SR_TXACTIVE	BIT(11) /* TX active */
#define ZYNQ_UART_SR_TXFULL	BIT(4) /* TX FIFO full */
#define ZYNQ_UART_SR_RXEMPTY	BIT(1) /* RX FIFO empty */

#define ZYNQ_UART_CR_TX_EN	BIT(4) /* TX enabled */
#define ZYNQ_UART_CR_RX_EN	BIT(2) /* RX enabled */
#define ZYNQ_UART_CR_TXRST	BIT(1) /* TX logic reset */
#define ZYNQ_UART_CR_RXRST	BIT(0) /* RX logic reset */

#define ZYNQ_UART_MR_STOPMODE_2_BIT	0x00000080  /* 2 stop bits */
#define ZYNQ_UART_MR_STOPMODE_1_5_BIT	0x00000040  /* 1.5 stop bits */
#define ZYNQ_UART_MR_STOPMODE_1_BIT	0x00000000  /* 1 stop bit */

#define ZYNQ_UART_MR_PARITY_NONE	0x00000020  /* No parity mode */
#define ZYNQ_UART_MR_PARITY_ODD		0x00000008  /* Odd parity mode */
#define ZYNQ_UART_MR_PARITY_EVEN	0x00000000  /* Even parity mode */

#define ZYNQ_UART_MR_CHARLEN_6_BIT	0x00000006  /* 6 bits data */
#define ZYNQ_UART_MR_CHARLEN_7_BIT	0x00000004  /* 7 bits data */
#define ZYNQ_UART_MR_CHARLEN_8_BIT	0x00000000  /* 8 bits data */

struct uart_zynq {
	u32 control; /* 0x0 - Control Register [8:0] */
	u32 mode; /* 0x4 - Mode Register [10:0] */
	u32 reserved1[4];
	u32 baud_rate_gen; /* 0x18 - Baud Rate Generator [15:0] */
	u32 reserved2[4];
	u32 channel_sts; /* 0x2c - Channel Status [11:0] */
	u32 tx_rx_fifo; /* 0x30 - FIFO [15:0] or [7:0] */
	u32 baud_rate_divider; /* 0x34 - Baud Rate Divider [7:0] */
};

struct zynq_uart_plat {
	struct uart_zynq *regs;
};

/* Set up the baud rate */
static void _uart_zynq_serial_setbrg(struct uart_zynq *regs,
				     unsigned long clock, unsigned long baud)
{
	/* Calculation results. */
	unsigned int calc_bauderror, bdiv, bgen;
	unsigned long calc_baud = 0;

	/* Covering case where input clock is so slow */
	if (clock < 1000000 && baud > 4800)
		baud = 4800;

	/*                master clock
	 * Baud rate = ------------------
	 *              bgen * (bdiv + 1)
	 *
	 * Find acceptable values for baud generation.
	 */
	for (bdiv = 4; bdiv < 255; bdiv++) {
		bgen = clock / (baud * (bdiv + 1));
		if (bgen < 2 || bgen > 65535)
			continue;

		calc_baud = clock / (bgen * (bdiv + 1));

		/*
		 * Use first calculated baudrate with
		 * an acceptable (<3%) error
		 */
		if (baud > calc_baud)
			calc_bauderror = baud - calc_baud;
		else
			calc_bauderror = calc_baud - baud;
		if (((calc_bauderror * 100) / baud) < 3)
			break;
	}

	writel(bdiv, &regs->baud_rate_divider);
	writel(bgen, &regs->baud_rate_gen);
}

/* Initialize the UART, with...some settings. */
static void _uart_zynq_serial_init(struct uart_zynq *regs)
{
	/* RX/TX enabled & reset */
	writel(ZYNQ_UART_CR_TX_EN | ZYNQ_UART_CR_RX_EN | ZYNQ_UART_CR_TXRST | \
					ZYNQ_UART_CR_RXRST, &regs->control);
	writel(ZYNQ_UART_MR_PARITY_NONE, &regs->mode); /* 8 bit, no parity */
}

static int _uart_zynq_serial_putc(struct uart_zynq *regs, const char c)
{
	if (readl(&regs->channel_sts) & ZYNQ_UART_SR_TXFULL)
		return -EAGAIN;

	writel(c, &regs->tx_rx_fifo);

	return 0;
}

static int zynq_serial_setbrg(struct udevice *dev, int baudrate)
{
	struct zynq_uart_plat *plat = dev_get_plat(dev);
	unsigned long clock;

	int ret;
	struct clk clk;

	ret = clk_get_by_index(dev, 0, &clk);
	if (ret < 0) {
		dev_err(dev, "failed to get clock\n");
		return ret;
	}

	clock = clk_get_rate(&clk);
	if (IS_ERR_VALUE(clock)) {
		dev_err(dev, "failed to get rate\n");
		return clock;
	}
	debug("%s: CLK %ld\n", __func__, clock);

	ret = clk_enable(&clk);
	if (ret) {
		dev_err(dev, "failed to enable clock\n");
		return ret;
	}

	_uart_zynq_serial_setbrg(plat->regs, clock, baudrate);

	return 0;
}

#if !defined(CONFIG_SPL_BUILD)
static int zynq_serial_setconfig(struct udevice *dev, uint serial_config)
{
	struct zynq_uart_plat *plat = dev_get_plat(dev);
	struct uart_zynq *regs = plat->regs;
	u32 val = 0;

	switch (SERIAL_GET_BITS(serial_config)) {
	case SERIAL_6_BITS:
		val |= ZYNQ_UART_MR_CHARLEN_6_BIT;
		break;
	case SERIAL_7_BITS:
		val |= ZYNQ_UART_MR_CHARLEN_7_BIT;
		break;
	case SERIAL_8_BITS:
		val |= ZYNQ_UART_MR_CHARLEN_8_BIT;
		break;
	default:
		return -ENOTSUPP; /* not supported in driver */
	}

	switch (SERIAL_GET_STOP(serial_config)) {
	case SERIAL_ONE_STOP:
		val |= ZYNQ_UART_MR_STOPMODE_1_BIT;
		break;
	case SERIAL_ONE_HALF_STOP:
		val |= ZYNQ_UART_MR_STOPMODE_1_5_BIT;
		break;
	case SERIAL_TWO_STOP:
		val |= ZYNQ_UART_MR_STOPMODE_2_BIT;
		break;
	default:
		return -ENOTSUPP; /* not supported in driver */
	}

	switch (SERIAL_GET_PARITY(serial_config)) {
	case SERIAL_PAR_NONE:
		val |= ZYNQ_UART_MR_PARITY_NONE;
		break;
	case SERIAL_PAR_ODD:
		val |= ZYNQ_UART_MR_PARITY_ODD;
		break;
	case SERIAL_PAR_EVEN:
		val |= ZYNQ_UART_MR_PARITY_EVEN;
		break;
	default:
		return -ENOTSUPP; /* not supported in driver */
	}

	writel(val, &regs->mode);

	return 0;
}
#else
#define zynq_serial_setconfig NULL
#endif

static int zynq_serial_probe(struct udevice *dev)
{
	struct zynq_uart_plat *plat = dev_get_plat(dev);
	struct uart_zynq *regs = plat->regs;
	u32 val;

	/* No need to reinitialize the UART if TX already enabled */
	val = readl(&regs->control);
	if (val & ZYNQ_UART_CR_TX_EN)
		return 0;

	_uart_zynq_serial_init(plat->regs);

	return 0;
}

static int zynq_serial_getc(struct udevice *dev)
{
	struct zynq_uart_plat *plat = dev_get_plat(dev);
	struct uart_zynq *regs = plat->regs;

	if (readl(&regs->channel_sts) & ZYNQ_UART_SR_RXEMPTY)
		return -EAGAIN;

	return readl(&regs->tx_rx_fifo);
}

static int zynq_serial_putc(struct udevice *dev, const char ch)
{
	struct zynq_uart_plat *plat = dev_get_plat(dev);

	return _uart_zynq_serial_putc(plat->regs, ch);
}

static int zynq_serial_pending(struct udevice *dev, bool input)
{
	struct zynq_uart_plat *plat = dev_get_plat(dev);
	struct uart_zynq *regs = plat->regs;

	if (input)
		return !(readl(&regs->channel_sts) & ZYNQ_UART_SR_RXEMPTY);
	else
		return !!(readl(&regs->channel_sts) & ZYNQ_UART_SR_TXACTIVE);
}

static int zynq_serial_of_to_plat(struct udevice *dev)
{
	struct zynq_uart_plat *plat = dev_get_plat(dev);

	plat->regs = (struct uart_zynq *)dev_read_addr(dev);
	if (IS_ERR(plat->regs))
		return PTR_ERR(plat->regs);

	return 0;
}

static const struct dm_serial_ops zynq_serial_ops = {
	.putc = zynq_serial_putc,
	.pending = zynq_serial_pending,
	.getc = zynq_serial_getc,
	.setbrg = zynq_serial_setbrg,
	.setconfig = zynq_serial_setconfig,
};

static const struct udevice_id zynq_serial_ids[] = {
	{ .compatible = "xlnx,xuartps" },
	{ .compatible = "cdns,uart-r1p8" },
	{ .compatible = "cdns,uart-r1p12" },
	{ .compatible = "xlnx,zynqmp-uart" },
	{ }
};

U_BOOT_DRIVER(serial_zynq) = {
	.name	= "serial_zynq",
	.id	= UCLASS_SERIAL,
	.of_match = zynq_serial_ids,
	.of_to_plat = zynq_serial_of_to_plat,
	.plat_auto	= sizeof(struct zynq_uart_plat),
	.probe = zynq_serial_probe,
	.ops	= &zynq_serial_ops,
};

#ifdef CONFIG_DEBUG_UART_ZYNQ
static inline void _debug_uart_init(void)
{
	struct uart_zynq *regs = (struct uart_zynq *)CONFIG_DEBUG_UART_BASE;

	_uart_zynq_serial_init(regs);
	_uart_zynq_serial_setbrg(regs, CONFIG_DEBUG_UART_CLOCK,
				 CONFIG_BAUDRATE);
}

static inline void _debug_uart_putc(int ch)
{
	struct uart_zynq *regs = (struct uart_zynq *)CONFIG_DEBUG_UART_BASE;

	while (_uart_zynq_serial_putc(regs, ch) == -EAGAIN)
		WATCHDOG_RESET();
}

DEBUG_UART_FUNCS

#endif
