/*
 * Copyright (c) 2017, Intel Corporation
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. Neither the name of the Intel Corporation nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "clk.h"
#include "dma.h"

#ifndef UNIT_TEST
qm_dma_reg_t *qm_dma[QM_DMA_NUM] = {(qm_dma_reg_t *)QM_DMA_BASE};
#endif

/* DMA driver private data structures */
dma_cfg_prv_t dma_channel_config[QM_DMA_NUM][QM_DMA_CHANNEL_NUM] = {{{0}}};

/*
 * Transfer interrupt handler.
 * - Single block: TFR triggers an user callback invocation
 * - Multiblock (contiguous): TFR triggers an user callback invocation, block
 *   interrupts are silent
 * - Multiblock (linked list): Last block interrupt on each buffer triggers an
 *   user callback invocation, TFR is silent
 */
static void qm_dma_isr_handler(const qm_dma_t dma,
			       const qm_dma_channel_id_t channel_id)
{
	dma_cfg_prv_t *prv_cfg = &dma_channel_config[dma][channel_id];
	volatile qm_dma_int_reg_t *int_reg = &QM_DMA[dma]->int_reg;
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];
	uint32_t transfer_length =
	    get_transfer_length(dma, channel_id, prv_cfg);

	/* The status can't be asserted here as there is a possible race
	 * condition when terminating channels. It's possible that an interrupt
	 * can be generated before the terminate function masks the
	 * interrupts. */

	if (int_reg->status_int_low & QM_DMA_INT_STATUS_TFR) {

		QM_ASSERT(int_reg->status_tfr_low & BIT(channel_id));

		/* Transfer completed, clear interrupt */
		int_reg->clear_tfr_low = BIT(channel_id);

		/* If multiblock, the final block is also completed. */
		int_reg->clear_block_low = BIT(channel_id);

		/* Mask interrupts for this channel */
		int_reg->mask_block_low = BIT(channel_id) << 8;
		int_reg->mask_tfr_low = BIT(channel_id) << 8;
		int_reg->mask_err_low = BIT(channel_id) << 8;

		/* Clear llp register */
		chan_reg->llp_low = 0;

		/*
		 * Call the callback if registered and pass the transfer length.
		 */
		if (prv_cfg->client_callback) {
			/* Single block or contiguous multiblock. */
			prv_cfg->client_callback(prv_cfg->callback_context,
						 transfer_length, 0);
		}
	} else if (int_reg->status_int_low & QM_DMA_INT_STATUS_BLOCK) {
		/* Block interrupts are only unmasked in multiblock mode. */
		QM_ASSERT(int_reg->status_block_low & BIT(channel_id));

		/* Block completed, clear interrupt. */
		int_reg->clear_block_low = BIT(channel_id);

		prv_cfg->num_blocks_int_pending--;

		if (NULL != prv_cfg->lli_tail &&
		    0 == prv_cfg->num_blocks_int_pending) {
			/*
			 * Linked list mode, invoke callback if this is last
			 * block of buffer.
			 */
			if (prv_cfg->client_callback) {
				prv_cfg->client_callback(
				    prv_cfg->callback_context, transfer_length,
				    0);
			}

			/* Buffer done, set for next buffer. */
			prv_cfg->num_blocks_int_pending =
			    prv_cfg->num_blocks_per_buffer;

		} else if (NULL == prv_cfg->lli_tail) {
			QM_ASSERT(prv_cfg->num_blocks_int_pending <
				  prv_cfg->num_blocks_per_buffer);
			if (1 == prv_cfg->num_blocks_int_pending) {
				/*
				 * Contiguous mode. We have just processed the
				 * next to last block, clear CFG.RELOAD so
				 * that the next block is the last one to be
				 * transfered.
				 */
				chan_reg->cfg_low &=
				    ~QM_DMA_CFG_L_RELOAD_SRC_MASK;
				chan_reg->cfg_low &=
				    ~QM_DMA_CFG_L_RELOAD_DST_MASK;
			}
		}
	}
}

/*
 * Error interrupt handler.
 */
