/*
 * strm.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * DSP/BIOS Bridge Stream Manager.
 *
 * Copyright (C) 2005-2006 Texas Instruments, Inc.
 *
 * This package is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include <linux/types.h>

/*  ----------------------------------- Host OS */
#include <dspbridge/host_os.h>

/*  ----------------------------------- DSP/BIOS Bridge */
#include <dspbridge/dbdefs.h>

/*  ----------------------------------- OS Adaptation Layer */
#include <dspbridge/sync.h>

/*  ----------------------------------- Bridge Driver */
#include <dspbridge/dspdefs.h>

/*  ----------------------------------- Resource Manager */
#include <dspbridge/nodepriv.h>

/*  ----------------------------------- Others */
#include <dspbridge/cmm.h>

/*  ----------------------------------- This */
#include <dspbridge/strm.h>

#include <dspbridge/resourcecleanup.h>

/*  ----------------------------------- Defines, Data Structures, Typedefs */
#define DEFAULTTIMEOUT      10000
#define DEFAULTNUMBUFS      2

/*
 *  ======== strm_mgr ========
 *  The strm_mgr contains device information needed to open the underlying
 *  channels of a stream.
 */
struct strm_mgr {
	struct dev_object *dev_obj;	/* Device for this processor */
	struct chnl_mgr *chnl_mgr;	/* Channel manager */
	/* Function interface to Bridge driver */
	struct bridge_drv_interface *intf_fxns;
};

/*
 *  ======== strm_object ========
 *  This object is allocated in strm_open().
 */
struct strm_object {
	struct strm_mgr *strm_mgr_obj;
	struct chnl_object *chnl_obj;
	u32 dir;		/* DSP_TONODE or DSP_FROMNODE */
	u32 timeout;
	u32 num_bufs;		/* Max # of bufs allowed in stream */
	u32 bufs_in_strm;	/* Current # of bufs in stream */
	u32 bytes;		/* bytes transferred since idled */
	/* STREAM_IDLE, STREAM_READY, ... */
	enum dsp_streamstate strm_state;
	void *user_event;	/* Saved for strm_get_info() */
	enum dsp_strmmode strm_mode;	/* STRMMODE_[PROCCOPY][ZEROCOPY]... */
	u32 dma_chnl_id;	/* DMA chnl id */
	u32 dma_priority;	/* DMA priority:DMAPRI_[LOW][HIGH] */
	u32 segment_id;		/* >0 is SM segment.=0 is local heap */
	u32 buf_alignment;	/* Alignment for stream bufs */
	/* Stream's SM address translator */
	struct cmm_xlatorobject *xlator;
};

/*  ----------------------------------- Function Prototypes */
static int delete_strm(struct strm_object *stream_obj);

/*
 *  ======== strm_allocate_buffer ========
 *  Purpose:
 *      Allocates buffers for a stream.
 */
int strm_allocate_buffer(struct strm_res_object *strmres, u32 usize,
				u8 **ap_buffer, u32 num_bufs,
				struct process_context *pr_ctxt)
{
	int status = 0;
	u32 alloc_cnt = 0;
	u32 i;
	struct strm_object *stream_obj = strmres->stream;

	if (stream_obj) {
		/*
		 * Allocate from segment specified at time of stream open.
		 */
		if (usize == 0)
			status = -EINVAL;

	} else {
		status = -EFAULT;
	}

	if (status)
		goto func_end;

	for (i = 0; i < num_bufs; i++) {
		(void)cmm_xlator_alloc_buf(stream_obj->xlator, &ap_buffer[i],
					   usize);
		if (ap_buffer[i] == NULL) {
			status = -ENOMEM;
			alloc_cnt = i;
			break;
		}
	}
	if (status)
		strm_free_buffer(strmres, ap_buffer, alloc_cnt, pr_ctxt);

	if (status)
		goto func_end;

