// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2004-2006 Atmel Corporation
 *
 * Modified to support C structur SoC access by
 * Andreas Bießmann <biessmann@corscience.de>
 */
#include <common.h>
#include <clk.h>
#include <dm.h>
#include <errno.h>
#include <malloc.h>
#include <watchdog.h>
#include <serial.h>
#include <debug_uart.h>
#include <asm/global_data.h>
#include <linux/compiler.h>
#include <linux/delay.h>

#include <asm/io.h>
#ifdef CONFIG_DM_SERIAL
#include <asm/arch/atmel_serial.h>
#endif
#include <asm/arch/clk.h>
#include <asm/arch/hardware.h>

#include "atmel_usart.h"

DECLARE_GLOBAL_DATA_PTR;

#ifndef CONFIG_DM_SERIAL
static void atmel_serial_setbrg_internal(atmel_usart3_t *usart, int id,
					 int baudrate)
{
	unsigned long divisor;
	unsigned long usart_hz;

	/*
	 *              Master Clock
	 * Baud Rate = --------------
	 *                16 * CD
	 */
	usart_hz = get_usart_clk_rate(id);
	divisor = (usart_hz / 16 + baudrate / 2) / baudrate;
	writel(USART3_BF(CD, divisor), &usart->brgr);
}

static void atmel_serial_init_internal(atmel_usart3_t *usart)
{
	/*
	 * Just in case: drain transmitter register
	 * 1000us is enough for baudrate >= 9600
	 */
	if (!(readl(&usart->csr) & USART3_BIT(TXEMPTY)))
		__udelay(1000);

	writel(USART3_BIT(RSTRX) | USART3_BIT(RSTTX), &usart->cr);
}

static void atmel_serial_activate(atmel_usart3_t *usart)
{
	writel((USART3_BF(USART_MODE, USART3_USART_MODE_NORMAL)
			   | USART3_BF(USCLKS, USART3_USCLKS_MCK)
			   | USART3_BF(CHRL, USART3_CHRL_8)
			   | USART3_BF(PAR, USART3_PAR_NONE)
			   | USART3_BF(NBSTOP, USART3_NBSTOP_1)),
			   &usart->mr);
	writel(USART3_BIT(RXEN) | USART3_BIT(TXEN), &usart->cr);
	/* 100us is enough for the new settings to be settled */
	__udelay(100);
}

static void atmel_serial_setbrg(void)
{
	atmel_serial_setbrg_internal((atmel_usart3_t *)CONFIG_USART_BASE,
				     CONFIG_USART_ID, gd->baudrate);
}

static int atmel_serial_init(void)
{
	atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE;

	atmel_serial_init_internal(usart);
	serial_setbrg();
	atmel_serial_activate(usart);

	return 0;
}

static void atmel_serial_putc(char c)
{
	atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE;

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

	while (!(readl(&usart->csr) & USART3_BIT(TXRDY)));
	writel(c, &usart->thr);
}

static int atmel_serial_getc(void)
{
	atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE;

	while (!(readl(&usart->csr) & USART3_BIT(RXRDY)))
		 WATCHDOG_RESET();
	return readl(&usart->rhr);
}

static int atmel_serial_tstc(void)
{
	atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE;
	return (readl(&usart->csr) & USART3_BIT(RXRDY)) != 0;
}

static struct serial_device atmel_serial_drv = {
	.name	= "atmel_serial",
	.start	= atmel_serial_init,
	.stop	= NULL,
	.setbrg	= atmel_serial_setbrg,
	.putc	= atmel_serial_putc,
	.puts	= default_serial_puts,
	.getc	= atmel_serial_getc,
	.tstc	= atmel_serial_tstc,
};

void atmel_serial_initialize(void)
{
	serial_register(&atmel_serial_drv);
}

__weak struct serial_device *default_serial_console(void)
{
	return &atmel_serial_drv;
}
#endif

#ifdef CONFIG_DM_SERIAL
enum serial_clk_type {
	CLK_TYPE_NORMAL = 0,
	CLK_TYPE_DBGU,
};

struct atmel_serial_priv {
	atmel_usart3_t *usart;
	ulong usart_clk_rate;
};

static void _atmel_serial_set_brg(atmel_usart3_t *usart,
				  ulong usart_clk_rate, int baudrate)
{
	unsigned long divisor;

	divisor = (usart_clk_rate / 16 + baudrate / 2) / baudrate;
	writel(USART3_BF(CD, divisor), &usart->brgr);
}

void _atmel_serial_init(atmel_usart3_t *usart,
			ulong usart_clk_rate, int baudrate)
{
	writel(USART3_BIT(RXDIS) | USART3_BIT(TXDIS), &usart->cr);

	writel((USART3_BF(USART_MODE, USART3_USART_MODE_NORMAL) |
		USART3_BF(USCLKS, USART3_USCLKS_MCK) |
		USART3_BF(CHRL, USART3_CHRL_8) |
		USART3_BF(PAR, USART3_PAR_NONE) |
		USART3_BF(NBSTOP, USART3_NBSTOP_1)), &usart->mr);

	_atmel_serial_set_brg(usart, usart_clk_rate, baudrate);

	writel(USART3_BIT(RSTRX) | USART3_BIT(RSTTX), &usart->cr);
	writel(USART3_BIT(RXEN) | USART3_BIT(TXEN), &usart->cr);
}

