/*
 * disp.c
 *
 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
 *
 * Node Dispatcher interface. Communicates with Resource Manager Server
 * (RMS) on DSP. Access to RMS is synchronized in NODE.
 *
 * 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>

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

/*  ----------------------------------- Platform Manager */
#include <dspbridge/dev.h>
#include <dspbridge/chnldefs.h>

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

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

/* Size of a reply from RMS */
#define REPLYSIZE (3 * sizeof(rms_word))

/* Reserved channel offsets for communication with RMS */
#define CHNLTORMSOFFSET       0
#define CHNLFROMRMSOFFSET     1

#define CHNLIOREQS      1

/*
 *  ======== disp_object ========
 */
struct disp_object {
	struct dev_object *dev_obj;	/* Device for this processor */
	/* Function interface to Bridge driver */
	struct bridge_drv_interface *intf_fxns;
	struct chnl_mgr *chnl_mgr;	/* Channel manager */
	struct chnl_object *chnl_to_dsp;	/* Chnl for commands to RMS */
	struct chnl_object *chnl_from_dsp;	/* Chnl for replies from RMS */
	u8 *buf;		/* Buffer for commands, replies */
	u32 bufsize;		/* buf size in bytes */
	u32 bufsize_rms;	/* buf size in RMS words */
	u32 char_size;		/* Size of DSP character */
	u32 word_size;		/* Size of DSP word */
	u32 data_mau_size;	/* Size of DSP Data MAU */
};

static void delete_disp(struct disp_object *disp_obj);
static int fill_stream_def(rms_word *pdw_buf, u32 *ptotal, u32 offset,
				  struct node_strmdef strm_def, u32 max,
				  u32 chars_in_rms_word);
static int send_message(struct disp_object *disp_obj, u32 timeout,
			       u32 ul_bytes, u32 *pdw_arg);

/*
 *  ======== disp_create ========
 *  Create a NODE Dispatcher object.
 */
int disp_create(struct disp_object **dispatch_obj,
		       struct dev_object *hdev_obj,
		       const struct disp_attr *disp_attrs)
{
	struct disp_object *disp_obj;
	struct bridge_drv_interface *intf_fxns;
	u32 ul_chnl_id;
	struct chnl_attr chnl_attr_obj;
	int status = 0;
	u8 dev_type;

	*dispatch_obj = NULL;

	/* Allocate Node Dispatcher object */
	disp_obj = kzalloc(sizeof(struct disp_object), GFP_KERNEL);
	if (disp_obj == NULL)
		status = -ENOMEM;
	else
		disp_obj->dev_obj = hdev_obj;

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

	/* check device type and decide if streams or messag'ing is used for
	 * RMS/EDS */
	if (status)
		goto func_cont;

	status = dev_get_dev_type(hdev_obj, &dev_type);

	if (status)
		goto func_cont;

	if (dev_type != DSP_UNIT) {
		status = -EPERM;
		goto func_cont;
	}

	disp_obj->char_size = DSPWORDSIZE;
	disp_obj->word_size = DSPWORDSIZE;
	disp_obj->data_mau_size = DSPWORDSIZE;
	/* Open channels for communicating with the RMS */
	chnl_attr_obj.uio_reqs = CHNLIOREQS;
	chnl_attr_obj.event_obj = NULL;
	ul_chnl_id = disp_attrs->chnl_offset + CHNLTORMSOFFSET;
	status = (*intf_fxns->chnl_open) (&(disp_obj->chnl_to_dsp),
					      disp_obj->chnl_mgr,
					      CHNL_MODETODSP, ul_chnl_id,
					      &chnl_attr_obj);

	if (!status) {
		ul_chnl_id = disp_attrs->chnl_offset + CHNLFROMRMSOFFSET;
		status =
		    (*intf_fxns->chnl_open) (&(disp_obj->chnl_from_dsp),
						 disp_obj->chnl_mgr,
						 CHNL_MODEFROMDSP, ul_chnl_id,
						 &chnl_attr_obj);
	}
	if (!status) {
		/* Allocate buffer for commands, replies */
		disp_obj->bufsize = disp_attrs->chnl_buf_size;
		disp_obj->bufsize_rms = RMS_COMMANDBUFSIZE;
		disp_obj->buf = kzalloc(disp_obj->bufsize, GFP_KERNEL);
		if (disp_obj->buf == NULL)
			status = -ENOMEM;
	}
func_cont:
	if (!status)
		*dispatch_obj = disp_obj;
	else
		delete_disp(disp_obj);

	return status;
}