	drv_proc_update_strm_res(num_bufs, strmres);

func_end:
	return status;
}

/*
 *  ======== strm_close ========
 *  Purpose:
 *      Close a stream opened with strm_open().
 */
int strm_close(struct strm_res_object *strmres,
		      struct process_context *pr_ctxt)
{
	struct bridge_drv_interface *intf_fxns;
	struct chnl_info chnl_info_obj;
	int status = 0;
	struct strm_object *stream_obj = strmres->stream;

	if (!stream_obj) {
		status = -EFAULT;
	} else {
		/* Have all buffers been reclaimed? If not, return
		 * -EPIPE */
		intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;
		status =
		    (*intf_fxns->chnl_get_info) (stream_obj->chnl_obj,
						     &chnl_info_obj);

		if (chnl_info_obj.cio_cs > 0 || chnl_info_obj.cio_reqs > 0)
			status = -EPIPE;
		else
			status = delete_strm(stream_obj);
	}

	if (status)
		goto func_end;

	idr_remove(pr_ctxt->stream_id, strmres->id);
func_end:
	dev_dbg(bridge, "%s: stream_obj: %p, status 0x%x\n", __func__,
		stream_obj, status);
	return status;
}

/*
 *  ======== strm_create ========
 *  Purpose:
 *      Create a STRM manager object.
 */
int strm_create(struct strm_mgr **strm_man,
		       struct dev_object *dev_obj)
{
	struct strm_mgr *strm_mgr_obj;
	int status = 0;

	*strm_man = NULL;
	/* Allocate STRM manager object */
	strm_mgr_obj = kzalloc(sizeof(struct strm_mgr), GFP_KERNEL);
	if (strm_mgr_obj == NULL)
		status = -ENOMEM;
	else
		strm_mgr_obj->dev_obj = dev_obj;

	/* Get Channel manager and Bridge function interface */
	if (!status) {
		status = dev_get_chnl_mgr(dev_obj, &(strm_mgr_obj->chnl_mgr));
		if (!status) {
			(void)dev_get_intf_fxns(dev_obj,
						&(strm_mgr_obj->intf_fxns));
		}
	}

	if (!status)
		*strm_man = strm_mgr_obj;
	else
		kfree(strm_mgr_obj);

	return status;
}

/*
 *  ======== strm_delete ========
 *  Purpose:
 *      Delete the STRM Manager Object.
 */
void strm_delete(struct strm_mgr *strm_mgr_obj)
{
	kfree(strm_mgr_obj);
}

/*
 *  ======== strm_free_buffer ========
 *  Purpose:
 *      Frees the buffers allocated for a stream.
 */
int strm_free_buffer(struct strm_res_object *strmres, u8 ** ap_buffer,
			    u32 num_bufs, struct process_context *pr_ctxt)
{
	int status = 0;
	u32 i = 0;
	struct strm_object *stream_obj = strmres->stream;

	if (!stream_obj)
		status = -EFAULT;

	if (!status) {
		for (i = 0; i < num_bufs; i++) {
			status =
			    cmm_xlator_free_buf(stream_obj->xlator,
						ap_buffer[i]);
			if (status)
				break;
			ap_buffer[i] = NULL;
		}
	}
	drv_proc_update_strm_res(num_bufs - i, strmres);

	return status;
}

/*
 *  ======== strm_get_info ========
 *  Purpose:
 *      Retrieves information about a stream.
 */
