/*
 * Copyright (c) 2021-2022, STMicroelectronics - All Rights Reserved
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <errno.h>
#include <string.h>

#include <common/bl_common.h>
#include <drivers/clk.h>
#include <drivers/delay_timer.h>
#include <drivers/st/stm32_gpio.h>
#include <drivers/st/stm32_uart.h>
#include <drivers/st/stm32_uart_regs.h>
#include <drivers/st/stm32mp_clkfunc.h>
#include <lib/mmio.h>

#include <platform_def.h>

/* UART time-out value */
#define STM32_UART_TIMEOUT_US	20000U

/* Mask to clear ALL the configuration registers */

#define STM32_UART_CR1_FIELDS \
		(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | \
		 USART_CR1_RE | USART_CR1_OVER8 | USART_CR1_FIFOEN)

#define STM32_UART_CR2_FIELDS \
		(USART_CR2_SLVEN | USART_CR2_DIS_NSS | USART_CR2_ADDM7 | \
		 USART_CR2_LBDL | USART_CR2_LBDIE | USART_CR2_LBCL | \
		 USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | \
		 USART_CR2_STOP | USART_CR2_LINEN | USART_CR2_SWAP | \
		 USART_CR2_RXINV | USART_CR2_TXINV | USART_CR2_DATAINV | \
		 USART_CR2_MSBFIRST | USART_CR2_ABREN | USART_CR2_ABRMODE | \
		 USART_CR2_RTOEN | USART_CR2_ADD)

#define STM32_UART_CR3_FIELDS \
		(USART_CR3_EIE | USART_CR3_IREN | USART_CR3_IRLP | \
		 USART_CR3_HDSEL | USART_CR3_NACK | USART_CR3_SCEN | \
		 USART_CR3_DMAR | USART_CR3_DMAT | USART_CR3_RTSE | \
		 USART_CR3_CTSE | USART_CR3_CTSIE | USART_CR3_ONEBIT | \
		 USART_CR3_OVRDIS | USART_CR3_DDRE | USART_CR3_DEM | \
		 USART_CR3_DEP | USART_CR3_SCARCNT | USART_CR3_WUS | \
		 USART_CR3_WUFIE | USART_CR3_TXFTIE | USART_CR3_TCBGTIE | \
		 USART_CR3_RXFTCFG | USART_CR3_RXFTIE | USART_CR3_TXFTCFG)

#define STM32_UART_ISR_ERRORS	 \
		(USART_ISR_ORE | USART_ISR_NE |  USART_ISR_FE | USART_ISR_PE)

static const uint16_t presc_table[STM32_UART_PRESCALER_NB] = {
	1U, 2U, 4U, 6U, 8U, 10U, 12U, 16U, 32U, 64U, 128U, 256U
};

/* @brief  BRR division operation to set BRR register in 8-bit oversampling
 * mode.
 * @param  clockfreq: UART clock.
 * @param  baud_rate: Baud rate set by the user.
 * @param  prescaler: UART prescaler value.
 * @retval Division result.
 */
static uint32_t uart_div_sampling8(unsigned long clockfreq,
				   uint32_t baud_rate,
				   uint32_t prescaler)
{
	uint32_t scaled_freq = clockfreq / presc_table[prescaler];

	return ((scaled_freq * 2) + (baud_rate / 2)) / baud_rate;

}

/* @brief  BRR division operation to set BRR register in 16-bit oversampling
 * mode.
 * @param  clockfreq: UART clock.
 * @param  baud_rate: Baud rate set by the user.
 * @param  prescaler: UART prescaler value.
 * @retval Division result.
 */
static uint32_t uart_div_sampling16(unsigned long clockfreq,
				    uint32_t baud_rate,
				    uint32_t prescaler)
{
	uint32_t scaled_freq = clockfreq / presc_table[prescaler];

	return (scaled_freq + (baud_rate / 2)) / baud_rate;

}

/*
 * @brief  Return the UART clock frequency.
 * @param  huart: UART handle.
 * @retval Frequency value in Hz.
 */
static unsigned long uart_get_clock_freq(struct stm32_uart_handle_s *huart)
{
	return fdt_get_uart_clock_freq((uintptr_t)huart->base);
}

/*
 * @brief  Configure the UART peripheral.
 * @param  huart: UART handle.
 * @retval UART status.
 */
