/*
 * 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 <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;
	}
}
