/* Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER 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 <bam.h>
#include <reg.h>
#include <debug.h>
#include <stdlib.h>
#include <arch/ops.h>
#include <platform.h>
#include <platform/interrupts.h>
#include <platform/iomap.h>
#include <platform/irqs.h>
#include <pow2.h>

#define HLOS_EE_INDEX          0

/* Resets pipe registers and state machines */
void bam_pipe_reset(struct bam_instance *bam,
					uint8_t pipe_num)
{
	/* Start sw reset of the pipe to be allocated */
	writel(1, BAM_P_RSTn(bam->pipe[pipe_num].pipe_num, bam->base));

	/* No delay required */

	/* Stop sw reset of the pipe to be allocated */
	writel(0, BAM_P_RSTn(bam->pipe[pipe_num].pipe_num, bam->base));
}

static enum handler_return bam_interrupt_handler(void* arg)
{
	return 0;
}

/* A blocking function that waits till an interrupt is signalled.
 * bam : BAM instance for the descriptors to be queued.
 * pipe_num : pipe number for the descriptors to be queued.
 * interrupt: interrupt to wait for.
 */
int bam_wait_for_interrupt(struct bam_instance *bam,
                           uint8_t pipe_num,
                           enum p_int_type interrupt)
{
	uint32_t val;

	while (1)
	{
		/* Wait for a interrupt on the right pipe */
		do{
			/* Determine the pipe causing the interrupt */
			val = readl(BAM_IRQ_SRCS(bam->base, bam->ee));
			/* Flush out the right most global interrupt bit */
		} while (!((val & 0x7FFF) & (1 << bam->pipe[pipe_num].pipe_num)));

		/* Check the interrupt type */
		/* Read interrupt status register */
		val = readl(BAM_P_IRQ_STTSn(bam->pipe[pipe_num].pipe_num, bam->base));

		/* Check for error */
		if (val & P_ERR_EN_MASK)
			goto bam_wait_int_error;

		if (val & interrupt)
		{
			/* Correct interrupt was fired. */
			 /* Clear the other interrupts */
			val = P_OUT_OF_DESC_EN_MASK | P_PRCSD_DESC_EN_MASK | P_TRNSFR_END_EN_MASK;
			writel (val, BAM_P_IRQ_CLRn(bam->pipe[pipe_num].pipe_num, bam->base));
			return BAM_RESULT_SUCCESS;
		}
	}

bam_wait_int_error:

	dprintf(CRITICAL, "Unexpected interrupt : val %u\n", val);
	return BAM_RESULT_FAILURE;
}

/* Enable BAM and pipe level interrupts */
void bam_enable_interrupts(struct bam_instance *bam, uint8_t pipe_num)
{

	uint32_t int_mask = P_ERR_EN_MASK | P_OUT_OF_DESC_EN_MASK |
						P_PRCSD_DESC_EN_MASK;
	uint32_t val;

	/* Leave BAM error interrupts disabled. */
	/* Enable the interrupts for the pipe by enabling the relevant bits
	 * in the BAM_PIPE_INTERRUPT_ENABLE register.
	 */
	writel(int_mask,
			BAM_P_IRQ_ENn(bam->pipe[pipe_num].pipe_num, bam->base));

	/* Enable pipe interrups */
	/* Do read-modify-write */
	val = readl(BAM_IRQ_SRCS_MSK(bam->base, bam->ee));
	writel((1 << bam->pipe[pipe_num].pipe_num) | val,
			BAM_IRQ_SRCS_MSK(bam->base, bam->ee));

	/* Unmask the QGIC interrupts only in the case of
	 * interrupt based transfer.
	 * Use polling othwerwise.
	 */
	if (bam->pipe[pipe_num].int_mode)
	{
		/* Register interrupt handler */
		register_int_handler(bam->pipe[pipe_num].spi_num, bam_interrupt_handler, 0);

		/* Unmask the interrupt */
		unmask_interrupt(bam->pipe[pipe_num].spi_num);
	}
}

/* Reset and initialize the bam module */
void bam_init(struct bam_instance *bam)
{
	/* bam is initialized by TZ, so nothing needs to be done here */
}

/* Funtion to setup a simple fifo structure.
 * Note: Addr should be 8 byte aligned.
 * bam : BAM instance for the descriptors to be queued.
 * pipe_num : pipe number for the descriptors to be queued.
 */