static void qm_dma_isr_err_handler(const qm_dma_t dma)
{
	uint32_t interrupt_channel_mask;
	dma_cfg_prv_t *chan_cfg;
	qm_dma_channel_id_t channel_id = 0;
	volatile qm_dma_int_reg_t *int_reg = &QM_DMA[dma]->int_reg;

	QM_ASSERT(int_reg->status_int_low & QM_DMA_INT_STATUS_ERR);
	QM_ASSERT(int_reg->status_err_low);

	interrupt_channel_mask = int_reg->status_err_low;
	while (interrupt_channel_mask) {

		/* Find the channel that the interrupt is for */
		if (!(interrupt_channel_mask & 0x1)) {
			interrupt_channel_mask >>= 1;
			channel_id++;
			continue;
		}

		/* Clear the error interrupt for this channel */
		int_reg->clear_err_low = BIT(channel_id);

		/* Mask interrupts for this channel */
		int_reg->mask_block_low = BIT(channel_id) << 8;
		int_reg->mask_tfr_low = BIT(channel_id) << 8;
		int_reg->mask_err_low = BIT(channel_id) << 8;

		/* Call the callback if registered and pass the
		 * transfer error code */
		chan_cfg = &dma_channel_config[dma][channel_id];
		if (chan_cfg->client_callback) {
			chan_cfg->client_callback(chan_cfg->callback_context, 0,
						  -EIO);
		}

		interrupt_channel_mask >>= 1;
		channel_id++;
	}
}

QM_ISR_DECLARE(qm_dma_0_error_isr)
{
	qm_dma_isr_err_handler(QM_DMA_0);
	QM_ISR_EOI(QM_IRQ_DMA_0_ERROR_INT_VECTOR);
}

QM_ISR_DECLARE(qm_dma_0_isr_0)
{
	qm_dma_isr_handler(QM_DMA_0, QM_DMA_CHANNEL_0);
	QM_ISR_EOI(QM_IRQ_DMA_0_INT_0_VECTOR);
}

QM_ISR_DECLARE(qm_dma_0_isr_1)
{
	qm_dma_isr_handler(QM_DMA_0, QM_DMA_CHANNEL_1);
	QM_ISR_EOI(QM_IRQ_DMA_0_INT_1_VECTOR);
}

#if (QUARK_SE)
QM_ISR_DECLARE(qm_dma_0_isr_2)
{
	qm_dma_isr_handler(QM_DMA_0, QM_DMA_CHANNEL_2);
	QM_ISR_EOI(QM_IRQ_DMA_0_INT_2_VECTOR);
}

QM_ISR_DECLARE(qm_dma_0_isr_3)
{
	qm_dma_isr_handler(QM_DMA_0, QM_DMA_CHANNEL_3);
	QM_ISR_EOI(QM_IRQ_DMA_0_INT_3_VECTOR);
}

QM_ISR_DECLARE(qm_dma_0_isr_4)
{
	qm_dma_isr_handler(QM_DMA_0, QM_DMA_CHANNEL_4);
	QM_ISR_EOI(QM_IRQ_DMA_0_INT_4_VECTOR);
}

QM_ISR_DECLARE(qm_dma_0_isr_5)
{
	qm_dma_isr_handler(QM_DMA_0, QM_DMA_CHANNEL_5);
	QM_ISR_EOI(QM_IRQ_DMA_0_INT_5_VECTOR);
}

QM_ISR_DECLARE(qm_dma_0_isr_6)
{
	qm_dma_isr_handler(QM_DMA_0, QM_DMA_CHANNEL_6);
	QM_ISR_EOI(QM_IRQ_DMA_0_INT_6_VECTOR);
}

QM_ISR_DECLARE(qm_dma_0_isr_7)
{
	qm_dma_isr_handler(QM_DMA_0, QM_DMA_CHANNEL_7);
	QM_ISR_EOI(QM_IRQ_DMA_0_INT_7_VECTOR);
}
#endif /* QUARK_SE */

