/**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); }
/**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); }
/**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 ); }
/**Send a command on SDMA's channel zero. * Check if buffer descriptor is already used by the sdma, if yes return * an error as c0BDNum is wrong. * * <b>Notes</b>\n * There is an upgrade in the script on the Context load command and * the fact that the context structure has a fixed length of 20 or 24 * depending on SDMA versions. * * @return * - IAPI_SUCCESS * - -iapi_errno if failure */ int iapi_Channel0Command(channelDescriptor *cd_p, void *buf, unsigned short nbyte, unsigned char command) { channelControlBlock *ccb_p; bufferDescriptor *bd_p; int result = IAPI_SUCCESS; unsigned char chNum; /* * Check data structures are properly initialized */ /* Channel descriptor validity */ if (cd_p == NULL) { result = IAPI_ERR_CD_UNINITIALIZED; iapi_errno = result; return -result; } /* Channel control block validity */ if (cd_p->ccb_ptr == NULL) { result = IAPI_ERR_CCB_UNINITIALIZED; iapi_errno = result; return -result; } /* Control block & Descriptpor associated with the channel being worked on */ chNum = cd_p->channelNumber; ccb_p = cd_p->ccb_ptr; /* Is channel already in use ? */ if (ccb_p->baseBDptr != NULL) { result = IAPI_ERR_BD_ALLOCATED | IAPI_ERR_CH_AVAILABLE | chNum; iapi_errno = result; return -result; } /* Allocation of buffer descriptors */ bd_p = (bufferDescriptor *) MALLOC(sizeof(bufferDescriptor), SDMA_ERAM); if (bd_p != NULL) { ccb_p->baseBDptr = (bufferDescriptor *) iapi_Virt2Phys(bd_p); } else { result = IAPI_ERR_BD_ALLOCATION | IAPI_ERR_CH_AVAILABLE | chNum; iapi_errno = result; return -result; } /* Buffer descriptor setting */ iapi_SetBufferDescriptor(bd_p, command, BD_WRAP | BD_DONE | BD_INTR, nbyte, buf, NULL); /* Actually the transfer */ iapi_lowStartChannel(cd_p->channelNumber); iapi_lowSynchChannel(cd_p->channelNumber); /* Cleaning of allocation */ FREE(bd_p); ccb_p->baseBDptr = NULL; return IAPI_SUCCESS; }