int bam_pipe_fifo_init(struct bam_instance *bam,
                       uint8_t pipe_num)
{
	if (bam->pipe[pipe_num].fifo.size > 0x7FFF)
	{
		dprintf(CRITICAL,
				"Size exceeds max size for a descriptor(0x7FFF)\n");
		return BAM_RESULT_FAILURE;
	}

	/* Check if fifo start is 8-byte alligned */
	ASSERT(!((uint32_t)PA((addr_t)bam->pipe[pipe_num].fifo.head & 0x7)));

	/* Check if fifo size is a power of 2.
	 * The circular fifo logic in lk expects this.
	 */
	ASSERT(ispow2(bam->pipe[pipe_num].fifo.size));

	bam->pipe[pipe_num].fifo.current = bam->pipe[pipe_num].fifo.head;

	/* Set the descriptor buffer size. Must be a multiple of 8 */
	writel(bam->pipe[pipe_num].fifo.size * BAM_DESC_SIZE,
		BAM_P_FIFO_SIZESn(bam->pipe[pipe_num].pipe_num, bam->base));

	/* Write descriptors FIFO base addr must be 8-byte aligned */
	/* Needs a physical address conversion as we are setting up
	 * the base of the FIFO for the BAM state machine.
	 */
	writel((uint32_t)PA((addr_t)bam->pipe[pipe_num].fifo.head),
		BAM_P_DESC_FIFO_ADDRn(bam->pipe[pipe_num].pipe_num, bam->base));

	/* Initialize FIFO offset for the first read */
	bam->pipe[pipe_num].fifo.offset = BAM_DESC_SIZE;

	writel(P_ENABLE | readl(BAM_P_CTRLn(bam->pipe[pipe_num].pipe_num, bam->base)),
		   BAM_P_CTRLn(bam->pipe[pipe_num].pipe_num, bam->base));

	/* Everything is set.
	 * Flag pipe init done.
	 */
	 bam->pipe[pipe_num].initialized = 1;

	return BAM_RESULT_SUCCESS;
}

void bam_sys_pipe_init(struct bam_instance *bam,
                       uint8_t pipe_num)
{
	/* Reset the pipe to be allocated */
	bam_pipe_reset(bam, pipe_num);

	/* Enable minimal interrupts */
	bam_enable_interrupts(bam, pipe_num);

	/* Pipe event threshold register is not relevant in sys modes */

	/* Enable pipe in system mode and set the direction */
	writel(P_SYS_MODE_MASK | bam->pipe[pipe_num].lock_grp <<  P_LOCK_GRP_SHIFT |
		   (bam->pipe[pipe_num].trans_type << P_DIRECTION_SHIFT),
		   BAM_P_CTRLn(bam->pipe[pipe_num].pipe_num, bam->base));

	/* Mark the pipe FIFO as uninitialized. */
	bam->pipe[pipe_num].initialized = 0;
}

/* Function to notify written descriptors to BAM.
 * bam : BAM instance for the descriptors to be queued.
 * pipe_num : pipe number for the descriptors to be queued.
 * num_desc : number of the descriptors.
 * fifo : Circular FIFO used for the descriptors.
 */
void bam_sys_gen_event(struct bam_instance *bam,
                       uint8_t pipe_num,
                       unsigned int num_desc)
{
	uint32_t val = 0;

	if (num_desc >= bam->pipe[pipe_num].fifo.size) {
		dprintf(CRITICAL,
				"Max allowed desc is one less than the fifo length\n");
		return;
	}

	/* bits 0:15 of BAM_P_EVNT_REGn denotes the offset. We read the offset,
	 * and update the offset to notify BAM HW that new descriptors have been written
	 */
	val = readl(BAM_P_EVNT_REGn(bam->pipe[pipe_num].pipe_num, bam->base));

	/* Update the fifo peer offset */
	val += (num_desc) * BAM_DESC_SIZE;
	val &= (bam->pipe[pipe_num].fifo.size * BAM_DESC_SIZE - 1);

	writel(val, BAM_P_EVNT_REGn(bam->pipe[pipe_num].pipe_num, bam->base));
}

/* Function to read the updates for FIFO offsets.
 * bam : BAM that uses the FIFO.
 * pipe : BAM pipe that uses the FIFO.
 * return : void.
 * Note : As per IPCAT This register denotes the pointer Offset of the first un-Acknowledged Descriptor.
 *        This register is only used by the Software. After receiving an interrupt, software reads this register
 *        in order to know what descriptors has been processed. Although being Writable, Software
 *        should never write to this register.
 */
void bam_read_offset_update(struct bam_instance *bam, unsigned int pipe_num)
{
	uint32_t offset;

	offset = readl(BAM_P_SW_OFSTSn(bam->pipe[pipe_num].pipe_num, bam->base));
	offset &= 0xFFFF;

	dprintf(SPEW, "Offset value is %d \n", offset);
}

/* Function to get the next desc address.
 * Keeps track of circular properties of the FIFO
 * and returns the appropriate address.
 */
static struct bam_desc* fifo_getnext(struct bam_desc_fifo *fifo,
                                     struct bam_desc* desc)
{
	uint16_t offset;

	offset = desc - fifo->head;

	if (offset == (fifo->size - 1))
		return fifo->head;
	else
		return desc + 1;
}

/* Function to add BAM descriptors for a given fifo.
 * bam : BAM instance to be used.
 * data_ptr : Physical memory address for data transfer.
 * data_len : Length of the data_ptr.
 * flags : Flags to be set on the last desc added.
 *
 * Note: This function also notifies the BAM about the added descriptors.
 */
