Example #1
0
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) {

			/*
                                     
    */
			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;
}
int api_init_complete2(void)
{
    int status = 0;
    struct cfg_devnode *dev_node;
    struct dev_object *hdev_obj;
    struct drv_data *drv_datap;
    u8 dev_type;

    for (hdev_obj = dev_get_first(); hdev_obj != NULL;
            hdev_obj = dev_get_next(hdev_obj)) {
        if (dev_get_dev_node(hdev_obj, &dev_node))
            continue;

        if (dev_get_dev_type(hdev_obj, &dev_type))
            continue;

        if ((dev_type == DSP_UNIT) || (dev_type == IVA_UNIT)) {
            drv_datap = dev_get_drvdata(bridge);

            if (drv_datap && drv_datap->base_img)
                proc_auto_start(dev_node, hdev_obj);
        }
    }

    return status;
}
/*
 *  ======== api_init_complete2 ========
 *  Purpose:
 *      Perform any required bridge initialization which cannot
 *      be performed in api_init() or dev_start_device() due
 *      to the fact that some services are not yet
 *      completely initialized.
 *  Parameters:
 *  Returns:
 *      0:	Allow this device to load
 *      -EPERM:      Failure.
 *  Requires:
 *      Bridge API initialized.
 *  Ensures:
 */
int api_init_complete2(void)
{
	int status = 0;
	struct cfg_devnode *dev_node;
	struct dev_object *hdev_obj;
	struct drv_data *drv_datap;
	u8 dev_type;

	/*  Walk the list of DevObjects, get each devnode, and attempting to
	 *  autostart the board. Note that this requires COF loading, which
	 *  requires KFILE. */
	for (hdev_obj = dev_get_first(); hdev_obj != NULL;
	     hdev_obj = dev_get_next(hdev_obj)) {
		if (dev_get_dev_node(hdev_obj, &dev_node))
			continue;

		if (dev_get_dev_type(hdev_obj, &dev_type))
			continue;

		if ((dev_type == DSP_UNIT) || (dev_type == IVA_UNIT)) {
			drv_datap = dev_get_drvdata(bridge);

			if (drv_datap && drv_datap->base_img)
				proc_auto_start(dev_node, hdev_obj);
		}
	}

	return status;
}
Example #4
0
/*
 *  ======== mgr_enum_processor_info ========
 *      Enumerate and get configuration information about available
 *      DSP processors.
 */