int strm_get_info(struct strm_object *stream_obj,
			 struct stream_info *stream_info,
			 u32 stream_info_size)
{
	struct bridge_drv_interface *intf_fxns;
	struct chnl_info chnl_info_obj;
	int status = 0;
	void *virt_base = NULL;	/* NULL if no SM used */

	if (!stream_obj) {
		status = -EFAULT;
	} else {
		if (stream_info_size < sizeof(struct stream_info)) {
			/* size of users info */
			status = -EINVAL;
		}
	}
	if (status)
		goto func_end;

	intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;
	status =
	    (*intf_fxns->chnl_get_info) (stream_obj->chnl_obj,
						  &chnl_info_obj);
	if (status)
		goto func_end;

	if (stream_obj->xlator) {
		/* We have a translator */
		cmm_xlator_info(stream_obj->xlator, (u8 **) &virt_base, 0,
				stream_obj->segment_id, false);
	}
	stream_info->segment_id = stream_obj->segment_id;
	stream_info->strm_mode = stream_obj->strm_mode;
	stream_info->virt_base = virt_base;
	stream_info->user_strm->number_bufs_allowed = stream_obj->num_bufs;
	stream_info->user_strm->number_bufs_in_stream = chnl_info_obj.cio_cs +
	    chnl_info_obj.cio_reqs;
	/* # of bytes transferred since last call to DSPStream_Idle() */
	stream_info->user_strm->number_bytes = chnl_info_obj.bytes_tx;
	stream_info->user_strm->sync_object_handle = chnl_info_obj.event_obj;
	/* Determine stream state based on channel state and info */
	if (chnl_info_obj.state & CHNL_STATEEOS) {
		stream_info->user_strm->ss_stream_state = STREAM_DONE;
	} else {
		if (chnl_info_obj.cio_cs > 0)
			stream_info->user_strm->ss_stream_state = STREAM_READY;
		else if (chnl_info_obj.cio_reqs > 0)
			stream_info->user_strm->ss_stream_state =
			    STREAM_PENDING;
		else
			stream_info->user_strm->ss_stream_state = STREAM_IDLE;

	}
func_end:
	return status;
}

/*
 *  ======== strm_idle ========
 *  Purpose:
 *      Idles a particular stream.
 */
int strm_idle(struct strm_object *stream_obj, bool flush_data)
{
	struct bridge_drv_interface *intf_fxns;
	int status = 0;

	if (!stream_obj) {
		status = -EFAULT;
	} else {
		intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;

		status = (*intf_fxns->chnl_idle) (stream_obj->chnl_obj,
						      stream_obj->timeout,
						      flush_data);
	}

	dev_dbg(bridge, "%s: stream_obj: %p flush_data: 0x%x status: 0x%x\n",
		__func__, stream_obj, flush_data, status);
	return status;
}

/*
 *  ======== strm_issue ========
 *  Purpose:
 *      Issues a buffer on a stream
 */
int strm_issue(struct strm_object *stream_obj, u8 *pbuf, u32 ul_bytes,
		      u32 ul_buf_size, u32 dw_arg)
{
	struct bridge_drv_interface *intf_fxns;
	int status = 0;
	void *tmp_buf = NULL;

	if (!stream_obj) {
		status = -EFAULT;
	} else {
		intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;

		if (stream_obj->segment_id != 0) {
			tmp_buf = cmm_xlator_translate(stream_obj->xlator,
						       (void *)pbuf,
						       CMM_VA2DSPPA);
			if (tmp_buf == NULL)
				status = -ESRCH;

		}
		if (!status) {
			status = (*intf_fxns->chnl_add_io_req)
			    (stream_obj->chnl_obj, pbuf, ul_bytes, ul_buf_size,
			     (u32) tmp_buf, dw_arg);
		}
		if (status == -EIO)
			status = -ENOSR;
	}

	dev_dbg(bridge, "%s: stream_obj: %p pbuf: %p ul_bytes: 0x%x dw_arg:"
		" 0x%x status: 0x%x\n", __func__, stream_obj, pbuf,
		ul_bytes, dw_arg, status);
	return status;
}

/*
 *  ======== strm_open ========
 *  Purpose:
 *      Open a stream for sending/receiving data buffers to/from a task or
 *      XDAIS socket node on the DSP.
 */