int qm_dma_init(const qm_dma_t dma)
{
	QM_CHECK(dma < QM_DMA_NUM, -EINVAL);

	qm_dma_channel_id_t channel_id;
	volatile qm_dma_int_reg_t *int_reg = &QM_DMA[dma]->int_reg;
	int return_code;

	/* Enable the DMA Clock */
	clk_dma_enable();

	/* Disable the controller */
	return_code = dma_controller_disable(dma);
	if (return_code) {
		return return_code;
	}

	/* Disable the channels and interrupts */
	for (channel_id = 0; channel_id < QM_DMA_CHANNEL_NUM; channel_id++) {
		return_code = dma_channel_disable(dma, channel_id);
		if (return_code) {
			return return_code;
		}
		dma_interrupt_disable(dma, channel_id);
	}

	/* Mask all interrupts */
	int_reg->mask_tfr_low = CHANNEL_MASK_ALL << 8;
	int_reg->mask_block_low = CHANNEL_MASK_ALL << 8;
	int_reg->mask_src_trans_low = CHANNEL_MASK_ALL << 8;
	int_reg->mask_dst_trans_low = CHANNEL_MASK_ALL << 8;
	int_reg->mask_err_low = CHANNEL_MASK_ALL << 8;

	/* Clear all interrupts */
	int_reg->clear_tfr_low = CHANNEL_MASK_ALL;
	int_reg->clear_block_low = CHANNEL_MASK_ALL;
	int_reg->clear_src_trans_low = CHANNEL_MASK_ALL;
	int_reg->clear_dst_trans_low = CHANNEL_MASK_ALL;
	int_reg->clear_err_low = CHANNEL_MASK_ALL;

	/* Enable the controller */
	dma_controller_enable(dma);

	return 0;
}

int qm_dma_channel_set_config(const qm_dma_t dma,
			      const qm_dma_channel_id_t channel_id,
			      qm_dma_channel_config_t *const channel_config)
{
	QM_CHECK(dma < QM_DMA_NUM, -EINVAL);
	QM_CHECK(channel_id < QM_DMA_CHANNEL_NUM, -EINVAL);
	QM_CHECK(channel_config != NULL, -EINVAL);

	dma_cfg_prv_t *chan_cfg = &dma_channel_config[dma][channel_id];
	int return_code;

	/* Set the transfer type. */
	return_code = dma_set_transfer_type(dma, channel_id,
					    channel_config->transfer_type,
					    channel_config->channel_direction);
	if (return_code) {
		return return_code;
	}

	/* Set the source and destination transfer width. */
	dma_set_source_transfer_width(dma, channel_id,
				      channel_config->source_transfer_width);
	dma_set_destination_transfer_width(
	    dma, channel_id, channel_config->destination_transfer_width);

	/* Set the source and destination burst transfer length. */
	dma_set_source_burst_length(dma, channel_id,
				    channel_config->source_burst_length);
	dma_set_destination_burst_length(
	    dma, channel_id, channel_config->destination_burst_length);

	/* Set channel direction */
	dma_set_transfer_direction(dma, channel_id,
				   channel_config->channel_direction);

	/* Set the increment type depending on direction */
	switch (channel_config->channel_direction) {
	case QM_DMA_PERIPHERAL_TO_MEMORY:
		dma_set_source_increment(dma, channel_id,
					 QM_DMA_ADDRESS_NO_CHANGE);
		dma_set_destination_increment(dma, channel_id,
					      QM_DMA_ADDRESS_INCREMENT);
		break;
	case QM_DMA_MEMORY_TO_PERIPHERAL:
		dma_set_source_increment(dma, channel_id,
					 QM_DMA_ADDRESS_INCREMENT);
		dma_set_destination_increment(dma, channel_id,
					      QM_DMA_ADDRESS_NO_CHANGE);
		break;
	case QM_DMA_MEMORY_TO_MEMORY:
		dma_set_source_increment(dma, channel_id,
					 QM_DMA_ADDRESS_INCREMENT);
		dma_set_destination_increment(dma, channel_id,
					      QM_DMA_ADDRESS_INCREMENT);
		break;
	}

	if (channel_config->channel_direction != QM_DMA_MEMORY_TO_MEMORY) {
		/* Set the handshake interface. */
		dma_set_handshake_interface(
		    dma, channel_id, channel_config->handshake_interface);

		/* Set the handshake type. This is hardcoded to hardware */
		dma_set_handshake_type(dma, channel_id, 0);

		/* Set the handshake polarity. */
		dma_set_handshake_polarity(dma, channel_id,
					   channel_config->handshake_polarity);
	}

	/* Save the client ID */
	chan_cfg->callback_context = channel_config->callback_context;

	/* Save the callback provided by DMA client */
	chan_cfg->client_callback = channel_config->client_callback;

	/* Multiblock linked list not configured. */
	chan_cfg->lli_tail = NULL;

	/* Number of blocks per buffer (>1 when multiblock). */
	chan_cfg->num_blocks_per_buffer = 1;

	/* Multiblock circular linked list flag. */
	chan_cfg->transfer_type_ll_circular =
	    (channel_config->transfer_type == QM_DMA_TYPE_MULTI_LL_CIRCULAR)
		? true
		: false;

	return 0;
}