int mgr_enum_processor_info(u32 processor_id,
				   struct dsp_processorinfo *
				   processor_info, u32 processor_info_size,
				   u8 *pu_num_procs)
{
	int status = 0;
	int status1 = 0;
	int status2 = 0;
	struct dsp_uuid temp_uuid;
	u32 temp_index = 0;
	u32 proc_index = 0;
	struct dcd_genericobj gen_obj;
	struct mgr_object *pmgr_obj = NULL;
	struct mgr_processorextinfo *ext_info;
	struct dev_object *hdev_obj;
	struct drv_object *hdrv_obj;
	u8 dev_type;
	struct cfg_devnode *dev_node;
	struct drv_data *drv_datap = dev_get_drvdata(bridge);
	bool proc_detect = false;

	*pu_num_procs = 0;

	/* Retrieve the Object handle from the driver data */
	if (!drv_datap || !drv_datap->drv_object) {
		status = -ENODATA;
		pr_err("%s: Failed to retrieve the object handle\n", __func__);
	} else {
		hdrv_obj = drv_datap->drv_object;
	}

	if (!status) {
		status = drv_get_dev_object(processor_id, hdrv_obj, &hdev_obj);
		if (!status) {
			status = dev_get_dev_type(hdev_obj, (u8 *) &dev_type);
			status = dev_get_dev_node(hdev_obj, &dev_node);
			if (dev_type != DSP_UNIT)
				status = -EPERM;

			if (!status)
				processor_info->processor_type = DSPTYPE64;
		}
	}
	if (status)
		goto func_end;

	/* Get The Manager Object from the driver data */
	if (drv_datap && drv_datap->mgr_object) {
		pmgr_obj = drv_datap->mgr_object;
	} else {
		dev_dbg(bridge, "%s: Failed to get MGR Object\n", __func__);
		goto func_end;
	}
	/* Forever loop till we hit no more items in the
	 * Enumeration. We will exit the loop other than 0; */
	while (status1 == 0) {
		status1 = dcd_enumerate_object(temp_index++,
					       DSP_DCDPROCESSORTYPE,
					       &temp_uuid);
		if (status1 != 0)
			break;

		proc_index++;
		/* Get the Object properties to find the Device/Processor
		 * Type */
		if (proc_detect != false)
			continue;

		status2 = dcd_get_object_def(pmgr_obj->dcd_mgr,
					     (struct dsp_uuid *)&temp_uuid,
					     DSP_DCDPROCESSORTYPE, &gen_obj);
		if (!status2) {
			/* Get the Obj def */
			if (processor_info_size <
			    sizeof(struct mgr_processorextinfo)) {
				*processor_info = gen_obj.obj_data.proc_info;
			} else {
				/* extended info */
				ext_info = (struct mgr_processorextinfo *)
				    processor_info;
				*ext_info = gen_obj.obj_data.ext_proc_obj;
			}
			dev_dbg(bridge, "%s: Got proctype  from DCD %x\n",
				__func__, processor_info->processor_type);
			/* See if we got the needed processor */
			if (dev_type == DSP_UNIT) {
				if (processor_info->processor_type ==
				    DSPPROCTYPE_C64)
					proc_detect = true;
			} else if (dev_type == IVA_UNIT) {
				if (processor_info->processor_type ==
				    IVAPROCTYPE_ARM7)
					proc_detect = true;
			}
			/* User applications only check for chip type, so
			 * this is a clumsy overwrite */
			processor_info->processor_type = DSPTYPE64;
		} else {
			dev_dbg(bridge, "%s: Failed to get DCD processor info "
				"%x\n", __func__, status2);
			status = -EPERM;
		}
	}
	*pu_num_procs = proc_index;
	if (proc_detect == false) {
		dev_dbg(bridge, "%s: Failed to get proc info from DCD, so use "
			"CFG registry\n", __func__);
		processor_info->processor_type = DSPTYPE64;
	}
func_end:
	return status;
}
Example #5
0
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;

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

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

	/*                                                                  
            */
	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;
	/*                                              */
	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) {
		/*                                       */
		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;
}
Example #6
0
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;	/*                                    */
	chars_in_rms_word = sizeof(rms_word) / disp_obj->char_size;
	/*                                             */
	dw_length =
	    (node_msg_args.arg_length + chars_in_rms_word -
	     1) / chars_in_rms_word;
	/*                                              */
	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);
	}
	/*
                                   
                                                
   
                 
                                    
                                          
                       
                  
   
                  
                               
                                            
                                                          
                                   
                          
   
                                        
                 
                   
                          
                      
             
                                
                                                                     
                                 
                                                               
                
                                                                  
                                                                    
   
                                       
   
  */
	if (!status) {
		total = 0;	/*                                        */
		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) {
			/*                      */
			rms_cmd->arg2 = 1;	/*                */
		} else {
			/*                     */
			rms_cmd->arg2 = 0;	/*                */
		}
		rms_cmd->data = node_get_type(hnode);
		/*
                                                           
                                                             
                         
   */
		args_offset = 3;
		total += sizeof(struct rms_command) / sizeof(rms_word);
		/*              */
		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_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;
		/*                     */
		if (total < max) {
			total = task_args_offset;
			more_task_args = (struct rms_more_task_args *)(pdw_buf +
								       total);
			/*
                                                          
                                                    
                                                     
    */
			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);
			/*                                           
                                                     
                       */
			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;
			/*                           */
			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 {
			/*                */
			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;
}
int bridge_io_create(struct io_mgr **io_man,
			    struct dev_object *hdev_obj,
			    const struct io_attrs *mgr_attrts)
{
	struct io_mgr *pio_mgr = NULL;
	struct bridge_dev_context *hbridge_context = NULL;
	struct cfg_devnode *dev_node_obj;
	struct chnl_mgr *hchnl_mgr;
	u8 dev_type;

	
	if (!io_man || !mgr_attrts || mgr_attrts->word_size == 0)
		return -EFAULT;

	*io_man = NULL;

	dev_get_chnl_mgr(hdev_obj, &hchnl_mgr);
	if (!hchnl_mgr || hchnl_mgr->iomgr)
		return -EFAULT;

	dev_get_bridge_context(hdev_obj, &hbridge_context);
	if (!hbridge_context)
		return -EFAULT;

	dev_get_dev_type(hdev_obj, &dev_type);

	
	pio_mgr = kzalloc(sizeof(struct io_mgr), GFP_KERNEL);
	if (!pio_mgr)
		return -ENOMEM;

	
	pio_mgr->chnl_mgr = hchnl_mgr;
	pio_mgr->word_size = mgr_attrts->word_size;

	if (dev_type == DSP_UNIT) {
		
		tasklet_init(&pio_mgr->dpc_tasklet, io_dpc, (u32) pio_mgr);

		
		pio_mgr->dpc_req = 0;
		pio_mgr->dpc_sched = 0;

		spin_lock_init(&pio_mgr->dpc_lock);

		if (dev_get_dev_node(hdev_obj, &dev_node_obj)) {
			bridge_io_destroy(pio_mgr);
			return -EIO;
		}
	}

	pio_mgr->bridge_context = hbridge_context;
	pio_mgr->shared_irq = mgr_attrts->irq_shared;
	if (dsp_wdt_init()) {
		bridge_io_destroy(pio_mgr);
		return -EPERM;
	}

	
	hchnl_mgr->iomgr = pio_mgr;
	*io_man = pio_mgr;

	return 0;
}