// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2016, STMicroelectronics - All Rights Reserved
 * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
 */

#include <common.h>
#include <clk.h>
#include <dm.h>
#include <serial.h>
#include <watchdog.h>
#include <asm/io.h>
#include <asm/arch/stm32.h>
#include "serial_stm32.h"

static void _stm32_serial_setbrg(fdt_addr_t base,
				 struct stm32_uart_info *uart_info,
				 u32 clock_rate,
				 int baudrate)
{
	bool stm32f4 = uart_info->stm32f4;
	u32 int_div, mantissa, fraction, oversampling;

	int_div = DIV_ROUND_CLOSEST(clock_rate, baudrate);

	if (int_div < 16) {
		oversampling = 8;
		setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_OVER8);
	} else {
		oversampling = 16;
		clrbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_OVER8);
	}

	mantissa = (int_div / oversampling) << USART_BRR_M_SHIFT;
	fraction = int_div % oversampling;

	writel(mantissa | fraction, base + BRR_OFFSET(stm32f4));
}

static int stm32_serial_setbrg(struct udevice *dev, int baudrate)
{
	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);

	_stm32_serial_setbrg(plat->base, plat->uart_info,
			     plat->clock_rate, baudrate);

	return 0;
}

static int stm32_serial_setparity(struct udevice *dev, enum serial_par parity)
{
	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
	bool stm32f4 = plat->uart_info->stm32f4;
	u8 uart_enable_bit = plat->uart_info->uart_enable_bit;
	u32 cr1 = plat->base + CR1_OFFSET(stm32f4);
	u32 config = 0;

	if (stm32f4)
		return -EINVAL; /* not supported in driver*/

	clrbits_le32(cr1, USART_CR1_RE | USART_CR1_TE | BIT(uart_enable_bit));
	/* update usart configuration (uart need to be disable)
	 * PCE: parity check control
	 * PS : '0' : Even / '1' : Odd
	 * M[1:0] = '00' : 8 Data bits
	 * M[1:0] = '01' : 9 Data bits with parity
	 */
	switch (parity) {
	default:
	case SERIAL_PAR_NONE:
		config = 0;
		break;
	case SERIAL_PAR_ODD:
		config = USART_CR1_PCE | USART_CR1_PS | USART_CR1_M0;
		break;
	case SERIAL_PAR_EVEN:
		config = USART_CR1_PCE | USART_CR1_M0;
		break;
	}
	clrsetbits_le32(cr1,
			USART_CR1_PCE | USART_CR1_PS | USART_CR1_M1 |
			USART_CR1_M0,
			config);
	setbits_le32(cr1, USART_CR1_RE | USART_CR1_TE | BIT(uart_enable_bit));

	return 0;
}

static int stm32_serial_getc(struct udevice *dev)
{
	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
	bool stm32f4 = plat->uart_info->stm32f4;
	fdt_addr_t base = plat->base;
	u32 isr = readl(base + ISR_OFFSET(stm32f4));

	if ((isr & USART_ISR_RXNE) == 0)
		return -EAGAIN;

	if (isr & (USART_ISR_PE | USART_ISR_ORE)) {
		if (!stm32f4)
			setbits_le32(base + ICR_OFFSET,
				     USART_ICR_PCECF | USART_ICR_ORECF);
		else
			readl(base + RDR_OFFSET(stm32f4));
		return -EIO;
	}

	return readl(base + RDR_OFFSET(stm32f4));
}

static int _stm32_serial_putc(fdt_addr_t base,
			      struct stm32_uart_info *uart_info,
			      const char c)
{
	bool stm32f4 = uart_info->stm32f4;

	if ((readl(base + ISR_OFFSET(stm32f4)) & USART_ISR_TXE) == 0)
		return -EAGAIN;

	writel(c, base + TDR_OFFSET(stm32f4));

	return 0;
}

static int stm32_serial_putc(struct udevice *dev, const char c)
{
	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);

	return _stm32_serial_putc(plat->base, plat->uart_info, c);
}