int qm_dma_transfer_set_config(const qm_dma_t dma,
			       const qm_dma_channel_id_t channel_id,
			       qm_dma_transfer_t *const transfer_config)
{
	QM_CHECK(dma < QM_DMA_NUM, -EINVAL);
	QM_CHECK(channel_id < QM_DMA_CHANNEL_NUM, -EINVAL);
	QM_CHECK(transfer_config != NULL, -EINVAL);
	QM_CHECK(transfer_config->source_address != NULL, -EINVAL);
	QM_CHECK(transfer_config->destination_address != NULL, -EINVAL);
	QM_CHECK(transfer_config->block_size >= QM_DMA_CTL_H_BLOCK_TS_MIN,
		 -EINVAL);
	QM_CHECK(transfer_config->block_size <= QM_DMA_CTL_H_BLOCK_TS_MAX,
		 -EINVAL);

	/* Set the source and destination addresses. */
	dma_set_source_address(dma, channel_id,
			       (uint32_t)transfer_config->source_address);
	dma_set_destination_address(
	    dma, channel_id, (uint32_t)transfer_config->destination_address);

	/* Set the block size for the transfer. */
	dma_set_block_size(dma, channel_id, transfer_config->block_size);

	return 0;
}

/* Populate a linked list. */
static qm_dma_linked_list_item_t *
dma_linked_list_init(const qm_dma_multi_transfer_t *multi_transfer,
		     uint32_t ctrl_low, uint32_t tail_pointing_lli)
{
	uint32_t source_address = (uint32_t)multi_transfer->source_address;
	uint32_t destination_address =
	    (uint32_t)multi_transfer->destination_address;
	/*
	 * Extracted source/destination increment type, used to calculate
	 * address increment between consecutive blocks.
	 */
	qm_dma_address_increment_t source_address_inc_type =
	    (ctrl_low & QM_DMA_CTL_L_SINC_MASK) >> QM_DMA_CTL_L_SINC_OFFSET;
	qm_dma_address_increment_t destination_address_inc_type =
	    (ctrl_low & QM_DMA_CTL_L_DINC_MASK) >> QM_DMA_CTL_L_DINC_OFFSET;
	/* Linked list node iteration variable. */
	qm_dma_linked_list_item_t *lli = multi_transfer->linked_list_first;
	uint32_t source_inc = 0;
	uint32_t destination_inc = 0;
	uint32_t i;

	QM_ASSERT(source_address_inc_type == QM_DMA_ADDRESS_INCREMENT ||
		  source_address_inc_type == QM_DMA_ADDRESS_NO_CHANGE);
	QM_ASSERT(destination_address_inc_type == QM_DMA_ADDRESS_INCREMENT ||
		  destination_address_inc_type == QM_DMA_ADDRESS_NO_CHANGE);

	/*
	 * Memory endpoints increment the source/destination address between
	 * consecutive LLIs by the block size times the transfer width in
	 * bytes.
	 */
	if (source_address_inc_type == QM_DMA_ADDRESS_INCREMENT) {
		source_inc = multi_transfer->block_size *
			     BIT((ctrl_low & QM_DMA_CTL_L_SRC_TR_WIDTH_MASK) >>
				 QM_DMA_CTL_L_SRC_TR_WIDTH_OFFSET);
	}

	if (destination_address_inc_type == QM_DMA_ADDRESS_INCREMENT) {
		destination_inc =
		    multi_transfer->block_size *
		    BIT((ctrl_low & QM_DMA_CTL_L_DST_TR_WIDTH_MASK) >>
			QM_DMA_CTL_L_DST_TR_WIDTH_OFFSET);
	}

	for (i = 0; i < multi_transfer->num_blocks; i++) {
		lli->source_address = source_address;
		lli->destination_address = destination_address;
		lli->ctrl_low = ctrl_low;
		lli->ctrl_high = multi_transfer->block_size;
		if (i < (uint32_t)(multi_transfer->num_blocks - 1)) {
			lli->linked_list_address =
			    (uint32_t)(qm_dma_linked_list_item_t *)(lli + 1);
			lli++;
			source_address += source_inc;
			destination_address += destination_inc;
		} else {
			/* Last node. */
			lli->linked_list_address = tail_pointing_lli;
		}
	}

	/* Last node of the populated linked list. */
	return lli;
}