/*
 *  ======== disp_delete ========
 *  Delete the NODE Dispatcher.
 */
void disp_delete(struct disp_object *disp_obj)
{
	delete_disp(disp_obj);
}

/*
 *  ======== disp_node_change_priority ========
 *  Change the priority of a node currently running on the target.
 */
int disp_node_change_priority(struct disp_object *disp_obj,
				     struct node_object *hnode,
				     u32 rms_fxn, nodeenv node_env, s32 prio)
{
	u32 dw_arg;
	struct rms_command *rms_cmd;
	int status = 0;

	/* Send message to RMS to change priority */
	rms_cmd = (struct rms_command *)(disp_obj->buf);
	rms_cmd->fxn = (rms_word) (rms_fxn);
	rms_cmd->arg1 = (rms_word) node_env;
	rms_cmd->arg2 = prio;
	status = send_message(disp_obj, node_get_timeout(hnode),
			      sizeof(struct rms_command), &dw_arg);

	return status;
}

/*
 *  ======== disp_node_create ========
 *  Create a node on the DSP by remotely calling the node's create function.
 */
int disp_node_create(struct disp_object *disp_obj,
			    struct node_object *hnode, u32 rms_fxn,
			    u32 ul_create_fxn,
			    const struct node_createargs *pargs,
			    nodeenv *node_env)
{
	struct node_msgargs node_msg_args;
	struct node_taskargs task_arg_obj;
	struct rms_command *rms_cmd;
	struct rms_msg_args *pmsg_args;
	struct rms_more_task_args *more_task_args;
	enum node_type node_type;
	u32 dw_length;
	rms_word *pdw_buf = NULL;
	u32 ul_bytes;
	u32 i;
	u32 total;
	u32 chars_in_rms_word;
	s32 task_args_offset;
	s32 sio_in_def_offset;
	s32 sio_out_def_offset;
	s32 sio_defs_offset;
	s32 args_offset = -1;
	s32 offset;
	struct node_strmdef strm_def;
	u32 max;
	int status = 0;
	struct dsp_nodeinfo node_info;
	u8 dev_type;

	status = dev_get_dev_type(disp_obj->dev_obj, &dev_type);

	if (status)
		goto func_end;

	if (dev_type != DSP_UNIT) {
		dev_dbg(bridge, "%s: unknown device type = 0x%x\n",
			__func__, dev_type);
		goto func_end;
	}
	node_type = node_get_type(hnode);
	node_msg_args = pargs->asa.node_msg_args;
	max = disp_obj->bufsize_rms;	/*Max # of RMS words that can be sent */
	chars_in_rms_word = sizeof(rms_word) / disp_obj->char_size;
	/* Number of RMS words needed to hold arg data */
	dw_length =
	    (node_msg_args.arg_length + chars_in_rms_word -
	     1) / chars_in_rms_word;
	/* Make sure msg args and command fit in buffer */
	total = sizeof(struct rms_command) / sizeof(rms_word) +
	    sizeof(struct rms_msg_args)
	    / sizeof(rms_word) - 1 + dw_length;
	if (total >= max) {
		status = -EPERM;
		dev_dbg(bridge, "%s: Message args too large for buffer! size "
			"= %d, max = %d\n", __func__, total, max);
	}
	/*
	 *  Fill in buffer to send to RMS.
	 *  The buffer will have the following  format:
	 *
	 *  RMS command:
	 *      Address of RMS_CreateNode()
	 *      Address of node's create function
	 *      dummy argument
	 *      node type
	 *
	 *  Message Args:
	 *      max number of messages
	 *      segid for message buffer allocation
	 *      notification type to use when message is received
	 *      length of message arg data
	 *      message args data
	 *
	 *  Task Args (if task or socket node):
	 *      priority
	 *      stack size
	 *      system stack size
	 *      stack segment
	 *      misc
	 *      number of input streams
	 *      pSTRMInDef[] - offsets of STRM definitions for input streams
	 *      number of output streams
	 *      pSTRMOutDef[] - offsets of STRM definitions for output
	 *      streams
	 *      STRMInDef[] - array of STRM definitions for input streams
	 *      STRMOutDef[] - array of STRM definitions for output streams
	 *
	 *  Socket Args (if DAIS socket node):
	 *
	 */
	if (!status) {
		total = 0;	/* Total number of words in buffer so far */
		pdw_buf = (rms_word *) disp_obj->buf;
		rms_cmd = (struct rms_command *)pdw_buf;
		rms_cmd->fxn = (rms_word) (rms_fxn);
		rms_cmd->arg1 = (rms_word) (ul_create_fxn);
		if (node_get_load_type(hnode) == NLDR_DYNAMICLOAD) {
			/* Flush ICACHE on Load */
			rms_cmd->arg2 = 1;	/* dummy argument */
		} else {
			/* Do not flush ICACHE */
			rms_cmd->arg2 = 0;	/* dummy argument */
		}
		rms_cmd->data = node_get_type(hnode);
		/*
		 *  args_offset is the offset of the data field in struct
		 *  rms_command structure. We need this to calculate stream
		 *  definition offsets.
		 */
		args_offset = 3;
		total += sizeof(struct rms_command) / sizeof(rms_word);
		/* Message args */
		pmsg_args = (struct rms_msg_args *)(pdw_buf + total);
		pmsg_args->max_msgs = node_msg_args.max_msgs;
		pmsg_args->segid = node_msg_args.seg_id;
		pmsg_args->notify_type = node_msg_args.notify_type;
		pmsg_args->arg_length = node_msg_args.arg_length;
		total += sizeof(struct rms_msg_args) / sizeof(rms_word) - 1;
		memcpy(pdw_buf + total, node_msg_args.pdata,
		       node_msg_args.arg_length);
		total += dw_length;
	}
	if (status)
		goto func_end;

	/* If node is a task node, copy task create arguments into  buffer */
	if (node_type == NODE_TASK || node_type == NODE_DAISSOCKET) {
		task_arg_obj = pargs->asa.task_arg_obj;
		task_args_offset = total;
		total += sizeof(struct rms_more_task_args) / sizeof(rms_word) +
		    1 + task_arg_obj.num_inputs + task_arg_obj.num_outputs;
		/* Copy task arguments */
		if (total < max) {
			total = task_args_offset;
			more_task_args = (struct rms_more_task_args *)(pdw_buf +
								       total);
			/*
			 * Get some important info about the node. Note that we
			 * don't just reach into the hnode struct because
			 * that would break the node object's abstraction.
			 */
			get_node_info(hnode, &node_info);
			more_task_args->priority = node_info.execution_priority;
			more_task_args->stack_size = task_arg_obj.stack_size;
			more_task_args->sysstack_size =
			    task_arg_obj.sys_stack_size;
			more_task_args->stack_seg = task_arg_obj.stack_seg;
			more_task_args->heap_addr = task_arg_obj.dsp_heap_addr;
			more_task_args->heap_size = task_arg_obj.heap_size;
			more_task_args->misc = task_arg_obj.dais_arg;
			more_task_args->num_input_streams =
			    task_arg_obj.num_inputs;
			total +=
			    sizeof(struct rms_more_task_args) /
			    sizeof(rms_word);
			dev_dbg(bridge, "%s: dsp_heap_addr %x, heap_size %x\n",
				__func__, task_arg_obj.dsp_heap_addr,
				task_arg_obj.heap_size);
			/* Keep track of pSIOInDef[] and pSIOOutDef[]
			 * positions in the buffer, since this needs to be
			 * filled in later. */
			sio_in_def_offset = total;
			total += task_arg_obj.num_inputs;
			pdw_buf[total++] = task_arg_obj.num_outputs;
			sio_out_def_offset = total;
			total += task_arg_obj.num_outputs;
			sio_defs_offset = total;
			/* Fill SIO defs and offsets */
			offset = sio_defs_offset;
			for (i = 0; i < task_arg_obj.num_inputs; i++) {
				if (status)
					break;

				pdw_buf[sio_in_def_offset + i] =
				    (offset - args_offset)
				    * (sizeof(rms_word) / DSPWORDSIZE);
				strm_def = task_arg_obj.strm_in_def[i];
				status =
				    fill_stream_def(pdw_buf, &total, offset,
						    strm_def, max,
						    chars_in_rms_word);
				offset = total;
			}
			for (i = 0; (i < task_arg_obj.num_outputs) &&
			     (!status); i++) {
				pdw_buf[sio_out_def_offset + i] =
				    (offset - args_offset)
				    * (sizeof(rms_word) / DSPWORDSIZE);
				strm_def = task_arg_obj.strm_out_def[i];
				status =
				    fill_stream_def(pdw_buf, &total, offset,
						    strm_def, max,
						    chars_in_rms_word);
				offset = total;
			}
		} else {
			/* Args won't fit */
			status = -EPERM;
		}
	}
	if (!status) {
		ul_bytes = total * sizeof(rms_word);
		status = send_message(disp_obj, node_get_timeout(hnode),
				      ul_bytes, node_env);
	}
func_end:
	return status;
}