int atmel_serial_setbrg(struct udevice *dev, int baudrate)
{
	struct atmel_serial_priv *priv = dev_get_priv(dev);

	_atmel_serial_set_brg(priv->usart, priv->usart_clk_rate, baudrate);

	return 0;
}

static int atmel_serial_getc(struct udevice *dev)
{
	struct atmel_serial_priv *priv = dev_get_priv(dev);

	if (!(readl(&priv->usart->csr) & USART3_BIT(RXRDY)))
		return -EAGAIN;

	return readl(&priv->usart->rhr);
}

static int atmel_serial_putc(struct udevice *dev, const char ch)
{
	struct atmel_serial_priv *priv = dev_get_priv(dev);

	if (!(readl(&priv->usart->csr) & USART3_BIT(TXRDY)))
		return -EAGAIN;

	writel(ch, &priv->usart->thr);

	return 0;
}

static int atmel_serial_pending(struct udevice *dev, bool input)
{
	struct atmel_serial_priv *priv = dev_get_priv(dev);
	uint32_t csr = readl(&priv->usart->csr);

	if (input)
		return csr & USART3_BIT(RXRDY) ? 1 : 0;
	else
		return csr & USART3_BIT(TXEMPTY) ? 0 : 1;
}

static const struct dm_serial_ops atmel_serial_ops = {
	.putc = atmel_serial_putc,
	.pending = atmel_serial_pending,
	.getc = atmel_serial_getc,
	.setbrg = atmel_serial_setbrg,
};

#if defined(CONFIG_SPL_BUILD) && !defined(CONFIG_SPL_CLK)
static int atmel_serial_enable_clk(struct udevice *dev)
{
	struct atmel_serial_priv *priv = dev_get_priv(dev);

	/* Use fixed clock value in SPL */
	priv->usart_clk_rate = CONFIG_SPL_UART_CLOCK;

	return 0;
}
#else
static int atmel_serial_enable_clk(struct udevice *dev)
{
	struct atmel_serial_priv *priv = dev_get_priv(dev);
	struct clk clk;
	ulong clk_rate;
	int ret;

	ret = clk_get_by_index(dev, 0, &clk);
	if (ret)
		return -EINVAL;

	if (dev_get_driver_data(dev) == CLK_TYPE_NORMAL) {
		ret = clk_enable(&clk);
		if (ret)
			return ret;
	}

	clk_rate = clk_get_rate(&clk);
	if (!clk_rate)
		return -EINVAL;

	priv->usart_clk_rate = clk_rate;

	clk_free(&clk);

	return 0;
}
#endif

static int atmel_serial_probe(struct udevice *dev)
{
	struct atmel_serial_plat *plat = dev_get_plat(dev);
	struct atmel_serial_priv *priv = dev_get_priv(dev);
	int ret;
#if CONFIG_IS_ENABLED(OF_CONTROL)
	fdt_addr_t addr_base;

	addr_base = dev_read_addr(dev);
	if (addr_base == FDT_ADDR_T_NONE)
		return -ENODEV;

	plat->base_addr = (uint32_t)addr_base;
#endif
	priv->usart = (atmel_usart3_t *)plat->base_addr;

	ret = atmel_serial_enable_clk(dev);
	if (ret)
		return ret;

	_atmel_serial_init(priv->usart, priv->usart_clk_rate, gd->baudrate);

	return 0;
}

#if CONFIG_IS_ENABLED(OF_CONTROL)
static const struct udevice_id atmel_serial_ids[] = {
	{
		.compatible = "atmel,at91sam9260-dbgu",
		.data = CLK_TYPE_DBGU,
	},
	{
		.compatible = "atmel,at91sam9260-usart",
		.data = CLK_TYPE_NORMAL,
	},
	{ }
};
#endif

U_BOOT_DRIVER(serial_atmel) = {
	.name	= "serial_atmel",
	.id	= UCLASS_SERIAL,
#if CONFIG_IS_ENABLED(OF_CONTROL)
	.of_match = atmel_serial_ids,
	.plat_auto	= sizeof(struct atmel_serial_plat),
#endif
	.probe = atmel_serial_probe,
	.ops	= &atmel_serial_ops,
#if !CONFIG_IS_ENABLED(OF_CONTROL)
	.flags = DM_FLAG_PRE_RELOC,
#endif
	.priv_auto	= sizeof(struct atmel_serial_priv),
};
#endif

#ifdef CONFIG_DEBUG_UART_ATMEL
static inline void _debug_uart_init(void)
{
	atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_DEBUG_UART_BASE;

	_atmel_serial_init(usart, CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE);
}

static inline void _debug_uart_putc(int ch)
{
	atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_DEBUG_UART_BASE;

	while (!(readl(&usart->csr) & USART3_BIT(TXRDY)))
		;

	writel(ch, &usart->thr);
}

DEBUG_UART_FUNCS
#endif