int qm_dma_multi_transfer_set_config(
    const qm_dma_t dma, const qm_dma_channel_id_t channel_id,
    qm_dma_multi_transfer_t *const multi_transfer_config)
{
	QM_CHECK(dma < QM_DMA_NUM, -EINVAL);
	QM_CHECK(channel_id < QM_DMA_CHANNEL_NUM, -EINVAL);
	QM_CHECK(multi_transfer_config != NULL, -EINVAL);
	QM_CHECK(multi_transfer_config->source_address != NULL, -EINVAL);
	QM_CHECK(multi_transfer_config->destination_address != NULL, -EINVAL);
	QM_CHECK(multi_transfer_config->block_size >= QM_DMA_CTL_H_BLOCK_TS_MIN,
		 -EINVAL);
	QM_CHECK(multi_transfer_config->block_size <= QM_DMA_CTL_H_BLOCK_TS_MAX,
		 -EINVAL);
	QM_CHECK(multi_transfer_config->num_blocks > 0, -EINVAL);

	dma_cfg_prv_t *prv_cfg = &dma_channel_config[dma][channel_id];
	qm_dma_transfer_type_t transfer_type =
	    dma_get_transfer_type(dma, channel_id, prv_cfg);
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];
	/*
	 * Node to which last node points to, 0 on linear linked lists or first
	 * node on circular linked lists.
	 */
	uint32_t tail_pointing_lli;

	/*
	 * Initialize block counting internal variables, needed in ISR to manage
	 * client callback invocations.
	 */
	if (0 == chan_reg->llp_low) {
		prv_cfg->num_blocks_per_buffer =
		    multi_transfer_config->num_blocks;
	}
	prv_cfg->num_blocks_int_pending = multi_transfer_config->num_blocks;

	switch (transfer_type) {
	case QM_DMA_TYPE_MULTI_CONT:
		/* Contiguous multiblock transfer. */
		dma_set_source_address(
		    dma, channel_id,
		    (uint32_t)multi_transfer_config->source_address);
		dma_set_destination_address(
		    dma, channel_id,
		    (uint32_t)multi_transfer_config->destination_address);
		dma_set_block_size(dma, channel_id,
				   multi_transfer_config->block_size);
		break;

	case QM_DMA_TYPE_MULTI_LL:
		/*
		 * Block interrupts are not enabled in linear linked list with
		 * single buffer as only one client callback invocation is
		 * needed, which takes place on transfer callback interrupt.
		 */
		if (0 == chan_reg->llp_low) {
			prv_cfg->num_blocks_int_pending = 0;
		}
	/* FALLTHROUGH - continue to common circular/linear LL code */

	case QM_DMA_TYPE_MULTI_LL_CIRCULAR:
		if (multi_transfer_config->linked_list_first == NULL ||
		    ((uint32_t)multi_transfer_config->linked_list_first &
		     0x3) != 0) {
			/*
			 * User-allocated linked list memory needs to be 4-byte
			 * alligned.
			 */
			return -EINVAL;
		}

		if (0 == chan_reg->llp_low) {
			/*
			 * Either first call to this function after DMA channel
			 * config or transfer reconfiguration after a completed
			 * multiblock transfer.
			 */
			tail_pointing_lli =
			    (transfer_type == QM_DMA_TYPE_MULTI_LL_CIRCULAR)
				? (uint32_t)
				      multi_transfer_config->linked_list_first
				: 0;

			/*
			 * Initialize LLIs using CTL drom DMA register (plus
			 * INT_EN bit).
			 */
			prv_cfg->lli_tail = dma_linked_list_init(
			    multi_transfer_config,
			    chan_reg->ctrl_low | QM_DMA_CTL_L_INT_EN_MASK,
			    tail_pointing_lli);

			/* Point DMA LLP register to this LLI. */
			chan_reg->llp_low =
			    (uint32_t)multi_transfer_config->linked_list_first;
		} else {
			/*
			 * Linked list multiblock transfer (additional appended
			 * LLIs). The number of blocks needs to match the number
			 * of blocks on previous calls to this function (we only
			 * allow scatter/gather buffers of same size).
			 */
			if (prv_cfg->num_blocks_per_buffer !=
			    multi_transfer_config->num_blocks) {
				return -EINVAL;
			}

			/*
			 * Reference to NULL (linear LL) or the first LLI node
			 * (circular LL), extracted from previously configured
			 * linked list.
			 */
			tail_pointing_lli =
			    prv_cfg->lli_tail->linked_list_address;

			/*
			 * Point last previously configured linked list to this
			 * node.
			 */
			prv_cfg->lli_tail->linked_list_address =
			    (uint32_t)multi_transfer_config->linked_list_first;

			/*
			 * Initialize LLI using CTL from last previously
			 * configured LLI, returning a pointer to the new tail
			 * node.
			 */
			prv_cfg->lli_tail = dma_linked_list_init(
			    multi_transfer_config, prv_cfg->lli_tail->ctrl_low,
			    tail_pointing_lli);

			QM_ASSERT(prv_cfg->lli_tail->linked_list_address ==
				  tail_pointing_lli);
		}
		break;

	default:
		/* Single block not allowed */
		return -EINVAL;
		break;
	}

	return 0;
}

