/*
 * 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;
}
