/**Load the context for a channel to SDMA
 *
 * <b>Algorithm:</b>\n
 *   - Send context and poll for answer.
 *
 * @param *cd_p  channel descriptor for channel 0
 * @param *buf pointer to context data
 * @param channel channel to place the context for
 *
 * @return none
 */
void
iapi_lowSetContext(channelDescriptor *cd_p, void *buf, unsigned char channel)
{

	bufferDescriptor *local_bd_p;
#ifdef SDMA_SKYE

	unsigned char command = 0;

	local_bd_p =
	    (bufferDescriptor *) iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);

	command = channel << 3;
	command = command | C0_SETCTX;
	iapi_SetBufferDescriptor(&local_bd_p[0],
				 command,
				 (unsigned char)(BD_DONE | BD_INTR | BD_WRAP),
				 (unsigned short)(sizeof(contextData) / 4),
				 buf, NULL);
#else

	local_bd_p =
	    (bufferDescriptor *) iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);

	iapi_SetBufferDescriptor(&local_bd_p[0],
				 C0_SETDM,
				 (unsigned char)(BD_DONE | BD_INTR | BD_WRAP |
						 BD_EXTD),
				 (unsigned short)(sizeof(contextData) / 4), buf,
				 (void *)(2048 +
					  (sizeof(contextData) / 4) * channel));
#endif
	/* Send */
	iapi_lowStartChannel(cd_p->channelNumber);
	iapi_lowSynchChannel(cd_p->channelNumber);

}
/**Load a SDMA script to SDMA
 *
 * <b>Algorithm:</b>\n
 *    - Setup BD with appropiate parameters (C0_SETPM)
 *    - Start channel
 *    - Poll for answer
 *
 * <b>Notes</b>\b
 *    - Parameter "size" is in bytes, it represents the size of "buf", e.g.
 *  the size in bytes of the script to be uploaded.
 *    - Parameter "address" denotes the RAM address for the script in SDMA
 *
 * @param *cd_p  channel descriptor for channel 0
 * @param *buf pointer to the script
 * @param size size of the script, in bytes
 * @param address address in SDMA RAM to place the script
 *
 * @return none
 */
void
iapi_lowSetScript(channelDescriptor *cd_p, void *buf, unsigned short size,
		  unsigned long address)
{
	bufferDescriptor *bd_p;

	bd_p = (bufferDescriptor *) iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);

	/*Setup buffer descriptor with channel 0 command */
	iapi_SetBufferDescriptor(&bd_p[0], C0_SETPM, (unsigned char)(BD_DONE | BD_INTR | BD_WRAP | BD_EXTD), (unsigned short)size / 2,	/*count in  shorts */
				 buf, (void *)(address));
	/* Receive, polling method */
	iapi_lowStartChannel(cd_p->channelNumber);
	iapi_lowSynchChannel(cd_p->channelNumber);
}
Пример #3
0
/**Load the context data of a channel from SDMA
 *
 * <b>Algorithm:</b>\n
 *    - Setup BD with appropiate parameters
 *    - Start channel
 *    - Poll for answer
 *
 * @param *cd_p  channel descriptor for channel 0
 * @param *buf pointer to receive context data 
 * @param channel channel for which the context data is requested
 *
 * @return none
 */
void
iapi_lowGetContext(channelDescriptor * cd_p, void * buf, unsigned char channel)
{
  bufferDescriptor * bd_p;

  bd_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
  
  /*Setup buffer descriptor with channel 0 command*/
  iapi_SetBufferDescriptor(&bd_p[0],
      C0_GETDM, 
      (unsigned char)(BD_DONE | BD_INTR | BD_WRAP | BD_EXTD),
      (unsigned short)sizeof(contextData)/4,
      buf,
      (void *)(CHANNEL_CONTEXT_BASE_ADDRESS + (sizeof(contextData)*channel/4)));
  /* Receive, polling method*/
  iapi_lowStartChannel(cd_p->channelNumber);
  iapi_lowSynchChannel(cd_p->channelNumber);
}
Пример #4
0
/**Load the context for a channel to SDMA
 *
 * <b>Algorithm:</b>\n
 *   - Send context and poll for answer.
 * 
 * @param *cd_p  channel descriptor for channel 0
 * @param *buf pointer to context data
 * @param channel channel to place the context for
 *
 * @return none
 */
