/* Copyright (c) 2014-2015, 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>

#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)
	{
		*dest++ = *src++;
		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++ = *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);
	}

	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*/
	while ((ch->port_info->ch1.write_index - ch->port_info->ch1.read_index) < sizeof(smd_pkt_hdr))
	{
		/* Get the update info from memory */
		arch_invalidate_cache_range((addr_t) ch->port_info, size);
	}

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

	arch_invalidate_cache_range((addr_t)&smd_hdr, sizeof(smd_hdr));

	*len = smd_hdr.pkt_size;

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

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

	arch_invalidate_cache_range((addr_t)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()
{
	int i = 0;
	for(i = 0; i< SMEM_NUM_SMD_STREAM_CHANNELS; i++)
	{
		arch_invalidate_cache_range((addr_t)&smd_channel_alloc_entry[i],
						sizeof(smd_channel_alloc_entry_t));
	}
}

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(CRITICAL,"Channel alloc freed\n");
	}

	return INT_NO_RESCHEDULE;
}