/*
 *  ======== disp_node_delete ========
 *  purpose:
 *      Delete a node on the DSP by remotely calling the node's delete function.
 *
 */
int disp_node_delete(struct disp_object *disp_obj,
			    struct node_object *hnode, u32 rms_fxn,
			    u32 ul_delete_fxn, nodeenv node_env)
{
	u32 dw_arg;
	struct rms_command *rms_cmd;
	int status = 0;
	u8 dev_type;

	status = dev_get_dev_type(disp_obj->dev_obj, &dev_type);

	if (!status) {

		if (dev_type == DSP_UNIT) {

			/*
			 *  Fill in buffer to send to RMS
			 */
			rms_cmd = (struct rms_command *)disp_obj->buf;
			rms_cmd->fxn = (rms_word) (rms_fxn);
			rms_cmd->arg1 = (rms_word) node_env;
			rms_cmd->arg2 = (rms_word) (ul_delete_fxn);
			rms_cmd->data = node_get_type(hnode);

			status = send_message(disp_obj, node_get_timeout(hnode),
					      sizeof(struct rms_command),
					      &dw_arg);
		}
	}
	return status;
}

/*
 *  ======== disp_node_run ========
 *  purpose:
 *      Start execution of a node's execute phase, or resume execution of a node
 *      that has been suspended (via DISP_NodePause()) on the DSP.
 */