void
iapi_lowSetContext(channelDescriptor * cd_p, void * buf, unsigned char channel)
{ 
	
  bufferDescriptor * local_bd_p;
  
  local_bd_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
  
  iapi_SetBufferDescriptor( &local_bd_p[0],
                            C0_SETDM,
							(unsigned char)(BD_DONE | BD_INTR | BD_WRAP|BD_EXTD),
							(unsigned short)(sizeof(contextData)/4),
							 buf,
							 (void *)(2048+(sizeof(contextData)/4)*channel));
							 
  /* Send */
  iapi_lowStartChannel( cd_p->channelNumber );
  iapi_lowSynchChannel( cd_p->channelNumber );

}
/**Changes channel description information after performing sanity checks.
 *
 * <b>Algorithm:</b>\n
 *    - Check channel properties.
 *    - Then modifies the properties of the channel description.
 *
 * @param *cd_p channel descriptor of the channel to change
 * @param whatToChange control code indicating the desired change
 * @param newval new value
 *
 * @return
 *     - IAPI_SUCCESS
 *     - IAPI_FAILURE if change failed
 *
 */
int
iapi_ChangeChannelDesc(channelDescriptor *cd_p, unsigned char whatToChange,
		       unsigned long newval)
{
	bufferDescriptor *tmpBDptr;
	unsigned char index = 0;
	int result = IAPI_SUCCESS;

	/* verify parameter validity */
	if (cd_p == NULL) {
		result = IAPI_ERR_CD_UNINITIALIZED;
		iapi_errno = result;
		return -result;
	}

	/* verify channel descriptor initialization */
	if (cd_p->ccb_ptr == NULL) {
		result = IAPI_ERR_CCB_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE |
		    cd_p->channelNumber;
		iapi_errno = result;
		return -result;
	}

	/* verify channel is not in use */
	tmpBDptr =
	    (bufferDescriptor *) iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
	for (index = cd_p->bufferDescNumber; index > 0; index--) {
		if (tmpBDptr->mode.status & BD_DONE) {
			result = IAPI_ERR_CH_IN_USE | IAPI_ERR_CH_AVAILABLE |
			    cd_p->channelNumber;
			iapi_errno = result;
			return -result;
		}
		tmpBDptr++;
	}

	/* Select the change accorded to the selector given in parameter */
	switch (whatToChange) {

		/*
		 * Channel Number
		 */
	case IAPI_CHANNELNUMBER:
		/* Channel number can not be changed (description remains attached) */
		result = IAPI_ERR_CD_CHANGE_CH_NUMBER | IAPI_ERR_CH_AVAILABLE |
		    cd_p->channelNumber;
		iapi_errno = result;
		return -result;

		/*
		 * Buffer Descriptor Number
		 */
	case IAPI_BUFFERDESCNUMBER:
		if (newval < MAX_BD_NUM) {
			if (newval != cd_p->bufferDescNumber) {
				/* Free memory used for previous old data */
				if (cd_p->ccb_ptr->baseBDptr != NULL) {
					tmpBDptr = (bufferDescriptor *)
					    iapi_Phys2Virt(cd_p->
							   ccb_ptr->baseBDptr);
					for (index = 0;
					     index < cd_p->bufferDescNumber;
					     index++) {
						if (tmpBDptr->bufferAddr !=
						    NULL) {
							if (cd_p->trust ==
							    FALSE) {
								FREE(iapi_Phys2Virt(tmpBDptr->bufferAddr));
							}
						}
						tmpBDptr++;
					}
					FREE((bufferDescriptor *)
					     iapi_Phys2Virt((cd_p->
							     ccb_ptr)->baseBDptr));
				}
				(cd_p->ccb_ptr)->baseBDptr = NULL;
				(cd_p->ccb_ptr)->currentBDptr = NULL;
				/* Allocate and initialize structures */
				cd_p->bufferDescNumber = (unsigned char)newval;
				cd_p->ccb_ptr->status.openedInit = FALSE;
				if (IAPI_SUCCESS !=
				    iapi_InitializeMemory(cd_p->ccb_ptr)) {
					result =
					    IAPI_ERR_BD_ALLOCATION |
					    cd_p->channelNumber;
					iapi_errno = result;
					return -result;
				}
				cd_p->ccb_ptr->status.openedInit = TRUE;
			}
			break;
		} else {
			result =
			    IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
			    cd_p->channelNumber;
			iapi_errno = result;
			return -result;
		}

		/*
		 * Buffer size
		 */
	case IAPI_BUFFERSIZE:
		if (newval < MAX_BD_SIZE) {
			if (newval != cd_p->bufferSize) {
				/* Free memory used for previous old data */
				if (cd_p->ccb_ptr->baseBDptr != NULL) {
					tmpBDptr = (bufferDescriptor *)
					    iapi_Phys2Virt(cd_p->
							   ccb_ptr->baseBDptr);
					for (index = 0;
					     index < cd_p->bufferDescNumber;
					     index++) {
						if (cd_p->trust == FALSE) {
							FREE(iapi_Phys2Virt
							     (tmpBDptr->bufferAddr));
						}
						tmpBDptr++;
					}
					FREE((bufferDescriptor *)
					     iapi_Phys2Virt((cd_p->
							     ccb_ptr)->baseBDptr));
				}
				(cd_p->ccb_ptr)->baseBDptr = NULL;
				(cd_p->ccb_ptr)->currentBDptr = NULL;
				/* Allocate and initialize structures */
				cd_p->bufferSize = (unsigned short)newval;
				cd_p->ccb_ptr->status.openedInit = FALSE;
				if (IAPI_SUCCESS !=
				    iapi_InitializeMemory(cd_p->ccb_ptr)) {
					result =
					    IAPI_ERR_BD_ALLOCATION |
					    cd_p->channelNumber;
					iapi_errno = result;
					return -result;
				}
				cd_p->ccb_ptr->status.openedInit = TRUE;
			}
			break;
		} else {
			result =
			    IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
			    cd_p->channelNumber;
			iapi_errno = result;
			return -result;
		}

		/*
		 * Blocking / non blocking feature
		 */
	case IAPI_BLOCKING:
		if (newval < MAX_BLOCKING) {
			cd_p->blocking = newval;
			break;
		} else {
			result =
			    IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
			    cd_p->channelNumber;
			iapi_errno = result;
			return -result;
		}

		/*
		 * Synchronization method
		 */
	case IAPI_CALLBACKSYNCH:
		if (newval < MAX_SYNCH) {
			cd_p->callbackSynch = newval;
			iapi_ChangeCallbackISR(cd_p, cd_p->callbackISR_ptr);
			break;
		} else {
			result =
			    IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
			    cd_p->channelNumber;
			iapi_errno = result;
			return -result;
		}

		/*
		 *  Ownership of the channel
		 */
	case IAPI_OWNERSHIP:
#ifdef DSP
		result = IAPI_ERR_NOT_ALLOWED | cd_p->channelNumber;
		iapi_errno = result;
		return -result;
#endif				/* DSP */
#ifdef MCU
		if (newval < MAX_OWNERSHIP) {
			cd_p->ownership = newval;
			iapi_ChannelConfig(cd_p->channelNumber,
					   (newval >> CH_OWNSHP_OFFSET_EVT) & 1,
					   (newval >> CH_OWNSHP_OFFSET_MCU) & 1,
					   (newval >> CH_OWNSHP_OFFSET_DSP) &
					   1);
			break;
		} else {