// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
 *
 * (C) Copyright 2002
 * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
 *
 * (C) Copyright 2002
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Marius Groeger <mgroeger@sysgo.de>
 *
 * (C) Copyright 2002
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Alex Zuepke <azu@sysgo.de>
 *
 * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
 *
 * Modified to add driver model (DM) support
 * (C) Copyright 2016 Marcel Ziswiler <marcel.ziswiler@toradex.com>
 */

#include <common.h>
#include <hang.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/regs-uart.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <dm.h>
#include <dm/platform_data/serial_pxa.h>
#include <linux/compiler.h>
#include <serial.h>
#include <watchdog.h>

DECLARE_GLOBAL_DATA_PTR;

static uint32_t pxa_uart_get_baud_divider(int baudrate)
{
	return 921600 / baudrate;
}

static void pxa_uart_toggle_clock(uint32_t uart_index, int enable)
{
	uint32_t clk_reg, clk_offset, reg;

	clk_reg = UART_CLK_REG;
	clk_offset = UART_CLK_BASE << uart_index;

	reg = readl(clk_reg);

	if (enable)
		reg |= clk_offset;
	else
		reg &= ~clk_offset;

	writel(reg, clk_reg);
}

/*
 * Enable clock and set baud rate, parity etc.
 */
void pxa_setbrg_common(struct pxa_uart_regs *uart_regs, int port, int baudrate)
{
	uint32_t divider = pxa_uart_get_baud_divider(baudrate);
	if (!divider)
		hang();


	pxa_uart_toggle_clock(port, 1);

	/* Disable interrupts and FIFOs */
	writel(0, &uart_regs->ier);
	writel(0, &uart_regs->fcr);

	/* Set baud rate */
	writel(LCR_WLS0 | LCR_WLS1 | LCR_DLAB, &uart_regs->lcr);
	writel(divider & 0xff, &uart_regs->dll);
	writel(divider >> 8, &uart_regs->dlh);
	writel(LCR_WLS0 | LCR_WLS1, &uart_regs->lcr);

	/* Enable UART */
	writel(IER_UUE, &uart_regs->ier);
}

#ifndef CONFIG_DM_SERIAL
static struct pxa_uart_regs *pxa_uart_index_to_regs(uint32_t uart_index)
{
	switch (uart_index) {
	case FFUART_INDEX: return (struct pxa_uart_regs *)FFUART_BASE;
	case BTUART_INDEX: return (struct pxa_uart_regs *)BTUART_BASE;
	case STUART_INDEX: return (struct pxa_uart_regs *)STUART_BASE;
	default:
		return NULL;
	}
}

/*
 * Enable clock and set baud rate, parity etc.
 */
void pxa_setbrg_dev(uint32_t uart_index)
{
	struct pxa_uart_regs *uart_regs = pxa_uart_index_to_regs(uart_index);
	if (!uart_regs)
		panic("Failed getting UART registers\n");

	pxa_setbrg_common(uart_regs, uart_index, gd->baudrate);
}

/*
 * Initialise the serial port with the given baudrate. The settings
 * are always 8 data bits, no parity, 1 stop bit, no start bits.
 */
int pxa_init_dev(unsigned int uart_index)
{
	pxa_setbrg_dev(uart_index);
	return 0;
}

/*
 * Output a single byte to the serial port.
 */
void pxa_putc_dev(unsigned int uart_index, const char c)
{
	struct pxa_uart_regs *uart_regs;

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

	uart_regs = pxa_uart_index_to_regs(uart_index);
	if (!uart_regs)
		hang();

	while (!(readl(&uart_regs->lsr) & LSR_TEMT))
		WATCHDOG_RESET();
	writel(c, &uart_regs->thr);
}

/*
 * Read a single byte from the serial port. Returns 1 on success, 0
 * otherwise. When the function is succesfull, the character read is
 * written into its argument c.
 */
int pxa_tstc_dev(unsigned int uart_index)
{
	struct pxa_uart_regs *uart_regs;

	uart_regs = pxa_uart_index_to_regs(uart_index);
	if (!uart_regs)
		return -1;

	return readl(&uart_regs->lsr) & LSR_DR;
}

/*
 * Read a single byte from the serial port. Returns 1 on success, 0
 * otherwise. When the function is succesfull, the character read is
 * written into its argument c.
 */
int pxa_getc_dev(unsigned int uart_index)
{
	struct pxa_uart_regs *uart_regs;

	uart_regs = pxa_uart_index_to_regs(uart_index);
	if (!uart_regs)
		return -1;

	while (!(readl(&uart_regs->lsr) & LSR_DR))
		WATCHDOG_RESET();
	return readl(&uart_regs->rbr) & 0xff;
}

void pxa_puts_dev(unsigned int uart_index, const char *s)
{
	while (*s)
		pxa_putc_dev(uart_index, *s++);
}