static int uart_set_config(struct stm32_uart_handle_s *huart,
			   const struct stm32_uart_init_s *init)
{
	uint32_t tmpreg;
	unsigned long clockfreq;
	unsigned long int_div;
	uint32_t brrtemp;
	uint32_t over_sampling;

	/*---------------------- USART BRR configuration --------------------*/
	clockfreq = uart_get_clock_freq(huart);
	if (clockfreq == 0UL) {
		return -ENODEV;
	}

	int_div = clockfreq / init->baud_rate;
	if (int_div < 16U) {
		uint32_t usartdiv = uart_div_sampling8(clockfreq,
						       init->baud_rate,
						       init->prescaler);

		brrtemp = (usartdiv & USART_BRR_DIV_MANTISSA) |
			  ((usartdiv & USART_BRR_DIV_FRACTION) >> 1);
		over_sampling = USART_CR1_OVER8;
	} else {
		brrtemp = uart_div_sampling16(clockfreq,
					      init->baud_rate,
					      init->prescaler) &
			  (USART_BRR_DIV_FRACTION | USART_BRR_DIV_MANTISSA);
		over_sampling = 0x0U;
	}
	mmio_write_32(huart->base + USART_BRR, brrtemp);

	/*
	 * ---------------------- USART CR1 Configuration --------------------
	 * Clear M, PCE, PS, TE, RE and OVER8 bits and configure
	 * the UART word length, parity, mode and oversampling:
	 * - set the M bits according to init->word_length value,
	 * - set PCE and PS bits according to init->parity value,
	 * - set TE and RE bits according to init->mode value,
	 * - set OVER8 bit according baudrate and clock.
	 */
	tmpreg = init->word_length |
		 init->parity |
		 init->mode |
		 over_sampling |
		 init->fifo_mode;
	mmio_clrsetbits_32(huart->base + USART_CR1, STM32_UART_CR1_FIELDS, tmpreg);

	/*
	 * --------------------- USART CR2 Configuration ---------------------
	 * Configure the UART Stop Bits: Set STOP[13:12] bits according
	 * to init->stop_bits value.
	 */
	mmio_clrsetbits_32(huart->base + USART_CR2, STM32_UART_CR2_FIELDS,
			   init->stop_bits);

	/*
	 * --------------------- USART CR3 Configuration ---------------------
	 * Configure:
	 * - UART HardWare Flow Control: set CTSE and RTSE bits according
	 *   to init->hw_flow_control value,
	 * - one-bit sampling method versus three samples' majority rule
	 *   according to init->one_bit_sampling (not applicable to
	 *   LPUART),
	 * - set TXFTCFG bit according to init->tx_fifo_threshold value,
	 * - set RXFTCFG bit according to init->rx_fifo_threshold value.
	 */
	tmpreg = init->hw_flow_control | init->one_bit_sampling;

	if (init->fifo_mode == USART_CR1_FIFOEN) {
		tmpreg |= init->tx_fifo_threshold |
			  init->rx_fifo_threshold;
	}

	mmio_clrsetbits_32(huart->base + USART_CR3, STM32_UART_CR3_FIELDS, tmpreg);

	/*
	 * --------------------- USART PRESC Configuration -------------------
	 * Configure UART Clock Prescaler : set PRESCALER according to
	 * init->prescaler value.
	 */
	assert(init->prescaler < STM32_UART_PRESCALER_NB);
	mmio_clrsetbits_32(huart->base + USART_PRESC, USART_PRESC_PRESCALER,
			   init->prescaler);

	return 0;
}

/*
 * @brief  Handle UART communication timeout.
 * @param  huart: UART handle.
 * @param  flag: Specifies the UART flag to check.
 * @retval UART status.
 */
static int stm32_uart_wait_flag(struct stm32_uart_handle_s *huart, uint32_t flag)
{
	uint64_t timeout_ref = timeout_init_us(STM32_UART_TIMEOUT_US);

	while ((mmio_read_32(huart->base + USART_ISR) & flag) == 0U) {
		if (timeout_elapsed(timeout_ref)) {
			return -ETIMEDOUT;
		}
	}

	return 0;
}

/*
 * @brief  Check the UART idle State.
 * @param  huart: UART handle.
 * @retval UART status.
 */
static int stm32_uart_check_idle(struct stm32_uart_handle_s *huart)
{
	int ret;

	/* Check if the transmitter is enabled */
	if ((mmio_read_32(huart->base + USART_CR1) & USART_CR1_TE) == USART_CR1_TE) {
		ret = stm32_uart_wait_flag(huart, USART_ISR_TEACK);
		if (ret != 0) {
			return ret;
		}
	}

	/* Check if the receiver is enabled */
	if ((mmio_read_32(huart->base + USART_CR1) & USART_CR1_RE) == USART_CR1_RE) {
		ret = stm32_uart_wait_flag(huart, USART_ISR_REACK);
		if (ret != 0) {
			return ret;
		}
	}

	return 0;
}

/*
 * @brief  Compute RDR register mask depending on word length.
 * @param  huart: UART handle.
 * @retval Mask value.
 */