int qm_dma_transfer_start(const qm_dma_t dma,
			  const qm_dma_channel_id_t channel_id)
{
	QM_CHECK(dma < QM_DMA_NUM, -EINVAL);
	QM_CHECK(channel_id < QM_DMA_CHANNEL_NUM, -EINVAL);

	volatile qm_dma_int_reg_t *int_reg = &QM_DMA[dma]->int_reg;
	dma_cfg_prv_t *prv_cfg = &dma_channel_config[dma][channel_id];

	/* Clear all interrupts as they may be asserted from a previous
	 * transfer */
	int_reg->clear_tfr_low = BIT(channel_id);
	int_reg->clear_block_low = BIT(channel_id);
	int_reg->clear_err_low = BIT(channel_id);

	/* Unmask Interrupts */
	int_reg->mask_tfr_low = ((BIT(channel_id) << 8) | BIT(channel_id));
	int_reg->mask_err_low = ((BIT(channel_id) << 8) | BIT(channel_id));

	if (prv_cfg->num_blocks_int_pending > 0) {
		/*
		 * Block interrupts are only unmasked in multiblock mode
		 * (contiguous, circular linked list or multibuffer linear
		 * linked list).
		 */
		int_reg->mask_block_low =
		    ((BIT(channel_id) << 8) | BIT(channel_id));
	}

	/* Enable interrupts and the channel */
	dma_interrupt_enable(dma, channel_id);
	dma_channel_enable(dma, channel_id);

	return 0;
}

int qm_dma_transfer_terminate(const qm_dma_t dma,
			      const qm_dma_channel_id_t channel_id)
{
	QM_CHECK(dma < QM_DMA_NUM, -EINVAL);
	QM_CHECK(channel_id < QM_DMA_CHANNEL_NUM, -EINVAL);

	int return_code;
	volatile qm_dma_int_reg_t *int_reg = &QM_DMA[dma]->int_reg;
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];

	/* Disable interrupts for the channel */
	dma_interrupt_disable(dma, channel_id);

	/* Mask Interrupts */
	int_reg->mask_tfr_low = (BIT(channel_id) << 8);
	int_reg->mask_block_low = (BIT(channel_id) << 8);
	int_reg->mask_err_low = (BIT(channel_id) << 8);

	/* Clear llp register */
	chan_reg->llp_low = 0;

	/* The channel is disabled and the transfer complete callback is
	 * triggered. This callback provides the client with the data length
	 * transferred before the transfer was stopped. */
	return_code = dma_channel_disable(dma, channel_id);
	if (!return_code) {
		dma_cfg_prv_t *prv_cfg = &dma_channel_config[dma][channel_id];
		if (prv_cfg->client_callback) {
			prv_cfg->client_callback(
			    prv_cfg->callback_context,
			    get_transfer_length(dma, channel_id, prv_cfg), 0);
		}
	}

	return return_code;
}

