/*
 * Copyright (c) 2019 Song Qiang <songqiang1304521@gmail.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @brief DMA low level driver implementation for F2/F4/F7 series SoCs.
 */

#include "dma_stm32.h"

#define LOG_LEVEL CONFIG_DMA_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(dma_stm32_v1);

/* DMA burst length */
#define BURST_TRANS_LENGTH_1			0

uint32_t dma_stm32_id_to_stream(uint32_t id)
{
	static const uint32_t stream_nr[] = {
		LL_DMA_STREAM_0,
		LL_DMA_STREAM_1,
		LL_DMA_STREAM_2,
		LL_DMA_STREAM_3,
		LL_DMA_STREAM_4,
		LL_DMA_STREAM_5,
		LL_DMA_STREAM_6,
		LL_DMA_STREAM_7,
	};

	__ASSERT_NO_MSG(id < ARRAY_SIZE(stream_nr));

	return stream_nr[id];
}

#if !defined(CONFIG_DMAMUX_STM32)
uint32_t dma_stm32_slot_to_channel(uint32_t slot)
{
	static const uint32_t channel_nr[] = {
		LL_DMA_CHANNEL_0,
		LL_DMA_CHANNEL_1,
		LL_DMA_CHANNEL_2,
		LL_DMA_CHANNEL_3,
		LL_DMA_CHANNEL_4,
		LL_DMA_CHANNEL_5,
		LL_DMA_CHANNEL_6,
		LL_DMA_CHANNEL_7,
	};

	__ASSERT_NO_MSG(slot < ARRAY_SIZE(channel_nr));

	return channel_nr[slot];
}
#endif

void dma_stm32_clear_ht(DMA_TypeDef *DMAx, uint32_t id)
{
	static const dma_stm32_clear_flag_func func[] = {
		LL_DMA_ClearFlag_HT0,
		LL_DMA_ClearFlag_HT1,
		LL_DMA_ClearFlag_HT2,
		LL_DMA_ClearFlag_HT3,
		LL_DMA_ClearFlag_HT4,
		LL_DMA_ClearFlag_HT5,
		LL_DMA_ClearFlag_HT6,
		LL_DMA_ClearFlag_HT7,
	};

	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));

	func[id](DMAx);
}

void dma_stm32_clear_tc(DMA_TypeDef *DMAx, uint32_t id)
{
	static const dma_stm32_clear_flag_func func[] = {
		LL_DMA_ClearFlag_TC0,
		LL_DMA_ClearFlag_TC1,
		LL_DMA_ClearFlag_TC2,
		LL_DMA_ClearFlag_TC3,
		LL_DMA_ClearFlag_TC4,
		LL_DMA_ClearFlag_TC5,
		LL_DMA_ClearFlag_TC6,
		LL_DMA_ClearFlag_TC7,
	};

	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));

	func[id](DMAx);
}

bool dma_stm32_is_ht_active(DMA_TypeDef *DMAx, uint32_t id)
{
	static const dma_stm32_check_flag_func func[] = {
		LL_DMA_IsActiveFlag_HT0,
		LL_DMA_IsActiveFlag_HT1,
		LL_DMA_IsActiveFlag_HT2,
		LL_DMA_IsActiveFlag_HT3,
		LL_DMA_IsActiveFlag_HT4,
		LL_DMA_IsActiveFlag_HT5,
		LL_DMA_IsActiveFlag_HT6,
		LL_DMA_IsActiveFlag_HT7,
	};

	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));

	return func[id](DMAx);
}

bool dma_stm32_is_tc_active(DMA_TypeDef *DMAx, uint32_t id)
{
	static const dma_stm32_check_flag_func func[] = {
		LL_DMA_IsActiveFlag_TC0,
		LL_DMA_IsActiveFlag_TC1,
		LL_DMA_IsActiveFlag_TC2,
		LL_DMA_IsActiveFlag_TC3,
		LL_DMA_IsActiveFlag_TC4,
		LL_DMA_IsActiveFlag_TC5,
		LL_DMA_IsActiveFlag_TC6,
		LL_DMA_IsActiveFlag_TC7,
	};

	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));

	return func[id](DMAx);
}

