/*
 * 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.
 */

#ifndef __DMA_H_
#define __DMA_H_

#include <errno.h>
#include "clk.h"
#include "qm_dma.h"

/* Timeout definitions */
#define STANDARD_TIMEOUT_MICROSECOND (1000)
#define ONE_MICROSECOND (1)

/* Set specific register bits */
#define UPDATE_REG_BITS(reg, value, offset, mask)                              \
	{                                                                      \
		reg &= ~mask;                                                  \
		reg |= (value << offset);                                      \
	}                                                                      \
	while (0)

/* Mask for all supported channels */
#define CHANNEL_MASK_ALL (BIT(QM_DMA_CHANNEL_NUM) - 1)

/*
 * DMA address increment type.
 */
typedef enum {
	QM_DMA_ADDRESS_INCREMENT = 0x0, /**< Increment address. */
	QM_DMA_ADDRESS_DECREMENT = 0x1, /**< Decrement address. */
	QM_DMA_ADDRESS_NO_CHANGE = 0x2  /**< Don't modify address. */
} qm_dma_address_increment_t;

/*
 * DMA channel private structure.
 */
typedef struct dma_cfg_prv_t {
	/* DMA client context to be passed back with callbacks */
	void *callback_context;

	/* DMA channel transfer callback */
	void (*client_callback)(void *callback_context, uint32_t len,
				int error_code);

	/* Pointer to latest configured LLI (multiblock linked list). */
	qm_dma_linked_list_item_t *lli_tail;

	/*
	 * Number of contiguous blocks per buffer (multiblock mode). This is
	 * needed to calculate the total transfer length which is communicated
	 * to the client with the complete callback. In linked list mode, where
	 * more than one buffer (scatter/gather) are used, this is also used to
	 * count single block transfer callbacks so that we know when to invoke
	 * the client callback corresponding to a whole transfered buffer.
	 */
	uint16_t num_blocks_per_buffer;

	/*
	 * Number of block interrupts pending on the buffer currently being
	 * transfered. Used in multiblock continuous mode as well as multiblock
	 * link list mode when more than one buffer is set up. This counter is
	 * decremented on each block interrupt.
	 */
	uint16_t num_blocks_int_pending;

	/*
	 * In multiblock linked list mode, indicates whether transfer is linear
	 * or circular. This information cannot be extracted from the DMA regs.
	 */
	bool transfer_type_ll_circular;
} dma_cfg_prv_t;

/*
 * The length of the transfer at the time that this function is called is
 * returned. The value returned is defined in bytes.
 */
static __inline__ uint32_t
get_transfer_length(const qm_dma_t dma, const qm_dma_channel_id_t channel_id,
		    const dma_cfg_prv_t *prv_cfg)
{
	uint32_t source_transfer_width;
	uint32_t transfer_length;
	uint32_t ctrl_low;
	uint32_t ctrl_high;

	QM_ASSERT(prv_cfg != NULL);
	if (NULL == prv_cfg->lli_tail) {
		/* Single block or contiguous multiblock. */
		volatile qm_dma_chan_reg_t *chan_reg =
		    &QM_DMA[dma]->chan_reg[channel_id];
		ctrl_low = chan_reg->ctrl_low;
		ctrl_high = chan_reg->ctrl_high;
	} else {
		/* Linked list multiblock. */
		ctrl_low = prv_cfg->lli_tail->ctrl_low;
		ctrl_high = prv_cfg->lli_tail->ctrl_high;
	}

	/* Read the source transfer width register value. */
	source_transfer_width = ((ctrl_low & QM_DMA_CTL_L_SRC_TR_WIDTH_MASK) >>
				 QM_DMA_CTL_L_SRC_TR_WIDTH_OFFSET);

	/* Read the length from the block_ts field. The units of this field
	 * are dependent on the source transfer width. */
	transfer_length = ((ctrl_high & QM_DMA_CTL_H_BLOCK_TS_MASK) >>
			   QM_DMA_CTL_H_BLOCK_TS_OFFSET) *
			  prv_cfg->num_blocks_per_buffer;

	/* To convert this to bytes the transfer length can be shifted using
	 * the source transfer width value. This value correspond to the
	 * shifts required and so this can be done as an optimization. */
	return (transfer_length << source_transfer_width);
}

static __inline__ int dma_controller_disable(const qm_dma_t dma)
{
	volatile qm_dma_misc_reg_t *misc_reg = &QM_DMA[dma]->misc_reg;

	misc_reg->cfg_low = 0;
	if (misc_reg->cfg_low) {
		return -EIO;
	}

	return 0;
}

