/* Copyright (c) 2014-2015, 2018, 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 Fundation, Inc. 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 <smd.h>
#include <smem.h>
#include <debug.h>
#include <kernel/event.h>
#include <platform/irqs.h>
#include <platform/iomap.h>
#include <platform/interrupts.h>
#include <platform/timer.h>
#include <reg.h>
#include <malloc.h>
#include <bits.h>
#include <stdlib.h>

#define SMD_CHANNEL_ACCESS_RETRY 1000000

smd_channel_alloc_entry_t *smd_channel_alloc_entry;
static event_t smd_closed;

static void smd_write_state(smd_channel_info_t *ch, uint32_t state)
{
	if(state == SMD_SS_OPENED)
	{
		ch->port_info->ch0.DTR_DSR = 1;
		ch->port_info->ch0.CTS_RTS = 1;
		ch->port_info->ch0.CD = 1;
	}
	else
	{
		ch->port_info->ch0.DTR_DSR = 0;
		ch->port_info->ch0.CTS_RTS = 0;
		ch->port_info->ch0.CD = 0;
	}

	ch->port_info->ch0.stream_state = state;
}

static void smd_state_update(smd_channel_info_t *ch, uint32_t flag)
{
	ch->port_info->ch0.state_updated = flag;
}

int smd_get_channel_entry(smd_channel_info_t *ch, uint32_t ch_type)
{
	int i = 0;

	for(i = 0; i< SMEM_NUM_SMD_STREAM_CHANNELS; i++)
	{
		if((smd_channel_alloc_entry[i].ctype & 0xFF) == ch_type)
		{
			memcpy(&ch->alloc_entry, &smd_channel_alloc_entry[i], sizeof(smd_channel_alloc_entry_t));
			break;
		}
	}

	/* Channel not found, retry again */
	if(i == SMEM_NUM_SMD_STREAM_CHANNELS)
	{
		dprintf(SPEW, "Channel not found, wait and retry for the update\n");
		return -1;
	}

	return 0;
}

int smd_get_channel_info(smd_channel_info_t *ch, uint32_t ch_type)
{
	int ret = 0;
	uint8_t *fifo_buf = NULL;
	uint32_t fifo_buf_size = 0;
	uint32_t size = 0;

	ret = smd_get_channel_entry(ch, ch_type);

	if (ret)
		return ret;

	ch->port_info = smem_get_alloc_entry(SMEM_SMD_BASE_ID + ch->alloc_entry.cid,
										 &size);

	fifo_buf = smem_get_alloc_entry(SMEM_SMD_FIFO_BASE_ID + ch->alloc_entry.cid,
									&fifo_buf_size);

	fifo_buf_size /= 2;
	ch->send_buf = fifo_buf;
	ch->recv_buf = fifo_buf + fifo_buf_size;
	ch->fifo_size = fifo_buf_size;

	return ret;
}

int smd_init(smd_channel_info_t *ch, uint32_t ch_type)
{
	unsigned ret = 0;
	int chnl_found = 0;
	uint64_t timeout = SMD_CHANNEL_ACCESS_RETRY;

	smd_channel_alloc_entry = (smd_channel_alloc_entry_t*)memalign(CACHE_LINE, SMD_CHANNEL_ALLOC_MAX);
	ASSERT(smd_channel_alloc_entry);

	dprintf(INFO, "Waiting for the RPM to populate smd channel table\n");

	do
	{
		ret = smem_read_alloc_entry(SMEM_CHANNEL_ALLOC_TBL,
									(void*)smd_channel_alloc_entry,
									SMD_CHANNEL_ALLOC_MAX);
		if(ret)
		{
			dprintf(CRITICAL,"ERROR reading smem channel alloc tbl\n");
			return -1;
		}

		chnl_found = smd_get_channel_info(ch, ch_type);
		timeout--;
		udelay(10);
	} while(timeout && chnl_found);

	if (!timeout)
	{
		dprintf(CRITICAL, "Apps timed out waiting for RPM-->APPS channel entry\n");
		ASSERT(0);
	}

	register_int_handler(SMD_IRQ, smd_irq_handler, ch);

	smd_set_state(ch, SMD_SS_OPENING, 1);

	smd_notify_rpm();

	unmask_interrupt(SMD_IRQ);

	return 0;
}

void smd_uninit(smd_channel_info_t *ch)
{
	event_init(&smd_closed, false, EVENT_FLAG_AUTOUNSIGNAL);
	smd_set_state(ch, SMD_SS_CLOSING, 1);

	smd_notify_rpm();
	/* Wait for the SMD-RPM channel to be closed */
	event_wait(&smd_closed);
}