static unsigned int stm32_uart_rdr_mask(const struct stm32_uart_init_s *init)
{
	unsigned int mask = 0U;

	switch (init->word_length) {
	case STM32_UART_WORDLENGTH_9B:
		mask = GENMASK(8, 0);
		break;
	case STM32_UART_WORDLENGTH_8B:
		mask = GENMASK(7, 0);
		break;
	case STM32_UART_WORDLENGTH_7B:
		mask = GENMASK(6, 0);
		break;
	default:
		break; /* not reached */
	}

	if (init->parity != STM32_UART_PARITY_NONE) {
		mask >>= 1;
	}

	return mask;
}

/*
 * @brief  Check interrupt and status errors.
 * @retval True if error detected, false otherwise.
 */
static bool stm32_uart_error_detected(struct stm32_uart_handle_s *huart)
{
	return (mmio_read_32(huart->base + USART_ISR) & STM32_UART_ISR_ERRORS) != 0U;
}

/*
 * @brief  Clear status errors.
 */
static void stm32_uart_error_clear(struct stm32_uart_handle_s *huart)
{
	mmio_write_32(huart->base + USART_ICR, STM32_UART_ISR_ERRORS);
}

/*
 * @brief  Stop the UART.
 * @param  base: UART base address.
 */
void stm32_uart_stop(uintptr_t base)
{
	mmio_clrbits_32(base + USART_CR1, USART_CR1_UE);
}

/*
 * @brief  Initialize UART.
 * @param  huart: UART handle.
 * @param  base_addr: base address of UART.
 * @param  init: UART initialization parameter.
 * @retval UART status.
 */
int stm32_uart_init(struct stm32_uart_handle_s *huart,
		    uintptr_t base_addr,
		    const struct stm32_uart_init_s *init)
{
	int ret;
	int uart_node;
	int clk;
	void *fdt = NULL;

	if (huart == NULL || init == NULL || base_addr == 0U) {
		return -EINVAL;
	}

	huart->base = base_addr;

	/* Search UART instance in DT */
	if (fdt_get_address(&fdt) == 0) {
		return -FDT_ERR_NOTFOUND;
	}

	if (fdt == NULL) {
		return -FDT_ERR_NOTFOUND;
	}

	uart_node = dt_match_instance_by_compatible(DT_UART_COMPAT, base_addr);
	if (uart_node == -FDT_ERR_NOTFOUND) {
		return -FDT_ERR_NOTFOUND;
	}

	/* Pinctrl initialization */
	if (dt_set_pinctrl_config(uart_node) != 0) {
		return -FDT_ERR_BADVALUE;
	}

	/* Clock initialization */
	clk = fdt_get_clock_id(uart_node);
	if (clk < 0) {
		return -FDT_ERR_NOTFOUND;
	}
	clk_enable(clk);

	/* Disable the peripheral */
	stm32_uart_stop(huart->base);

	/* Computation of UART mask to apply to RDR register */
	huart->rdr_mask = stm32_uart_rdr_mask(init);

	/* Init the peripheral */
	ret = uart_set_config(huart, init);
	if (ret != 0) {
		return ret;
	}

	/* Enable the peripheral */
	mmio_setbits_32(huart->base + USART_CR1, USART_CR1_UE);

	/* TEACK and/or REACK to check */
	return stm32_uart_check_idle(huart);
}

/*
 * @brief  Transmit one data in no blocking mode.
 * @param  huart: UART handle.
 * @param  c: data to sent.
 * @retval UART status.
 */
int stm32_uart_putc(struct stm32_uart_handle_s *huart, int c)
{
	int ret;

	if (huart == NULL) {
		return -EINVAL;
	}

	ret = stm32_uart_wait_flag(huart, USART_ISR_TXE);
	if (ret != 0) {
		return ret;
	}

	mmio_write_32(huart->base + USART_TDR, c);
	if (stm32_uart_error_detected(huart)) {
		stm32_uart_error_clear(huart);
		return -EFAULT;
	}

	return 0;
}

/*
 * @brief  Flush TX Transmit fifo
 * @param  huart: UART handle.
 * @retval UART status.
 */
int stm32_uart_flush(struct stm32_uart_handle_s *huart)
{
	int ret;

	if (huart == NULL) {
		return -EINVAL;
	}

	ret = stm32_uart_wait_flag(huart, USART_ISR_TXE);
	if (ret != 0) {
		return ret;
	}

	return stm32_uart_wait_flag(huart, USART_ISR_TC);
}

/*
 * @brief  Receive a data in no blocking mode.
 * @retval value if >0 or UART status.
 */
int stm32_uart_getc(struct stm32_uart_handle_s *huart)
{
	uint32_t data;

	if (huart == NULL) {
		return -EINVAL;
	}

	/* Check if data is available */
	if ((mmio_read_32(huart->base + USART_ISR) & USART_ISR_RXNE) == 0U) {
		return -EAGAIN;
	}

	data = mmio_read_32(huart->base + USART_RDR) & huart->rdr_mask;

	if (stm32_uart_error_detected(huart)) {
		stm32_uart_error_clear(huart);
		return -EFAULT;
	}

	return (int)data;
}