int bam_add_desc(struct bam_instance *bam,
                 unsigned int pipe_num,
                 unsigned char *data_ptr,
                 unsigned int data_len,
                 unsigned flags)
{
	int bam_ret = BAM_RESULT_SUCCESS;
	unsigned int len = data_len;
	unsigned int desc_len;
	unsigned int n = 0;
	unsigned int desc_flags;

	dprintf(SPEW, "Data length for BAM transfer is %u\n", data_len);

	if (data_ptr == NULL || len == 0)
	{
		dprintf(CRITICAL, "Wrong params for BAM transfer \n");
		bam_ret = BAM_RESULT_FAILURE;
		goto bam_add_desc_error;
	}

	/* Check if we have enough space in FIFO */
	if (len > (unsigned)bam->pipe[pipe_num].fifo.size * bam->max_desc_len)
	{
		dprintf(CRITICAL, "Data transfer exceeds desc fifo length.\n");
		bam_ret = BAM_RESULT_FAILURE;
		goto bam_add_desc_error;
	}

	while (len)
	{

		/* There are only 16 bits to write data length.
		 * If more bits are needed, create more
		 * descriptors.
		 */
		if (len > bam->max_desc_len)
		{
			desc_len = bam->max_desc_len;
			len -= bam->max_desc_len;
			desc_flags = 0;
		}
		else
		{
			desc_len = len;
			len = 0;
			/* Set correct flags on the last desc. */
			desc_flags = flags;
		}

		/* Write descriptor */
		bam_add_one_desc(bam, pipe_num, data_ptr, desc_len, desc_flags);

		data_ptr += bam->max_desc_len;
		n++;
	}


	/* Create a read/write event to notify the periperal of the added desc. */
	bam_sys_gen_event(bam, pipe_num, n);

bam_add_desc_error:

	return bam_ret;
}

/* Function to add a BAM descriptor for a given fifo.
 * bam : BAM instance to be used.
 * data_ptr : Memory address for data transfer.
 * data_len : Length of the data_ptr.
 * flags : Flags to be set on the desc added.
 *
 * Note: This function does not notify the BAM about the added descriptor.
 */
int bam_add_one_desc(struct bam_instance *bam,
                     unsigned int pipe_num,
                     unsigned char* data_ptr,
                     uint32_t len,
                     uint8_t flags)
{

	struct bam_desc *desc = bam->pipe[pipe_num].fifo.current;
	int bam_ret = BAM_RESULT_SUCCESS;

	if (data_ptr == NULL || len == 0)
	{
		dprintf(CRITICAL, "Wrong params for BAM transfer \n");
		bam_ret = BAM_RESULT_FAILURE;
		goto bam_add_one_desc_error;
	}

	/* Check if the FIFO is allocated for the pipe */
	if (!bam->pipe[pipe_num].initialized)
	{
		dprintf(CRITICAL, "Please allocate the FIFO for the BAM pipe %d\n",
				bam->pipe[pipe_num].pipe_num);
		bam_ret = BAM_RESULT_FAILURE;
		goto bam_add_one_desc_error;
	}

	if ((flags & BAM_DESC_LOCK_FLAG) && (flags & BAM_DESC_UNLOCK_FLAG))
	{
		dprintf(CRITICAL, "Can't lock and unlock in the same desc\n");
		bam_ret = BAM_RESULT_FAILURE;
		goto bam_add_one_desc_error;
	}

	/* Setting EOT flag on a CMD desc is not valid */
	if ((flags & BAM_DESC_EOT_FLAG) && (flags & BAM_DESC_CMD_FLAG))
	{
		dprintf(CRITICAL, "EOT flag set on the CMD desc\n");
		bam_ret = BAM_RESULT_FAILURE;
		goto bam_add_one_desc_error;
	}

	/* Check for the length of the desc. */
	if (len > bam->max_desc_len)
	{
		dprintf(CRITICAL, "len of the desc exceeds max length"
				" %d > %d\n", len, bam->max_desc_len);
		bam_ret = BAM_RESULT_FAILURE;
		goto bam_add_one_desc_error;
	}

	desc->flags    = flags;
	desc->addr     = (uint32_t)data_ptr;
	desc->size     = (uint16_t)len;
	desc->reserved = 0;

	arch_clean_invalidate_cache_range((addr_t) VA((addr_t)data_ptr), len);
	arch_clean_invalidate_cache_range((addr_t) desc, BAM_DESC_SIZE);

	/* Update the FIFO to point to the head */
	bam->pipe[pipe_num].fifo.current = fifo_getnext(&bam->pipe[pipe_num].fifo, desc);

bam_add_one_desc_error:
	return bam_ret;
}

struct cmd_element* bam_add_cmd_element(struct cmd_element *ptr,
                                        uint32_t reg_addr,
                                        uint32_t value,
                                        enum bam_ce_cmd_t cmd_type)
{
	/* Write cmd type.
	 * Also, write the register address.
	 */
	 ptr->addr_n_cmd = (reg_addr & ~(0xFF000000)) | (cmd_type << 24);

	/* Do not mask any of the addr bits by default */
	ptr->reg_mask = 0xFFFFFFFF;

	/* Write the value to be written */
	ptr->reg_data = value;

	/* Return the address to add the next element to */
	return ptr + 1;
}