int strm_open(struct node_object *hnode, u32 dir, u32 index,
		     struct strm_attr *pattr,
		     struct strm_res_object **strmres,
		     struct process_context *pr_ctxt)
{
	struct strm_mgr *strm_mgr_obj;
	struct bridge_drv_interface *intf_fxns;
	u32 ul_chnl_id;
	struct strm_object *strm_obj = NULL;
	s8 chnl_mode;
	struct chnl_attr chnl_attr_obj;
	int status = 0;
	struct cmm_object *hcmm_mgr = NULL;	/* Shared memory manager hndl */

	void *stream_res;

	*strmres = NULL;
	if (dir != DSP_TONODE && dir != DSP_FROMNODE) {
		status = -EPERM;
	} else {
		/* Get the channel id from the node (set in node_connect()) */
		status = node_get_channel_id(hnode, dir, index, &ul_chnl_id);
	}
	if (!status)
		status = node_get_strm_mgr(hnode, &strm_mgr_obj);

	if (!status) {
		strm_obj = kzalloc(sizeof(struct strm_object), GFP_KERNEL);
		if (strm_obj == NULL) {
			status = -ENOMEM;
		} else {
			strm_obj->strm_mgr_obj = strm_mgr_obj;
			strm_obj->dir = dir;
			strm_obj->strm_state = STREAM_IDLE;
			strm_obj->user_event = pattr->user_event;
			if (pattr->stream_attr_in != NULL) {
				strm_obj->timeout =
				    pattr->stream_attr_in->timeout;
				strm_obj->num_bufs =
				    pattr->stream_attr_in->num_bufs;
				strm_obj->strm_mode =
				    pattr->stream_attr_in->strm_mode;
				strm_obj->segment_id =
				    pattr->stream_attr_in->segment_id;
				strm_obj->buf_alignment =
				    pattr->stream_attr_in->buf_alignment;
				strm_obj->dma_chnl_id =
				    pattr->stream_attr_in->dma_chnl_id;
				strm_obj->dma_priority =
				    pattr->stream_attr_in->dma_priority;
				chnl_attr_obj.uio_reqs =
				    pattr->stream_attr_in->num_bufs;
			} else {
				strm_obj->timeout = DEFAULTTIMEOUT;
				strm_obj->num_bufs = DEFAULTNUMBUFS;
				strm_obj->strm_mode = STRMMODE_PROCCOPY;
				strm_obj->segment_id = 0;	/* local mem */
				strm_obj->buf_alignment = 0;
				strm_obj->dma_chnl_id = 0;
				strm_obj->dma_priority = 0;
				chnl_attr_obj.uio_reqs = DEFAULTNUMBUFS;
			}
			chnl_attr_obj.reserved1 = NULL;
			/* DMA chnl flush timeout */
			chnl_attr_obj.reserved2 = strm_obj->timeout;
			chnl_attr_obj.event_obj = NULL;
			if (pattr->user_event != NULL)
				chnl_attr_obj.event_obj = pattr->user_event;

		}
	}
	if (status)
		goto func_cont;

	if ((pattr->virt_base == NULL) || !(pattr->virt_size > 0))
		goto func_cont;

