// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
 * Scott McNutt <smcnutt@psyent.com>
 */

#include <dm.h>
#include <errno.h>
#include <serial.h>
#include <asm/io.h>
#include <linux/bitops.h>

/* status register */
#define ALTERA_UART_TMT		BIT(5)	/* tx empty */
#define ALTERA_UART_TRDY	BIT(6)	/* tx ready */
#define ALTERA_UART_RRDY	BIT(7)	/* rx ready */

struct altera_uart_regs {
	u32	rxdata;		/* Rx data reg */
	u32	txdata;		/* Tx data reg */
	u32	status;		/* Status reg */
	u32	control;	/* Control reg */
	u32	divisor;	/* Baud rate divisor reg */
	u32	endofpacket;	/* End-of-packet reg */
};

struct altera_uart_plat {
	struct altera_uart_regs *regs;
	unsigned int uartclk;
};

static int altera_uart_setbrg(struct udevice *dev, int baudrate)
{
	struct altera_uart_plat *plat = dev_get_plat(dev);
	struct altera_uart_regs *const regs = plat->regs;
	u32 div;

	div = (plat->uartclk / baudrate) - 1;
	writel(div, &regs->divisor);

	return 0;
}

static int altera_uart_putc(struct udevice *dev, const char ch)
{
	struct altera_uart_plat *plat = dev_get_plat(dev);
	struct altera_uart_regs *const regs = plat->regs;

	if (!(readl(&regs->status) & ALTERA_UART_TRDY))
		return -EAGAIN;

	writel(ch, &regs->txdata);

	return 0;
}

static int altera_uart_pending(struct udevice *dev, bool input)
{
	struct altera_uart_plat *plat = dev_get_plat(dev);
	struct altera_uart_regs *const regs = plat->regs;
	u32 st = readl(&regs->status);

	if (input)
		return st & ALTERA_UART_RRDY ? 1 : 0;
	else
		return !(st & ALTERA_UART_TMT);
}

static int altera_uart_getc(struct udevice *dev)
{
	struct altera_uart_plat *plat = dev_get_plat(dev);
	struct altera_uart_regs *const regs = plat->regs;

	if (!(readl(&regs->status) & ALTERA_UART_RRDY))
		return -EAGAIN;

	return readl(&regs->rxdata) & 0xff;
}

static int altera_uart_probe(struct udevice *dev)
{
	return 0;
}

static int altera_uart_of_to_plat(struct udevice *dev)
{
	struct altera_uart_plat *plat = dev_get_plat(dev);

	plat->regs = map_physmem(dev_read_addr(dev),
				 sizeof(struct altera_uart_regs),
				 MAP_NOCACHE);
	plat->uartclk = dev_read_u32_default(dev, "clock-frequency", 0);

	return 0;
}

static const struct dm_serial_ops altera_uart_ops = {
	.putc = altera_uart_putc,
	.pending = altera_uart_pending,
	.getc = altera_uart_getc,
	.setbrg = altera_uart_setbrg,
};

static const struct udevice_id altera_uart_ids[] = {
	{ .compatible = "altr,uart-1.0" },
	{}
};

U_BOOT_DRIVER(altera_uart) = {
	.name	= "altera_uart",
	.id	= UCLASS_SERIAL,
	.of_match = altera_uart_ids,
	.of_to_plat = altera_uart_of_to_plat,
	.plat_auto	= sizeof(struct altera_uart_plat),
	.probe = altera_uart_probe,
	.ops	= &altera_uart_ops,
};

#ifdef CONFIG_DEBUG_UART_ALTERA_UART

#include <debug_uart.h>

static inline void _debug_uart_init(void)
{
	struct altera_uart_regs *regs = (void *)CONFIG_VAL(DEBUG_UART_BASE);
	u32 div;

	div = (CONFIG_DEBUG_UART_CLOCK / CONFIG_BAUDRATE) - 1;
	writel(div, &regs->divisor);
}

static inline void _debug_uart_putc(int ch)
{
	struct altera_uart_regs *regs = (void *)CONFIG_VAL(DEBUG_UART_BASE);

	while (1) {
		u32 st = readl(&regs->status);

		if (st & ALTERA_UART_TRDY)
			break;
	}

	writel(ch, &regs->txdata);
}

DEBUG_UART_FUNCS

#endif