void dma_stm32_clear_te(DMA_TypeDef *DMAx, uint32_t id)
{
	static const dma_stm32_clear_flag_func func[] = {
		LL_DMA_ClearFlag_TE0,
		LL_DMA_ClearFlag_TE1,
		LL_DMA_ClearFlag_TE2,
		LL_DMA_ClearFlag_TE3,
		LL_DMA_ClearFlag_TE4,
		LL_DMA_ClearFlag_TE5,
		LL_DMA_ClearFlag_TE6,
		LL_DMA_ClearFlag_TE7,
	};

	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));

	func[id](DMAx);
}

void dma_stm32_clear_dme(DMA_TypeDef *DMAx, uint32_t id)
{
	static const dma_stm32_clear_flag_func func[] = {
		LL_DMA_ClearFlag_DME0,
		LL_DMA_ClearFlag_DME1,
		LL_DMA_ClearFlag_DME2,
		LL_DMA_ClearFlag_DME3,
		LL_DMA_ClearFlag_DME4,
		LL_DMA_ClearFlag_DME5,
		LL_DMA_ClearFlag_DME6,
		LL_DMA_ClearFlag_DME7,
	};

	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));

	func[id](DMAx);
}

void dma_stm32_clear_fe(DMA_TypeDef *DMAx, uint32_t id)
{
	static const dma_stm32_clear_flag_func func[] = {
		LL_DMA_ClearFlag_FE0,
		LL_DMA_ClearFlag_FE1,
		LL_DMA_ClearFlag_FE2,
		LL_DMA_ClearFlag_FE3,
		LL_DMA_ClearFlag_FE4,
		LL_DMA_ClearFlag_FE5,
		LL_DMA_ClearFlag_FE6,
		LL_DMA_ClearFlag_FE7,
	};

	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));

	func[id](DMAx);
}

bool dma_stm32_is_te_active(DMA_TypeDef *DMAx, uint32_t id)
{
	static const dma_stm32_check_flag_func func[] = {
		LL_DMA_IsActiveFlag_TE0,
		LL_DMA_IsActiveFlag_TE1,
		LL_DMA_IsActiveFlag_TE2,
		LL_DMA_IsActiveFlag_TE3,
		LL_DMA_IsActiveFlag_TE4,
		LL_DMA_IsActiveFlag_TE5,
		LL_DMA_IsActiveFlag_TE6,
		LL_DMA_IsActiveFlag_TE7,
	};

	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));

	return func[id](DMAx);
}

bool dma_stm32_is_dme_active(DMA_TypeDef *DMAx, uint32_t id)
{
	static const dma_stm32_check_flag_func func[] = {
		LL_DMA_IsActiveFlag_DME0,
		LL_DMA_IsActiveFlag_DME1,
		LL_DMA_IsActiveFlag_DME2,
		LL_DMA_IsActiveFlag_DME3,
		LL_DMA_IsActiveFlag_DME4,
		LL_DMA_IsActiveFlag_DME5,
		LL_DMA_IsActiveFlag_DME6,
		LL_DMA_IsActiveFlag_DME7,
	};

	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));

	return func[id](DMAx);
}

bool dma_stm32_is_fe_active(DMA_TypeDef *DMAx, uint32_t id)
{
	static const dma_stm32_check_flag_func func[] = {
		LL_DMA_IsActiveFlag_FE0,
		LL_DMA_IsActiveFlag_FE1,
		LL_DMA_IsActiveFlag_FE2,
		LL_DMA_IsActiveFlag_FE3,
		LL_DMA_IsActiveFlag_FE4,
		LL_DMA_IsActiveFlag_FE5,
		LL_DMA_IsActiveFlag_FE6,
		LL_DMA_IsActiveFlag_FE7,
	};

	__ASSERT_NO_MSG(id < ARRAY_SIZE(func));

	return func[id](DMAx);
}

void stm32_dma_dump_stream_irq(DMA_TypeDef *dma, uint32_t id)
{
	LOG_INF("tc: %d, ht: %d, te: %d, dme: %d, fe: %d",
		dma_stm32_is_tc_active(dma, id),
		dma_stm32_is_ht_active(dma, id),
		dma_stm32_is_te_active(dma, id),
		dma_stm32_is_dme_active(dma, id),
		dma_stm32_is_fe_active(dma, id));
}