	/* No System DMA */
	/* Get the shared mem mgr for this streams dev object */
	status = dev_get_cmm_mgr(strm_mgr_obj->dev_obj, &hcmm_mgr);
	if (!status) {
		/*Allocate a SM addr translator for this strm. */
		status = cmm_xlator_create(&strm_obj->xlator, hcmm_mgr, NULL);
		if (!status) {
			/*  Set translators Virt Addr attributes */
			status = cmm_xlator_info(strm_obj->xlator,
						 (u8 **) &pattr->virt_base,
						 pattr->virt_size,
						 strm_obj->segment_id, true);
		}
	}
func_cont:
	if (!status) {
		/* Open channel */
		chnl_mode = (dir == DSP_TONODE) ?
		    CHNL_MODETODSP : CHNL_MODEFROMDSP;
		intf_fxns = strm_mgr_obj->intf_fxns;
		status = (*intf_fxns->chnl_open) (&(strm_obj->chnl_obj),
						      strm_mgr_obj->chnl_mgr,
						      chnl_mode, ul_chnl_id,
						      &chnl_attr_obj);
		if (status) {
			/*
			 * over-ride non-returnable status codes so we return
			 * something documented
			 */
			if (status != -ENOMEM && status !=
			    -EINVAL && status != -EPERM) {
				/*
				 * We got a status that's not return-able.
				 * Assert that we got something we were
				 * expecting (-EFAULT isn't acceptable,
				 * strm_mgr_obj->chnl_mgr better be valid or we
				 * assert here), and then return -EPERM.
				 */
				status = -EPERM;
			}
		}
	}
	if (!status) {
		status = drv_proc_insert_strm_res_element(strm_obj,
							&stream_res, pr_ctxt);
		if (status)
			delete_strm(strm_obj);
		else
			*strmres = (struct strm_res_object *)stream_res;
	} else {
		(void)delete_strm(strm_obj);
	}

	dev_dbg(bridge, "%s: hnode: %p dir: 0x%x index: 0x%x pattr: %p "
		"strmres: %p status: 0x%x\n", __func__,
		hnode, dir, index, pattr, strmres, status);
	return status;
}

/*
 *  ======== strm_reclaim ========
 *  Purpose:
 *      Relcaims a buffer from a stream.
 */
int strm_reclaim(struct strm_object *stream_obj, u8 ** buf_ptr,
			u32 *nbytes, u32 *buff_size, u32 *pdw_arg)
{
	struct bridge_drv_interface *intf_fxns;
	struct chnl_ioc chnl_ioc_obj;
	int status = 0;
	void *tmp_buf = NULL;

	if (!stream_obj) {
		status = -EFAULT;
		goto func_end;
	}
	intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;

	status =
	    (*intf_fxns->chnl_get_ioc) (stream_obj->chnl_obj,
					    stream_obj->timeout,
					    &chnl_ioc_obj);
	if (!status) {
		*nbytes = chnl_ioc_obj.byte_size;
		if (buff_size)
			*buff_size = chnl_ioc_obj.buf_size;

		*pdw_arg = chnl_ioc_obj.arg;
		if (!CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) {
			if (CHNL_IS_TIMED_OUT(chnl_ioc_obj)) {
				status = -ETIME;
			} else {
				/* Allow reclaims after idle to succeed */
				if (!CHNL_IS_IO_CANCELLED(chnl_ioc_obj))
					status = -EPERM;

			}
		}
		/* Translate zerocopy buffer if channel not canceled. */
		if (!status
		    && (!CHNL_IS_IO_CANCELLED(chnl_ioc_obj))
		    && (stream_obj->strm_mode == STRMMODE_ZEROCOPY)) {
			/*
			 *  This is a zero-copy channel so chnl_ioc_obj.buf
			 *  contains the DSP address of SM. We need to
			 *  translate it to a virtual address for the user
			 *  thread to access.
			 *  Note: Could add CMM_DSPPA2VA to CMM in the future.
			 */
			tmp_buf = cmm_xlator_translate(stream_obj->xlator,
						       chnl_ioc_obj.buf,
						       CMM_DSPPA2PA);
			if (tmp_buf != NULL) {
				/* now convert this GPP Pa to Va */
				tmp_buf = cmm_xlator_translate(stream_obj->
							       xlator,
							       tmp_buf,
							       CMM_PA2VA);
			}
			if (tmp_buf == NULL)
				status = -ESRCH;

			chnl_ioc_obj.buf = tmp_buf;
		}
		*buf_ptr = chnl_ioc_obj.buf;
	}
func_end:
	dev_dbg(bridge, "%s: stream_obj: %p buf_ptr: %p nbytes: %p "
		"pdw_arg: %p status 0x%x\n", __func__, stream_obj,
		buf_ptr, nbytes, pdw_arg, status);
	return status;
}