static int stm32_serial_pending(struct udevice *dev, bool input)
{
	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
	bool stm32f4 = plat->uart_info->stm32f4;
	fdt_addr_t base = plat->base;

	if (input)
		return readl(base + ISR_OFFSET(stm32f4)) &
			USART_ISR_RXNE ? 1 : 0;
	else
		return readl(base + ISR_OFFSET(stm32f4)) &
			USART_ISR_TXE ? 0 : 1;
}

static void _stm32_serial_init(fdt_addr_t base,
			       struct stm32_uart_info *uart_info)
{
	bool stm32f4 = uart_info->stm32f4;
	u8 uart_enable_bit = uart_info->uart_enable_bit;

	/* Disable uart-> enable fifo -> enable uart */
	clrbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_RE | USART_CR1_TE |
		     BIT(uart_enable_bit));
	if (uart_info->has_fifo)
		setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_FIFOEN);
	setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_RE | USART_CR1_TE |
		     BIT(uart_enable_bit));
}

static int stm32_serial_probe(struct udevice *dev)
{
	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);
	struct clk clk;
	int ret;

	plat->uart_info = (struct stm32_uart_info *)dev_get_driver_data(dev);

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

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

	plat->clock_rate = clk_get_rate(&clk);
	if (plat->clock_rate < 0) {
		clk_disable(&clk);
		return plat->clock_rate;
	};

	_stm32_serial_init(plat->base, plat->uart_info);

	return 0;
}

static const struct udevice_id stm32_serial_id[] = {
	{ .compatible = "st,stm32-uart", .data = (ulong)&stm32f4_info},
	{ .compatible = "st,stm32f7-uart", .data = (ulong)&stm32f7_info},
	{ .compatible = "st,stm32h7-uart", .data = (ulong)&stm32h7_info},
	{}
};

static int stm32_serial_ofdata_to_platdata(struct udevice *dev)
{
	struct stm32x7_serial_platdata *plat = dev_get_platdata(dev);

	plat->base = devfdt_get_addr(dev);
	if (plat->base == FDT_ADDR_T_NONE)
		return -EINVAL;

	return 0;
}

static const struct dm_serial_ops stm32_serial_ops = {
	.putc = stm32_serial_putc,
	.pending = stm32_serial_pending,
	.getc = stm32_serial_getc,
	.setbrg = stm32_serial_setbrg,
	.setparity = stm32_serial_setparity
};

U_BOOT_DRIVER(serial_stm32) = {
	.name = "serial_stm32",
	.id = UCLASS_SERIAL,
	.of_match = of_match_ptr(stm32_serial_id),
	.ofdata_to_platdata = of_match_ptr(stm32_serial_ofdata_to_platdata),
	.platdata_auto_alloc_size = sizeof(struct stm32x7_serial_platdata),
	.ops = &stm32_serial_ops,
	.probe = stm32_serial_probe,
	.flags = DM_FLAG_PRE_RELOC,
};

#ifdef CONFIG_DEBUG_UART_STM32
#include <debug_uart.h>
static inline struct stm32_uart_info *_debug_uart_info(void)
{
	struct stm32_uart_info *uart_info;

#if defined(CONFIG_STM32F4)
	uart_info = &stm32f4_info;
#elif defined(CONFIG_STM32F7)
	uart_info = &stm32f7_info;
#else
	uart_info = &stm32h7_info;
#endif
	return uart_info;
}

static inline void _debug_uart_init(void)
{
	fdt_addr_t base = CONFIG_DEBUG_UART_BASE;
	struct stm32_uart_info *uart_info = _debug_uart_info();

	_stm32_serial_init(base, uart_info);
	_stm32_serial_setbrg(base, uart_info,
			     CONFIG_DEBUG_UART_CLOCK,
			     CONFIG_BAUDRATE);
	printf("DEBUG done\n");
}

static inline void _debug_uart_putc(int c)
{
	fdt_addr_t base = CONFIG_DEBUG_UART_BASE;
	struct stm32_uart_info *uart_info = _debug_uart_info();

	while (_stm32_serial_putc(base, uart_info, c) == -EAGAIN)
		WATCHDOG_RESET();
}

DEBUG_UART_FUNCS
#endif