inline bool stm32_dma_is_tc_irq_active(DMA_TypeDef *dma, uint32_t id)
{
	return LL_DMA_IsEnabledIT_TC(dma, dma_stm32_id_to_stream(id)) &&
	       dma_stm32_is_tc_active(dma, id);
}

inline bool stm32_dma_is_ht_irq_active(DMA_TypeDef *dma, uint32_t id)
{
	return LL_DMA_IsEnabledIT_HT(dma, dma_stm32_id_to_stream(id)) &&
	       dma_stm32_is_ht_active(dma, id);
}

static inline bool stm32_dma_is_te_irq_active(DMA_TypeDef *dma, uint32_t id)
{
	return LL_DMA_IsEnabledIT_TE(dma, dma_stm32_id_to_stream(id)) &&
	       dma_stm32_is_te_active(dma, id);
}

static inline bool stm32_dma_is_dme_irq_active(DMA_TypeDef *dma, uint32_t id)
{
	return LL_DMA_IsEnabledIT_DME(dma, dma_stm32_id_to_stream(id)) &&
	       dma_stm32_is_dme_active(dma, id);
}

static inline bool stm32_dma_is_fe_irq_active(DMA_TypeDef *dma, uint32_t id)
{
	return LL_DMA_IsEnabledIT_FE(dma, dma_stm32_id_to_stream(id)) &&
	       dma_stm32_is_fe_active(dma, id);
}

bool stm32_dma_is_irq_active(DMA_TypeDef *dma, uint32_t id)
{
	return stm32_dma_is_tc_irq_active(dma, id) ||
	       stm32_dma_is_ht_irq_active(dma, id) ||
	       stm32_dma_is_te_irq_active(dma, id) ||
	       stm32_dma_is_dme_irq_active(dma, id) ||
	       stm32_dma_is_fe_irq_active(dma, id);
}

void stm32_dma_clear_stream_irq(DMA_TypeDef *dma, uint32_t id)
{
	dma_stm32_clear_te(dma, id);
	dma_stm32_clear_dme(dma, id);
	dma_stm32_clear_fe(dma, id);
}

bool stm32_dma_is_irq_happened(DMA_TypeDef *dma, uint32_t id)
{
	if (LL_DMA_IsEnabledIT_FE(dma, dma_stm32_id_to_stream(id)) &&
	    dma_stm32_is_fe_active(dma, id)) {
		return true;
	}

	return false;
}

bool stm32_dma_is_unexpected_irq_happened(DMA_TypeDef *dma, uint32_t id)
{
	if (LL_DMA_IsEnabledIT_FE(dma, dma_stm32_id_to_stream(id)) &&
	    dma_stm32_is_fe_active(dma, id)) {
		LOG_ERR("FiFo error.");
		stm32_dma_dump_stream_irq(dma, id);
		stm32_dma_clear_stream_irq(dma, id);

		return true;
	}

	return false;
}

void stm32_dma_enable_stream(DMA_TypeDef *dma, uint32_t id)
{
	LL_DMA_EnableStream(dma, dma_stm32_id_to_stream(id));
}

int stm32_dma_disable_stream(DMA_TypeDef *dma, uint32_t id)
{
	LL_DMA_DisableStream(dma, dma_stm32_id_to_stream(id));

	if (!LL_DMA_IsEnabledStream(dma, dma_stm32_id_to_stream(id))) {
		return 0;
	}

	return -EAGAIN;
}

void stm32_dma_disable_fifo_irq(DMA_TypeDef *dma, uint32_t id)
{
	LL_DMA_DisableIT_FE(dma, dma_stm32_id_to_stream(id));
}

#if !defined(CONFIG_DMAMUX_STM32)
void stm32_dma_config_channel_function(DMA_TypeDef *dma, uint32_t id,
					uint32_t slot)
{
	LL_DMA_SetChannelSelection(dma, dma_stm32_id_to_stream(id),
			dma_stm32_slot_to_channel(slot));
}
#endif