int disp_node_run(struct disp_object *disp_obj,
			 struct node_object *hnode, u32 rms_fxn,
			 u32 ul_execute_fxn, nodeenv node_env)
{
	u32 dw_arg;
	struct rms_command *rms_cmd;
	int status = 0;
	u8 dev_type;

	status = dev_get_dev_type(disp_obj->dev_obj, &dev_type);

	if (!status) {

		if (dev_type == DSP_UNIT) {

			/*
			 *  Fill in buffer to send to RMS.
			 */
			rms_cmd = (struct rms_command *)disp_obj->buf;
			rms_cmd->fxn = (rms_word) (rms_fxn);
			rms_cmd->arg1 = (rms_word) node_env;
			rms_cmd->arg2 = (rms_word) (ul_execute_fxn);
			rms_cmd->data = node_get_type(hnode);

			status = send_message(disp_obj, node_get_timeout(hnode),
					      sizeof(struct rms_command),
					      &dw_arg);
		}
	}

	return status;
}

/*
 *  ======== delete_disp ========
 *  purpose:
 *      Frees the resources allocated for the dispatcher.
 */
static void delete_disp(struct disp_object *disp_obj)
{
	int status = 0;
	struct bridge_drv_interface *intf_fxns;

	if (disp_obj) {
		intf_fxns = disp_obj->intf_fxns;

		/* Free Node Dispatcher resources */
		if (disp_obj->chnl_from_dsp) {
			/* Channel close can fail only if the channel handle
			 * is invalid. */
			status = (*intf_fxns->chnl_close)
			    (disp_obj->chnl_from_dsp);
			if (status) {
				dev_dbg(bridge, "%s: Failed to close channel "
					"from RMS: 0x%x\n", __func__, status);
			}
		}
		if (disp_obj->chnl_to_dsp) {
			status =
			    (*intf_fxns->chnl_close) (disp_obj->
							  chnl_to_dsp);
			if (status) {
				dev_dbg(bridge, "%s: Failed to close channel to"
					" RMS: 0x%x\n", __func__, status);
			}
		}
		kfree(disp_obj->buf);

		kfree(disp_obj);
	}
}

/*
 *  ======== fill_stream_def ========
 *  purpose:
 *      Fills stream definitions.
 */