bool is_channel_open(smd_channel_info_t *ch)
{
	if(ch->port_info->ch0.stream_state == SMD_SS_OPENED &&
	  (ch->port_info->ch1.stream_state == SMD_SS_OPENED ||
	   ch->port_info->ch1.stream_state == SMD_SS_FLUSHING))
		return true;
	else
		return false;
}

/* Copy the local buffer to fifo buffer.
 * Takes care of fifo overlap.
 * Uses the fifo as circular buffer, if the request data
 * exceeds the max size of the buffer start from the beginning.
 */
static void memcpy_to_fifo(smd_channel_info_t *ch_ptr, uint32_t *src, size_t len)
{
	uint32_t write_index = ch_ptr->port_info->ch0.write_index;
	uint32_t *dest = (uint32_t *)(ch_ptr->send_buf + write_index);

	while(len)
	{
		writel(*src++, dest++);
		write_index += 4;
		len -= 4;

		if (write_index >= ch_ptr->fifo_size)
		{
			write_index = 0;
			dest = (uint32_t *)(ch_ptr->send_buf + write_index);
		}
	}
	ch_ptr->port_info->ch0.write_index = write_index;
}

/* Copy the fifo buffer to a local destination.
 * Takes care of fifo overlap.
 * If the response data is split across with some part at
 * end of fifo and some at the beginning of the fifo
 */
void memcpy_from_fifo(smd_channel_info_t *ch_ptr, uint32_t *dest, size_t len)
{
	uint32_t read_index = ch_ptr->port_info->ch1.read_index;
	uint32_t *src = (uint32_t *)(ch_ptr->recv_buf + read_index);

	while(len)
	{
		*dest++ = readl(src++);
		read_index += 4;
		len -= 4;

		if (read_index >= ch_ptr->fifo_size)
		{
			read_index = 0;
			src = (uint32_t *) (ch_ptr->recv_buf + read_index);
		}
	}

	ch_ptr->port_info->ch1.read_index = read_index;
}

void smd_read(smd_channel_info_t *ch, uint32_t *len, int ch_type, uint32_t *response)
{
	smd_pkt_hdr smd_hdr;
	uint32_t size = 0;

	/* Read the indices from smem */
	ch->port_info = smem_get_alloc_entry(SMEM_SMD_BASE_ID + ch->alloc_entry.cid,
										 &size);
	if(!ch->port_info)
	{
		dprintf(CRITICAL,"%s: unable to find index in smem\n", __func__);
		ASSERT(0);
	}

	arch_invalidate_cache_range((addr_t) ch->port_info, ROUNDUP(size, CACHE_LINE));
	if(!ch->port_info->ch1.DTR_DSR)
	{
		dprintf(CRITICAL,"%s: DTR is off\n", __func__);
		ASSERT(0);
	}

	/* Wait until the data updated in the smd buffer is equal to smd packet header*/
	do {
		/* Get the update info from memory */
		arch_invalidate_cache_range((addr_t) ch->port_info, ROUNDUP(size, CACHE_LINE));
	} while ((ch->port_info->ch1.write_index - ch->port_info->ch1.read_index) < sizeof(smd_pkt_hdr));

	/* Copy the smd buffer to local buf */
	memcpy_from_fifo(ch, (uint32_t *)&smd_hdr, sizeof(smd_hdr));


	*len = smd_hdr.pkt_size;

	/* Wait on the data being updated in SMEM before returing the response */
	do {
		/* Get the update info from memory */
		arch_invalidate_cache_range((addr_t) ch->port_info, ROUNDUP(size, CACHE_LINE));
	} while ((ch->port_info->ch1.write_index - ch->port_info->ch1.read_index) < smd_hdr.pkt_size);

	/* We are good to return the response now */
	memcpy_from_fifo(ch, response, smd_hdr.pkt_size);

}

void smd_signal_read_complete(smd_channel_info_t *ch, uint32_t len)
{
	/* Clear the data_written flag */
	ch->port_info->ch1.data_written = 0;

	/* Set the data_read flag */
	ch->port_info->ch0.data_read = 1;
	ch->port_info->ch0.mask_recv_intr = 1;

	dsb();

	smd_notify_rpm();
}