uint32_t stm32_dma_get_mburst(struct dma_config *config, bool source_periph)
{
	uint32_t memory_burst;

	if (source_periph) {
		memory_burst = config->dest_burst_length;
	} else {
		memory_burst = config->source_burst_length;
	}

	switch (memory_burst) {
	case 1:
		return LL_DMA_MBURST_SINGLE;
	case 4:
		return LL_DMA_MBURST_INC4;
	case 8:
		return LL_DMA_MBURST_INC8;
	case 16:
		return LL_DMA_MBURST_INC16;
	default:
		LOG_ERR("Memory burst size error,"
			"using single burst as default");
		return LL_DMA_MBURST_SINGLE;
	}
}

uint32_t stm32_dma_get_pburst(struct dma_config *config, bool source_periph)
{
	uint32_t periph_burst;

	if (source_periph) {
		periph_burst = config->source_burst_length;
	} else {
		periph_burst = config->dest_burst_length;
	}

	switch (periph_burst) {
	case 1:
		return LL_DMA_PBURST_SINGLE;
	case 4:
		return LL_DMA_PBURST_INC4;
	case 8:
		return LL_DMA_PBURST_INC8;
	case 16:
		return LL_DMA_PBURST_INC16;
	default:
		LOG_ERR("Peripheral burst size error,"
			"using single burst as default");
		return LL_DMA_PBURST_SINGLE;
	}
}

/*
 * This function checks if the msize, mburst and fifo level is
 * compatible. If they are not compatible, refer to the 'FIFO'
 * section in the 'DMA' chapter in the Reference Manual for more
 * information.
 * break is emitted since every path of the code has 'return'.
 * This function does not have the obligation of checking the parameters.
 */
bool stm32_dma_check_fifo_mburst(LL_DMA_InitTypeDef *DMAx)
{
	uint32_t msize = DMAx->MemoryOrM2MDstDataSize;
	uint32_t fifo_level = DMAx->FIFOThreshold;
	uint32_t mburst = DMAx->MemBurst;

	switch (msize) {
	case LL_DMA_MDATAALIGN_BYTE:
		switch (mburst) {
		case LL_DMA_MBURST_INC4:
			return true;
		case LL_DMA_MBURST_INC8:
			if (fifo_level == LL_DMA_FIFOTHRESHOLD_1_2 ||
			    fifo_level == LL_DMA_FIFOTHRESHOLD_FULL) {
				return true;
			} else {
				return false;
			}
		case LL_DMA_MBURST_INC16:
			if (fifo_level == LL_DMA_FIFOTHRESHOLD_FULL) {
				return true;
			} else {
				return false;
			}
		}
	case LL_DMA_MDATAALIGN_HALFWORD:
		switch (mburst) {
		case LL_DMA_MBURST_INC4:
			if (fifo_level == LL_DMA_FIFOTHRESHOLD_1_2 ||
			    fifo_level == LL_DMA_FIFOTHRESHOLD_FULL) {
				return true;
			} else {
				return false;
			}
		case LL_DMA_MBURST_INC8:
			if (fifo_level == LL_DMA_FIFOTHRESHOLD_FULL) {
				return true;
			} else {
				return false;
			}
		case LL_DMA_MBURST_INC16:
			return false;
		}
	case LL_DMA_MDATAALIGN_WORD:
		if (mburst == LL_DMA_MBURST_INC4 &&
		    fifo_level == LL_DMA_FIFOTHRESHOLD_FULL) {
			return true;
		} else {
			return false;
		}
	default:
		return false;
	}
}

uint32_t stm32_dma_get_fifo_threshold(uint16_t fifo_mode_control)
{
	switch (fifo_mode_control) {
	case 0:
		return LL_DMA_FIFOTHRESHOLD_1_4;
	case 1:
		return LL_DMA_FIFOTHRESHOLD_1_2;
	case 2:
		return LL_DMA_FIFOTHRESHOLD_3_4;
	case 3:
		return LL_DMA_FIFOTHRESHOLD_FULL;
	default:
		LOG_WRN("FIFO threshold parameter error, reset to 1/4");
		return LL_DMA_FIFOTHRESHOLD_1_4;
	}
}