#define	pxa_uart(uart, UART)						\
	int uart##_init(void)						\
	{								\
		return pxa_init_dev(UART##_INDEX);			\
	}								\
									\
	void uart##_setbrg(void)					\
	{								\
		return pxa_setbrg_dev(UART##_INDEX);			\
	}								\
									\
	void uart##_putc(const char c)					\
	{								\
		return pxa_putc_dev(UART##_INDEX, c);			\
	}								\
									\
	void uart##_puts(const char *s)					\
	{								\
		return pxa_puts_dev(UART##_INDEX, s);			\
	}								\
									\
	int uart##_getc(void)						\
	{								\
		return pxa_getc_dev(UART##_INDEX);			\
	}								\
									\
	int uart##_tstc(void)						\
	{								\
		return pxa_tstc_dev(UART##_INDEX);			\
	}								\

#define	pxa_uart_desc(uart)						\
	struct serial_device serial_##uart##_device =			\
	{								\
		.name	= "serial_"#uart,				\
		.start	= uart##_init,					\
		.stop	= NULL,						\
		.setbrg	= uart##_setbrg,				\
		.getc	= uart##_getc,					\
		.tstc	= uart##_tstc,					\
		.putc	= uart##_putc,					\
		.puts	= uart##_puts,					\
	};

#define	pxa_uart_multi(uart, UART)					\
	pxa_uart(uart, UART)						\
	pxa_uart_desc(uart)

#if defined(CONFIG_HWUART)
	pxa_uart_multi(hwuart, HWUART)
#endif
#if defined(CONFIG_STUART)
	pxa_uart_multi(stuart, STUART)
#endif
#if defined(CONFIG_FFUART)
	pxa_uart_multi(ffuart, FFUART)
#endif
#if defined(CONFIG_BTUART)
	pxa_uart_multi(btuart, BTUART)
#endif

__weak struct serial_device *default_serial_console(void)
{
#if CONFIG_CONS_INDEX == 1
	return &serial_hwuart_device;
#elif CONFIG_CONS_INDEX == 2
	return &serial_stuart_device;
#elif CONFIG_CONS_INDEX == 3
	return &serial_ffuart_device;
#elif CONFIG_CONS_INDEX == 4
	return &serial_btuart_device;
#else
#error "Bad CONFIG_CONS_INDEX."
#endif
}

void pxa_serial_initialize(void)
{
#if defined(CONFIG_FFUART)
	serial_register(&serial_ffuart_device);
#endif
#if defined(CONFIG_BTUART)
	serial_register(&serial_btuart_device);
#endif
#if defined(CONFIG_STUART)
	serial_register(&serial_stuart_device);
#endif
}
#endif /* CONFIG_DM_SERIAL */

#ifdef CONFIG_DM_SERIAL
static int pxa_serial_probe(struct udevice *dev)
{
	struct pxa_serial_plat *plat = dev_get_plat(dev);

	pxa_setbrg_common((struct pxa_uart_regs *)plat->base, plat->port,
			  plat->baudrate);
	return 0;
}

static int pxa_serial_putc(struct udevice *dev, const char ch)
{
	struct pxa_serial_plat *plat = dev_get_plat(dev);
	struct pxa_uart_regs *uart_regs = (struct pxa_uart_regs *)plat->base;

	/* Wait for last character to go. */
	if (!(readl(&uart_regs->lsr) & LSR_TEMT))
		return -EAGAIN;

	writel(ch, &uart_regs->thr);

	return 0;
}

static int pxa_serial_getc(struct udevice *dev)
{
	struct pxa_serial_plat *plat = dev_get_plat(dev);
	struct pxa_uart_regs *uart_regs = (struct pxa_uart_regs *)plat->base;

	/* Wait for a character to arrive. */
	if (!(readl(&uart_regs->lsr) & LSR_DR))
		return -EAGAIN;

	return readl(&uart_regs->rbr) & 0xff;
}

int pxa_serial_setbrg(struct udevice *dev, int baudrate)
{
	struct pxa_serial_plat *plat = dev_get_plat(dev);
	struct pxa_uart_regs *uart_regs = (struct pxa_uart_regs *)plat->base;
	int port = plat->port;

	pxa_setbrg_common(uart_regs, port, baudrate);

	return 0;
}

static int pxa_serial_pending(struct udevice *dev, bool input)
{
	struct pxa_serial_plat *plat = dev_get_plat(dev);
	struct pxa_uart_regs *uart_regs = (struct pxa_uart_regs *)plat->base;

	if (input)
		return readl(&uart_regs->lsr) & LSR_DR ? 1 : 0;
	else
		return readl(&uart_regs->lsr) & LSR_TEMT ? 0 : 1;

	return 0;
}

static const struct dm_serial_ops pxa_serial_ops = {
	.putc		= pxa_serial_putc,
	.pending	= pxa_serial_pending,
	.getc		= pxa_serial_getc,
	.setbrg		= pxa_serial_setbrg,
};

U_BOOT_DRIVER(serial_pxa) = {
	.name	= "serial_pxa",
	.id	= UCLASS_SERIAL,
	.probe	= pxa_serial_probe,
	.ops	= &pxa_serial_ops,
	.flags	= DM_FLAG_PRE_RELOC,
};
#endif /* CONFIG_DM_SERIAL */