static __inline__ void dma_controller_enable(const qm_dma_t dma)
{
	QM_DMA[dma]->misc_reg.cfg_low = QM_DMA_MISC_CFG_DMA_EN;
}

static int dma_channel_disable(const qm_dma_t dma,
			       const qm_dma_channel_id_t channel_id)
{
	uint8_t channel_mask = BIT(channel_id);
	uint16_t timeout_us;
	volatile qm_dma_misc_reg_t *misc_reg = &QM_DMA[dma]->misc_reg;
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];

	/* If the channel is already disabled return */
	if (!(misc_reg->chan_en_low & channel_mask)) {
		return 0;
	}

	/* Suspend the channel */
	chan_reg->cfg_low |= QM_DMA_CFG_L_CH_SUSP_MASK;

	/* Ensure that the channel has been suspended */
	timeout_us = STANDARD_TIMEOUT_MICROSECOND;
	while ((!(chan_reg->cfg_low & QM_DMA_CFG_L_CH_SUSP_MASK)) &&
	       timeout_us) {
		clk_sys_udelay(ONE_MICROSECOND);
		timeout_us--;
	}

	if (!(chan_reg->cfg_low & QM_DMA_CFG_L_CH_SUSP_MASK)) {
		return -EIO;
	}

	/* Wait until the fifo is empty */
	timeout_us = STANDARD_TIMEOUT_MICROSECOND;
	while ((!(chan_reg->cfg_low & QM_DMA_CFG_L_FIFO_EMPTY_MASK)) &&
	       timeout_us) {
		clk_sys_udelay(ONE_MICROSECOND);
		timeout_us--;
	}

	/* Disable the channel and wait to confirm that it has been disabled. */
	misc_reg->chan_en_low = (channel_mask << QM_DMA_MISC_CHAN_EN_WE_OFFSET);

	timeout_us = STANDARD_TIMEOUT_MICROSECOND;
	while ((misc_reg->chan_en_low & channel_mask) && timeout_us) {
		clk_sys_udelay(ONE_MICROSECOND);
		timeout_us--;
	}

	if (misc_reg->chan_en_low & channel_mask) {
		return -EIO;
	}

	/* Set the channel to resume */
	chan_reg->cfg_low &= ~QM_DMA_CFG_L_CH_SUSP_MASK;

	return 0;
}

static __inline__ void dma_channel_enable(const qm_dma_t dma,
					  const qm_dma_channel_id_t channel_id)
{
	uint8_t channel_mask = BIT(channel_id);

	QM_DMA[dma]->misc_reg.chan_en_low =
	    (channel_mask << QM_DMA_MISC_CHAN_EN_WE_OFFSET) | channel_mask;
}

static __inline__ void
dma_interrupt_disable(const qm_dma_t dma, const qm_dma_channel_id_t channel_id)
{
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];

	chan_reg->ctrl_low &= ~QM_DMA_CTL_L_INT_EN_MASK;
}

static __inline__ void
dma_interrupt_enable(const qm_dma_t dma, const qm_dma_channel_id_t channel_id)
{
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];

	chan_reg->ctrl_low |= QM_DMA_CTL_L_INT_EN_MASK;
}