int qm_dma_transfer_mem_to_mem(const qm_dma_t dma,
			       const qm_dma_channel_id_t channel_id,
			       qm_dma_transfer_t *const transfer_config)
{
	QM_CHECK(dma < QM_DMA_NUM, -EINVAL);
	QM_CHECK(channel_id < QM_DMA_CHANNEL_NUM, -EINVAL);
	QM_CHECK(transfer_config != NULL, -EINVAL);
	QM_CHECK(transfer_config->source_address != NULL, -EINVAL);
	QM_CHECK(transfer_config->destination_address != NULL, -EINVAL);
	QM_CHECK(transfer_config->block_size <= QM_DMA_CTL_H_BLOCK_TS_MAX,
		 -EINVAL);

	int return_code;

	/* Set the transfer configuration and start the transfer */
	return_code =
	    qm_dma_transfer_set_config(dma, channel_id, transfer_config);
	if (!return_code) {
		return_code = qm_dma_transfer_start(dma, channel_id);
	}

	return return_code;
}

#if (ENABLE_RESTORE_CONTEXT)
int qm_dma_save_context(const qm_dma_t dma, qm_dma_context_t *const ctx)
{
	QM_CHECK(dma < QM_DMA_NUM, -EINVAL);
	QM_CHECK(ctx != NULL, -EINVAL);
	int i;

	QM_RW qm_dma_misc_reg_t *misc_reg = &QM_DMA[dma]->misc_reg;

	ctx->misc_cfg_low = misc_reg->cfg_low;

	for (i = 0; i < QM_DMA_CHANNEL_NUM; i++) {
		QM_RW qm_dma_chan_reg_t *chan_reg = &QM_DMA[dma]->chan_reg[i];

		/* Masking the bit QM_DMA_CTL_L_INT_EN_MASK disables a possible
		* trigger of a new transition. */
		ctx->channel[i].ctrl_low =
		    chan_reg->ctrl_low & ~QM_DMA_CTL_L_INT_EN_MASK;
		ctx->channel[i].cfg_low = chan_reg->cfg_low;
		ctx->channel[i].cfg_high = chan_reg->cfg_high;
		ctx->channel[i].llp_low = chan_reg->llp_low;
	}
	return 0;
}

int qm_dma_restore_context(const qm_dma_t dma,
			   const qm_dma_context_t *const ctx)
{
	QM_CHECK(dma < QM_DMA_NUM, -EINVAL);
	QM_CHECK(ctx != NULL, -EINVAL);
	int i;
	QM_RW qm_dma_misc_reg_t *misc_reg = &QM_DMA[dma]->misc_reg;

	misc_reg->cfg_low = ctx->misc_cfg_low;

	for (i = 0; i < QM_DMA_CHANNEL_NUM; i++) {
		QM_RW qm_dma_chan_reg_t *chan_reg = &QM_DMA[dma]->chan_reg[i];

		chan_reg->ctrl_low = ctx->channel[i].ctrl_low;
		chan_reg->cfg_low = ctx->channel[i].cfg_low;
		chan_reg->cfg_high = ctx->channel[i].cfg_high;
		chan_reg->llp_low = ctx->channel[i].llp_low;
	}
	return 0;
}
#else
int qm_dma_save_context(const qm_dma_t dma, qm_dma_context_t *const ctx)
{
	(void)dma;
	(void)ctx;

	return 0;
}

int qm_dma_restore_context(const qm_dma_t dma,
			   const qm_dma_context_t *const ctx)
{
	(void)dma;
	(void)ctx;

	return 0;
}
#endif /* ENABLE_RESTORE_CONTEXT */