static int fill_stream_def(rms_word *pdw_buf, u32 *ptotal, u32 offset,
				  struct node_strmdef strm_def, u32 max,
				  u32 chars_in_rms_word)
{
	struct rms_strm_def *strm_def_obj;
	u32 total = *ptotal;
	u32 name_len;
	u32 dw_length;
	int status = 0;

	if (total + sizeof(struct rms_strm_def) / sizeof(rms_word) >= max) {
		status = -EPERM;
	} else {
		strm_def_obj = (struct rms_strm_def *)(pdw_buf + total);
		strm_def_obj->bufsize = strm_def.buf_size;
		strm_def_obj->nbufs = strm_def.num_bufs;
		strm_def_obj->segid = strm_def.seg_id;
		strm_def_obj->align = strm_def.buf_alignment;
		strm_def_obj->timeout = strm_def.timeout;
	}

	if (!status) {
		/*
		 *  Since we haven't added the device name yet, subtract
		 *  1 from total.
		 */
		total += sizeof(struct rms_strm_def) / sizeof(rms_word) - 1;
		dw_length = strlen(strm_def.sz_device) + 1;

		/* Number of RMS_WORDS needed to hold device name */
		name_len =
		    (dw_length + chars_in_rms_word - 1) / chars_in_rms_word;

		if (total + name_len >= max) {
			status = -EPERM;
		} else {
			/*
			 *  Zero out last word, since the device name may not
			 *  extend to completely fill this word.
			 */
			pdw_buf[total + name_len - 1] = 0;
			/** TODO USE SERVICES * */
			memcpy(pdw_buf + total, strm_def.sz_device, dw_length);
			total += name_len;
			*ptotal = total;
		}
	}

	return status;
}

/*
 *  ======== send_message ======
 *  Send command message to RMS, get reply from RMS.
 */
static int send_message(struct disp_object *disp_obj, u32 timeout,
			       u32 ul_bytes, u32 *pdw_arg)
{
	struct bridge_drv_interface *intf_fxns;
	struct chnl_object *chnl_obj;
	u32 dw_arg = 0;
	u8 *pbuf;
	struct chnl_ioc chnl_ioc_obj;
	int status = 0;

	*pdw_arg = (u32) NULL;
	intf_fxns = disp_obj->intf_fxns;
	chnl_obj = disp_obj->chnl_to_dsp;
	pbuf = disp_obj->buf;

	/* Send the command */
	status = (*intf_fxns->chnl_add_io_req) (chnl_obj, pbuf, ul_bytes, 0,
						    0L, dw_arg);
	if (status)
		goto func_end;

	status =
	    (*intf_fxns->chnl_get_ioc) (chnl_obj, timeout, &chnl_ioc_obj);
	if (!status) {
		if (!CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) {
			if (CHNL_IS_TIMED_OUT(chnl_ioc_obj))
				status = -ETIME;
			else
				status = -EPERM;
		}
	}
	/* Get the reply */
	if (status)
		goto func_end;

	chnl_obj = disp_obj->chnl_from_dsp;
	ul_bytes = REPLYSIZE;
	status = (*intf_fxns->chnl_add_io_req) (chnl_obj, pbuf, ul_bytes,
						    0, 0L, dw_arg);
	if (status)
		goto func_end;

	status =
	    (*intf_fxns->chnl_get_ioc) (chnl_obj, timeout, &chnl_ioc_obj);
	if (!status) {
		if (CHNL_IS_TIMED_OUT(chnl_ioc_obj)) {
			status = -ETIME;
		} else if (chnl_ioc_obj.byte_size < ul_bytes) {
			/* Did not get all of the reply from the RMS */
			status = -EPERM;
		} else {
			if (CHNL_IS_IO_COMPLETE(chnl_ioc_obj)) {
				if (*((int *)chnl_ioc_obj.buf) < 0) {
					/* Translate DSP's to kernel error */
					status = -EREMOTEIO;
					dev_dbg(bridge, "%s: DSP-side failed:"
						" DSP errcode = 0x%x, Kernel "
						"errcode = %d\n", __func__,
						*(int *)pbuf, status);
				}
				*pdw_arg =
				    (((rms_word *) (chnl_ioc_obj.buf))[1]);
			} else {
				status = -EPERM;
			}
		}
	}
func_end:
	return status;
}