int smd_write(smd_channel_info_t *ch, void *data, uint32_t len, int ch_type)
{
	smd_pkt_hdr smd_hdr;
	uint32_t size = 0;

	memset(&smd_hdr, 0, sizeof(smd_pkt_hdr));

	if(len + sizeof(smd_hdr) > ch->fifo_size)
	{
		dprintf(CRITICAL,"%s: len is greater than fifo sz\n", __func__);
		return -1;
	}

	/* Read the indices from smem */
	ch->port_info = smem_get_alloc_entry(SMEM_SMD_BASE_ID + ch->alloc_entry.cid,
                                                        &size);
	if(!ch->port_info)
	{
		dprintf(CRITICAL,"%s: unable to find index in smem\n", __func__);
		ASSERT(0);
	}

	if(!is_channel_open(ch))
	{
		dprintf(CRITICAL,"%s: channel is not in OPEN state \n", __func__);
		return -1;
	}

	if(!ch->port_info->ch0.DTR_DSR)
	{
		dprintf(CRITICAL,"%s: DTR is off\n", __func__);
		return -1;
	}

	/* Clear the data_read flag */
	ch->port_info->ch1.data_read = 0;

	/*copy the local buf to smd buf */
	smd_hdr.pkt_size = len;

	memcpy_to_fifo(ch, (uint32_t *)&smd_hdr, sizeof(smd_hdr));

	memcpy_to_fifo(ch, data, len);

	dsb();

	/* Set the necessary flags */

	ch->port_info->ch0.data_written = 1;
	ch->port_info->ch0.mask_recv_intr = 0;

	dsb();

	smd_notify_rpm();

	return 0;
}

void smd_notify_rpm()
{
	/* Set BIT 0 to notify RPM via IPC interrupt*/
	writel(BIT(0), APCS_ALIAS0_IPC_INTERRUPT);
}

void smd_set_state(smd_channel_info_t *ch, uint32_t state, uint32_t flag)
{
	uint32_t current_state;
	uint32_t size = 0;

	if(!ch->port_info)
	{
		ch->port_info = smem_get_alloc_entry(SMEM_SMD_BASE_ID + ch->alloc_entry.cid,
							&size);
		ASSERT(ch->port_info);
	}

	current_state = ch->port_info->ch0.stream_state;

	switch(state)
	{
		case SMD_SS_CLOSED:
		if(current_state == SMD_SS_OPENED)
		{
			smd_write_state(ch, SMD_SS_CLOSING);
		}
		else
		{
			smd_write_state(ch, SMD_SS_CLOSED);
		}
		break;
		case SMD_SS_OPENING:
		if(current_state == SMD_SS_CLOSING || current_state == SMD_SS_CLOSED)
		{
			smd_write_state(ch, SMD_SS_OPENING);
			ch->port_info->ch1.read_index = 0;
			ch->port_info->ch0.write_index = 0;
			ch->port_info->ch0.mask_recv_intr = 0;
		}
		break;
		case SMD_SS_OPENED:
		if(current_state == SMD_SS_OPENING)
		{
			smd_write_state(ch, SMD_SS_OPENED);
		}
		break;
		case SMD_SS_CLOSING:
		if(current_state == SMD_SS_OPENED)
		{
			smd_write_state(ch, SMD_SS_CLOSING);
		}
		break;
		case SMD_SS_FLUSHING:
		case SMD_SS_RESET:
		case SMD_SS_RESET_OPENING:
		default:
		break;
	}

	ch->current_state = state;

	smd_state_update(ch, flag);
}

static void flush_smd_channel_entries()
{
	arch_invalidate_cache_range((addr_t)smd_channel_alloc_entry,
			SMD_CHANNEL_ALLOC_MAX);
}

enum handler_return smd_irq_handler(void* data)
{
	smd_channel_info_t *ch = (smd_channel_info_t*)data;

	if(ch->current_state == SMD_SS_CLOSED)
	{
		flush_smd_channel_entries();
		if(smd_channel_alloc_entry)
		{
			free(smd_channel_alloc_entry);
			smd_channel_alloc_entry = NULL;
		}
		event_signal(&smd_closed, false);
		return INT_NO_RESCHEDULE;
	}

	if(ch->port_info->ch1.state_updated)
		ch->port_info->ch1.state_updated = 0;

	/* Should we have to use a do while and change states until we complete */
	if(ch->current_state != ch->port_info->ch1.stream_state)
	{
		smd_set_state(ch, ch->port_info->ch1.stream_state, 0);
	}

	if(ch->current_state == SMD_SS_CLOSING)
	{
		smd_set_state(ch, SMD_SS_CLOSED, 1);
		smd_notify_rpm();
		dprintf(SPEW,"Channel alloc freed\n");
	}

	return INT_NO_RESCHEDULE;
}