static __inline__ int
dma_set_transfer_type(const qm_dma_t dma, const qm_dma_channel_id_t channel_id,
		      const qm_dma_transfer_type_t transfer_type,
		      const qm_dma_channel_direction_t channel_direction)
{
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];

	/*
	 * Valid for single block and contiguous multiblock, will be later
	 * updated if using linked list multiblock.
	 */
	chan_reg->llp_low = 0x0;

	/* Currently only single block is supported */
	switch (transfer_type) {
	case QM_DMA_TYPE_SINGLE:
		chan_reg->ctrl_low &= ~QM_DMA_CTL_L_LLP_SRC_EN_MASK;
		chan_reg->ctrl_low &= ~QM_DMA_CTL_L_LLP_DST_EN_MASK;
		chan_reg->cfg_low &= ~QM_DMA_CFG_L_RELOAD_SRC_MASK;
		chan_reg->cfg_low &= ~QM_DMA_CFG_L_RELOAD_DST_MASK;
		break;

	case QM_DMA_TYPE_MULTI_CONT:
		if (QM_DMA_MEMORY_TO_MEMORY == channel_direction) {
			/*
			 * The DMA core cannot handle memory to memory
			 * multiblock contiguous transactions.
			 */
			return -EINVAL;
		} else if (QM_DMA_PERIPHERAL_TO_MEMORY == channel_direction) {
			/* Reload source. */
			chan_reg->cfg_low |= QM_DMA_CFG_L_RELOAD_SRC_MASK;
			chan_reg->cfg_low &= ~QM_DMA_CFG_L_RELOAD_DST_MASK;
		} else {
			/* Reload destination. */
			chan_reg->cfg_low |= QM_DMA_CFG_L_RELOAD_DST_MASK;
			chan_reg->cfg_low &= ~QM_DMA_CFG_L_RELOAD_SRC_MASK;
		}

		/* Disable block chaining. */
		chan_reg->ctrl_low &= ~QM_DMA_CTL_L_LLP_SRC_EN_MASK;
		chan_reg->ctrl_low &= ~QM_DMA_CTL_L_LLP_DST_EN_MASK;
		break;

	case QM_DMA_TYPE_MULTI_LL:
	case QM_DMA_TYPE_MULTI_LL_CIRCULAR:
		/* Destination status update disable. */
		chan_reg->cfg_high &= ~QM_DMA_CFG_H_DS_UPD_EN_MASK;

		/* Source status update disable. */
		chan_reg->cfg_high &= ~QM_DMA_CFG_H_SS_UPD_EN_MASK;

		/* Enable linked lists for source. */
		chan_reg->ctrl_low |= QM_DMA_CTL_L_LLP_SRC_EN_MASK;
		chan_reg->cfg_low &= ~QM_DMA_CFG_L_RELOAD_SRC_MASK;

		/* Enable linked lists for destination. */
		chan_reg->ctrl_low |= QM_DMA_CTL_L_LLP_DST_EN_MASK;
		chan_reg->cfg_low &= ~QM_DMA_CFG_L_RELOAD_DST_MASK;
		break;

	default:
		return -EINVAL;
	}

	return 0;
}

static __inline__ qm_dma_transfer_type_t
dma_get_transfer_type(const qm_dma_t dma, const qm_dma_channel_id_t channel_id,
		      const dma_cfg_prv_t *prv_cfg)
{
	qm_dma_transfer_type_t transfer_type;
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];

	if (0 == (chan_reg->ctrl_low & (QM_DMA_CTL_L_LLP_SRC_EN_MASK |
					QM_DMA_CTL_L_LLP_DST_EN_MASK))) {
		/* Block chaining disabled */
		if (0 == (chan_reg->cfg_low & (QM_DMA_CFG_L_RELOAD_SRC_MASK |
					       QM_DMA_CFG_L_RELOAD_DST_MASK))) {
			/* Single block transfer */
			transfer_type = QM_DMA_TYPE_SINGLE;
		} else {
			/* Contiguous multiblock */
			transfer_type = QM_DMA_TYPE_MULTI_CONT;
		}
	} else {
		/* LLP enabled, linked list multiblock */
		transfer_type = (prv_cfg->transfer_type_ll_circular)
				    ? QM_DMA_TYPE_MULTI_LL_CIRCULAR
				    : QM_DMA_TYPE_MULTI_LL;
	}

	return transfer_type;
}

static __inline__ void
dma_set_source_transfer_width(const qm_dma_t dma,
			      const qm_dma_channel_id_t channel_id,
			      const qm_dma_transfer_width_t transfer_width)
{
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];

	UPDATE_REG_BITS(chan_reg->ctrl_low, transfer_width,
			QM_DMA_CTL_L_SRC_TR_WIDTH_OFFSET,
			QM_DMA_CTL_L_SRC_TR_WIDTH_MASK);
}

static __inline__ void
dma_set_destination_transfer_width(const qm_dma_t dma,
				   const qm_dma_channel_id_t channel_id,
				   const qm_dma_transfer_width_t transfer_width)
{
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];

	UPDATE_REG_BITS(chan_reg->ctrl_low, transfer_width,
			QM_DMA_CTL_L_DST_TR_WIDTH_OFFSET,
			QM_DMA_CTL_L_DST_TR_WIDTH_MASK);
}

static __inline__ void
dma_set_source_burst_length(const qm_dma_t dma,
			    const qm_dma_channel_id_t channel_id,
			    const qm_dma_burst_length_t burst_length)
{
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];

	UPDATE_REG_BITS(chan_reg->ctrl_low, burst_length,
			QM_DMA_CTL_L_SRC_MSIZE_OFFSET,
			QM_DMA_CTL_L_SRC_MSIZE_MASK);
}