/*
 *  ======== strm_register_notify ========
 *  Purpose:
 *      Register to be notified on specific events for this stream.
 */
int strm_register_notify(struct strm_object *stream_obj, u32 event_mask,
				u32 notify_type, struct dsp_notification
				* hnotification)
{
	struct bridge_drv_interface *intf_fxns;
	int status = 0;

	if (!stream_obj) {
		status = -EFAULT;
	} else if ((event_mask & ~((DSP_STREAMIOCOMPLETION) |
				   DSP_STREAMDONE)) != 0) {
		status = -EINVAL;
	} else {
		if (notify_type != DSP_SIGNALEVENT)
			status = -ENOSYS;

	}
	if (!status) {
		intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;

		status =
		    (*intf_fxns->chnl_register_notify) (stream_obj->
							    chnl_obj,
							    event_mask,
							    notify_type,
							    hnotification);
	}

	return status;
}

/*
 *  ======== strm_select ========
 *  Purpose:
 *      Selects a ready stream.
 */
int strm_select(struct strm_object **strm_tab, u32 strms,
		       u32 *pmask, u32 utimeout)
{
	u32 index;
	struct chnl_info chnl_info_obj;
	struct bridge_drv_interface *intf_fxns;
	struct sync_object **sync_events = NULL;
	u32 i;
	int status = 0;

	*pmask = 0;
	for (i = 0; i < strms; i++) {
		if (!strm_tab[i]) {
			status = -EFAULT;
			break;
		}
	}
	if (status)
		goto func_end;

	/* Determine which channels have IO ready */
	for (i = 0; i < strms; i++) {
		intf_fxns = strm_tab[i]->strm_mgr_obj->intf_fxns;
		status = (*intf_fxns->chnl_get_info) (strm_tab[i]->chnl_obj,
							  &chnl_info_obj);
		if (status) {
			break;
		} else {
			if (chnl_info_obj.cio_cs > 0)
				*pmask |= (1 << i);

		}
	}
	if (!status && utimeout > 0 && *pmask == 0) {
		/* Non-zero timeout */
		sync_events = kmalloc(strms * sizeof(struct sync_object *),
								GFP_KERNEL);

		if (sync_events == NULL) {
			status = -ENOMEM;
		} else {
			for (i = 0; i < strms; i++) {
				intf_fxns =
				    strm_tab[i]->strm_mgr_obj->intf_fxns;
				status = (*intf_fxns->chnl_get_info)
				    (strm_tab[i]->chnl_obj, &chnl_info_obj);
				if (status)
					break;
				else
					sync_events[i] =
					    chnl_info_obj.sync_event;

			}
		}
		if (!status) {
			status =
			    sync_wait_on_multiple_events(sync_events, strms,
							 utimeout, &index);
			if (!status) {
				/* Since we waited on the event, we have to
				 * reset it */
				sync_set_event(sync_events[index]);
				*pmask = 1 << index;
			}
		}
	}
func_end:
	kfree(sync_events);

	return status;
}

/*
 *  ======== delete_strm ========
 *  Purpose:
 *      Frees the resources allocated for a stream.
 */
static int delete_strm(struct strm_object *stream_obj)
{
	struct bridge_drv_interface *intf_fxns;
	int status = 0;

	if (stream_obj) {
		if (stream_obj->chnl_obj) {
			intf_fxns = stream_obj->strm_mgr_obj->intf_fxns;
			/* Channel close can fail only if the channel handle
			 * is invalid. */
			status = (*intf_fxns->chnl_close)
					(stream_obj->chnl_obj);
		}
		/* Free all SM address translator resources */
		kfree(stream_obj->xlator);
		kfree(stream_obj);
	} else {
		status = -EFAULT;
	}
	return status;
}