static __inline__ void
dma_set_destination_burst_length(const qm_dma_t dma,
				 const qm_dma_channel_id_t channel_id,
				 const qm_dma_burst_length_t burst_length)
{
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];

	UPDATE_REG_BITS(chan_reg->ctrl_low, burst_length,
			QM_DMA_CTL_L_DEST_MSIZE_OFFSET,
			QM_DMA_CTL_L_DEST_MSIZE_MASK);
}

static __inline__ void
dma_set_transfer_direction(const qm_dma_t dma,
			   const qm_dma_channel_id_t channel_id,
			   const qm_dma_channel_direction_t transfer_direction)
{
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];

	UPDATE_REG_BITS(chan_reg->ctrl_low, transfer_direction,
			QM_DMA_CTL_L_TT_FC_OFFSET, QM_DMA_CTL_L_TT_FC_MASK);
}

static __inline__ void
dma_set_source_increment(const qm_dma_t dma,
			 const qm_dma_channel_id_t channel_id,
			 const qm_dma_address_increment_t address_increment)
{
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];

	UPDATE_REG_BITS(chan_reg->ctrl_low, address_increment,
			QM_DMA_CTL_L_SINC_OFFSET, QM_DMA_CTL_L_SINC_MASK);
}

static __inline__ void dma_set_destination_increment(
    const qm_dma_t dma, const qm_dma_channel_id_t channel_id,
    const qm_dma_address_increment_t address_increment)
{
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];

	UPDATE_REG_BITS(chan_reg->ctrl_low, address_increment,
			QM_DMA_CTL_L_DINC_OFFSET, QM_DMA_CTL_L_DINC_MASK);
}

static __inline__ void dma_set_handshake_interface(
    const qm_dma_t dma, const qm_dma_channel_id_t channel_id,
    const qm_dma_handshake_interface_t handshake_interface)
{
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];

	UPDATE_REG_BITS(chan_reg->cfg_high, handshake_interface,
			QM_DMA_CFG_H_SRC_PER_OFFSET, QM_DMA_CFG_H_SRC_PER_MASK);

	UPDATE_REG_BITS(chan_reg->cfg_high, handshake_interface,
			QM_DMA_CFG_H_DEST_PER_OFFSET,
			QM_DMA_CFG_H_DEST_PER_MASK);
}

static __inline__ void
dma_set_handshake_type(const qm_dma_t dma, const qm_dma_channel_id_t channel_id,
		       const uint8_t handshake_type)
{
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];

	UPDATE_REG_BITS(chan_reg->cfg_low, handshake_type,
			QM_DMA_CFG_L_HS_SEL_SRC_OFFSET,
			QM_DMA_CFG_L_HS_SEL_SRC_MASK);

	UPDATE_REG_BITS(chan_reg->cfg_low, handshake_type,
			QM_DMA_CFG_L_HS_SEL_DST_OFFSET,
			QM_DMA_CFG_L_HS_SEL_DST_MASK);
}

static __inline__ void
dma_set_handshake_polarity(const qm_dma_t dma,
			   const qm_dma_channel_id_t channel_id,
			   const qm_dma_handshake_polarity_t handshake_polarity)
{
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];

	UPDATE_REG_BITS(chan_reg->cfg_low, handshake_polarity,
			QM_DMA_CFG_L_SRC_HS_POL_OFFSET,
			QM_DMA_CFG_L_SRC_HS_POL_MASK);

	UPDATE_REG_BITS(chan_reg->cfg_low, handshake_polarity,
			QM_DMA_CFG_L_DST_HS_POL_OFFSET,
			QM_DMA_CFG_L_DST_HS_POL_MASK);
}

static __inline__ void
dma_set_source_address(const qm_dma_t dma, const qm_dma_channel_id_t channel_id,
		       const uint32_t source_address)
{
	QM_DMA[dma]->chan_reg[channel_id].sar_low = source_address;
}

static __inline__ void
dma_set_destination_address(const qm_dma_t dma,
			    const qm_dma_channel_id_t channel_id,
			    const uint32_t destination_address)
{
	QM_DMA[dma]->chan_reg[channel_id].dar_low = destination_address;
}

static __inline__ void dma_set_block_size(const qm_dma_t dma,
					  const qm_dma_channel_id_t channel_id,
					  const uint32_t block_size)
{
	volatile qm_dma_chan_reg_t *chan_reg =
	    &QM_DMA[dma]->chan_reg[channel_id];

	UPDATE_REG_BITS(chan_reg->ctrl_high, block_size,
			QM_DMA_CTL_H_BLOCK_TS_OFFSET,
			QM_DMA_CTL_H_BLOCK_TS_MASK);
}

#endif /* __DMA_H_ */
