/******************************************************************************* * **+--------------------------------------------------------------------------+** * **| **** |** * **| **** |** * **| ******o*** |** * **| ********_///_**** |** * **| ***** /_//_/ **** |** * **| ** ** (__/ **** |** * **| ********* |** * **| **** |** * **| *** |** * **| |** * **| Copyright (c) 1998-2006 Texas Instruments Incorporated |** * **| ALL RIGHTS RESERVED |** * **| |** * **+--------------------------------------------------------------------------+** * *******************************************************************************/ /** \file pal_cppi4.c * \brief PAL CPPI 4 Source file * * This file contains the main PAL implementation for CPPI4 common peripherals, * including the CPPI 4 DMA Controller, the Queue Manager, and the Buffer * Manager. Based upon PSP Framework architecture. * * @author Greg Guyotte * */ #include "pal.h" /* PAL SYS/OS services required */ #include "pal_cppi4Pvt.h" /* Version macro */ #define CPPI4_PAL_MAJOR_VERSION 0 #define CPPI4_PAL_MINOR_VERSION 1 const static Char Cppi4PALVersionString[] = "CPPI4 PAL version 0.2"; /* Static Global Instance Variable */ static Cppi4PALObj Cppi4PALObject; static Uint32 Cppi4PALNumInst = 0; Uint32 Cppi4PALDebug = 0; /* No debug flags by default */ static Ptr tdArray; static Ptr tempTDArray; /************************ CPPI4 PAL FUNCTIONS (External Interface) *************/ /** * * PAL_cppi4Init * * - initializes the PAL CPPI4 instance for first caller only * * - returns handle to PAL * * * */ PAL_Handle * PAL_cppi4Init (Cppi4InitConfig * initCfg, Ptr param) { Teardown_DescSize_t * tempBD; Cppi4PALObj *palCppi4Obj = &Cppi4PALObject; Uint32 retVal = PAL_SOK; Uint32 size = 0; Uint32 ch; /* Check if CPPI4 is already initialized */ if (Cppi4PALNumInst++ > 0) return ((PAL_Handle *) palCppi4Obj); PAL_osMemSet (palCppi4Obj, 0, sizeof (Cppi4PALObj)); /* Set CPPI4 object variables */ palCppi4Obj->versionId = (CPPI4_PAL_MAJOR_VERSION << 16) | CPPI4_PAL_MINOR_VERSION; palCppi4Obj->qmRegs = (CSL_QueueMgr_RegsOvly) initCfg->qmRegs_Addr; palCppi4Obj->dmaRegs = (CSL_Cppi4Dma_RegsOvly) initCfg->dmaRegs_Addr; palCppi4Obj->resetLine = initCfg->resetLine; /* Bring CPPI4 out of reset - for clean implementation, reset and then * * unreset the module */ // bk: TODO Move this to early_initcall, before any module is started (before CPMAC and DSL) // PAL_sysResetCtrl (initCfg->resetLine, IN_RESET); // PAL_sysResetCtrl (initCfg->resetLine, OUT_OF_RESET); // PAL_osWaitMsecs (CPPI4_RESET_WAIT); // end bk size = ((sizeof (Teardown_DescSize_t) * CPPI4_MAX_CHANNELS * 2)+512); retVal = PAL_osMemAlloc(0, size, 0, (Ptr *) & tempTDArray); if (retVal != PAL_SOK) { CPPI4_PAL_LOGERR ("\nERROR:PAL: cppi4Open: Failed to allocate teardown descriptors"); return NULL; } tdArray = (Ptr)((Uint32)tempTDArray & 0xFFFFFF00); tdArray = (Ptr)((Uint32)tdArray + 512); tempBD = (Teardown_DescSize_t *)tdArray; /* initialize teardown array with channel numbers */ for (ch=0; chchannelNo = ch; /* Tx teardown descriptor */ tempBD->channelType = 0; tempBD++; tempBD->channelNo = ch; /* Rx teardown descriptor */ tempBD->channelType = 1; tempBD++; } palCppi4Obj->tdDescArray = (Teardown_DescSize_t *) tdArray; palCppi4Obj->dmaRegs->Teardown_Desc_Array_Ptr = PAL_CPPI4_VIRT_2_PHYS ((Uint32) palCppi4Obj->tdDescArray); palCppi4Obj->dmaRegs->Teardown_Desc_Size = (sizeof (Teardown_DescSize_t) / 4) - 1; /* Divide by four */ return ((PAL_Handle *) palCppi4Obj); } /** * PAL_cppi4GetTxTeardownBD * - Returns the Address of the TX Teardown Buffer Descriptor from the SW array * */ PAL_Cppi4BD * PAL_cppi4GetTxTeardownBD (PAL_Cppi4TxChHnd * hnd, Ptr param) { PAL_Cppi4TxChObj *txChObj = (PAL_Cppi4TxChObj *) hnd; Cppi4PALObj *palCppi4Obj = txChObj->palCppi4Obj; Teardown_DescSize_t *retBD = &palCppi4Obj->tdDescArray[txChObj->chNum]; /* Returning the value from the SW array. */ return ((PAL_Cppi4BD *) retBD); } /** * * PAL_cppi4GetRxTeardownBD * * - Returns the Address of the RX Teardown Buffer Descriptor from the SW array * * * */ PAL_Cppi4BD * PAL_cppi4GetRxTeardownBD (PAL_Cppi4RxChHnd * hnd, Ptr param) { PAL_Cppi4RxChObj *rxChObj = (PAL_Cppi4RxChObj *) hnd; Cppi4PALObj *palCppi4Obj = rxChObj->palCppi4Obj; Teardown_DescSize_t *retBD = &palCppi4Obj->tdDescArray[rxChObj->chNum + 1]; /* Returning the value from the SW array. */ return ((PAL_Cppi4BD *) retBD); } /** * * PAL_cppi4TxChOpen * * - Verify channel info (range checking etc) * * - Allocate memory for the channel * * - Channel information stored within PAL structure * * \note "chOpenArgs" is not used * */ PAL_Cppi4TxChHnd * PAL_cppi4TxChOpen (PAL_Handle * hnd, Cppi4TxChInfo * info, Ptr chOpenArgs) { Uint32 chNum = info->chInfo.chNum; Cppi4PALObj *palCppi4Obj = (Cppi4PALObj *) hnd; PAL_Cppi4TxChObj *txChObj; if (chNum >= CPPI4_MAX_CHANNELS) return (NULL); txChObj = &palCppi4Obj->txCh[chNum]; if (txChObj->isOpen) return (NULL); PAL_osMemSet (txChObj, 0, sizeof (PAL_Cppi4TxChObj)); /* Populate channel Obj structure to return to calling function */ txChObj->chNum = chNum; txChObj->endian = info->chInfo.endian; txChObj->chMode = info->chInfo.chMode; txChObj->descCopyCnt = info->descCopyByteCount; txChObj->pktType = info->pktType; txChObj->cqIndex = info->cqIndex; txChObj->txQueue = &palCppi4Obj->qmRegs->Tx_Queue[chNum]; txChObj->txCompQueue = &palCppi4Obj->qmRegs->Tx_Completion_Queue[info->cqIndex]; txChObj->txCompQueueIntrEOI = &palCppi4Obj->qmRegs->Tx_Completion_Queue_Int_EOI; txChObj->palCppi4Obj = palCppi4Obj; txChObj->isOpen = True; return (PAL_Cppi4TxChHnd *) txChObj; } /** * * PAL_cppi4TxChClose * * - Free all stored channel information for the given Transmit channel * */ PAL_Result PAL_cppi4TxChClose (PAL_Cppi4TxChHnd * hnd, Ptr chCloseArgs) { PAL_Cppi4TxChObj *txChObj = (PAL_Cppi4TxChObj *) hnd; if (txChObj->isOpen == False) return (CPPI4_ERR_TX_CH_ALREADY_CLOSED); txChObj->isOpen = False; return (PAL_SOK); } /** * * PAL_cppi4RxChOpen * * - Verify channel info (range checking etc) * * - Allocate memory for the channel * * - Channel information stored within PAL structure * * \note "chOpenArgs" is not used * */ PAL_Cppi4RxChHnd * PAL_cppi4RxChOpen (PAL_Handle * hnd, Cppi4RxChInfo * info, Ptr chOpenArgs) { Uint32 chNum = info->chInfo.chNum; Cppi4PALObj *palCppi4Obj = (Cppi4PALObj *) hnd; PAL_Cppi4RxChObj *rxChObj; if (chNum >= CPPI4_MAX_CHANNELS) return (NULL); rxChObj = &palCppi4Obj->rxCh[chNum]; printk ("[bk] %s : rxChObj = %p\n",__FUNCTION__, &palCppi4Obj->rxCh[chNum]); if (rxChObj->isOpen == True) return (NULL); printk ("[bk] %s : sizeof(PAL_Cppi4RxChObj) = %d\n",__FUNCTION__, sizeof(PAL_Cppi4RxChObj)); PAL_osMemSet (rxChObj, 0, sizeof (PAL_Cppi4RxChObj)); rxChObj->chNum = chNum; rxChObj->endian = info->chInfo.endian; rxChObj->chMode = info->chInfo.chMode; rxChObj->sopOffset = info->sopOffset; rxChObj->fbqIndex[0] = info->fbqIndex[0]; rxChObj->fbqIndex[1] = info->fbqIndex[0]; rxChObj->fbqIndex[2] = info->fbqIndex[0]; rxChObj->fbqIndex[3] = info->fbqIndex[0]; rxChObj->rqIndex = ((((info->rqIndex) * 4) + 0xE00) & 0xFFF); rxChObj->fdbIndex = info->fdpIndex; rxChObj->errHandling = info->errHandling; rxChObj->palCppi4Obj = palCppi4Obj; rxChObj->rxQueue = &palCppi4Obj->qmRegs->Rx_Queue[(rxChObj->rqIndex & 0xfc) / 4]; printk("[bk] %s: &palCppi4Obj->qmRegs->Rx_Free_Desc_Queue[rxChObj->fbqIndex[0]] : %p\n",__FUNCTION__,&palCppi4Obj->qmRegs->Rx_Free_Desc_Queue[rxChObj->fbqIndex[0]] ); printk("[bk] %s: rxChObj->fbqIndex[0] : %p\n",__FUNCTION__,rxChObj->fbqIndex[0]); printk("[bk] %s: palCppi4Obj->qmRegs : %p\n",__FUNCTION__,palCppi4Obj->qmRegs); rxChObj->rxFreeQueue = &palCppi4Obj->qmRegs->Rx_Free_Desc_Queue[rxChObj->fbqIndex[0]]; printk("[bk] %s: rxChObj->rxFreeQueue : %p\n",__FUNCTION__,rxChObj->rxFreeQueue); rxChObj->rxQueueIntrEOI = &palCppi4Obj->qmRegs->Rx_Queue_Int_EOI; rxChObj->isOpen = True; return ((PAL_Cppi4RxChHnd *) rxChObj); } /** * * PAL_cppi4RxChClose * * - Free all stored channel information for the given Receive channel * */ PAL_Result PAL_cppi4RxChClose (PAL_Cppi4RxChHnd * hnd, Ptr chCloseArgs) { PAL_Cppi4RxChObj *rxChObj = (PAL_Cppi4RxChObj *) hnd; if (rxChObj->isOpen == False) return (CPPI4_ERR_RX_CH_ALREADY_CLOSED); rxChObj->isOpen = False; return (PAL_SOK); } /** * * PAL_cppi4EnableTxIntr * * - Enables the interrupt for the Tx completion queue. * * * */ PAL_Result PAL_cppi4EnableTxIntr (PAL_Cppi4TxChHnd * hnd, Ptr param) { PAL_Cppi4TxChObj *txChObj = (PAL_Cppi4TxChObj *) hnd; Cppi4PALObj *palCppi4Obj = txChObj->palCppi4Obj; /* Enable the channelinterrupt */ palCppi4Obj->qmRegs->Tx_Completion_Queue_Int_Mask_Set = (1 << (txChObj->cqIndex)); return (PAL_SOK); } /** * * PAL_cppi4DisableTxChannel * * - Channel DMA is disabled in hardware. * * * */ PAL_Result PAL_cppi4DisableTxChannel (PAL_Cppi4TxChHnd * hnd, Ptr chCloseArgs) { PAL_Cppi4TxChObj *txChObj = (PAL_Cppi4TxChObj *) hnd; Cppi4PALObj *palCppi4Obj = txChObj->palCppi4Obj; CSL_Ch_Cfg_A_B_Regs *txCfgRegs = &palCppi4Obj->dmaRegs->Ch_Cfg[txChObj->chNum].Tx_Ch_Cfg; /* Initiate teardown of TX channel */ txCfgRegs->CfgB = 1 /* (disable) */ << TXCFG_TEARDOWN_SHIFT; txCfgRegs->CfgB = (1 /* (enable) */ << TXCFG_ENABLE_SHIFT) | (1 /* (disable) */ << TXCFG_TEARDOWN_SHIFT) | (txChObj->chMode << TXCFG_CHMODE_SHIFT) | (txChObj->endian << TXCFG_ENDIAN_SHIFT) | (txChObj->pktType << TXCFG_PKTTYPE_SHIFT) | (txChObj->cqIndex << TXCFG_CQINDEX_SHIFT); /* Mark channel closed */ txChObj->isEnabled = False; return (PAL_SOK); } /** * * PAL_cppi4EnableTxChannel * * - Channel DMA is enabled in hardware. Ready for data transmission. * */ PAL_Result PAL_cppi4EnableTxChannel (PAL_Cppi4TxChHnd * hnd, Ptr chCloseArgs) { PAL_Cppi4TxChObj *txChObj = (PAL_Cppi4TxChObj *) hnd; Cppi4PALObj *palCppi4Obj = txChObj->palCppi4Obj; CSL_Ch_Cfg_A_B_Regs *txCfgRegs = &palCppi4Obj->dmaRegs->Ch_Cfg[txChObj->chNum].Tx_Ch_Cfg; /* Initialize CPPI 4 Channel Config Registers */ txCfgRegs->CfgA = txChObj->descCopyCnt << TXCFG_DESC_COPY_BYTECOUNT_SHIFT; txCfgRegs->CfgB = (1 /* (enable) */ << TXCFG_ENABLE_SHIFT) | (txChObj->chMode << TXCFG_CHMODE_SHIFT) | (txChObj->endian << TXCFG_ENDIAN_SHIFT) | (txChObj->pktType << TXCFG_PKTTYPE_SHIFT) | (txChObj->cqIndex << TXCFG_CQINDEX_SHIFT); /* Mark channel open */ txChObj->isEnabled = True; return (PAL_SOK); } /** * * PAL_cppi4EnableRxChannel * * - Channel DMA is enabled in hardware. Ready for data reception. * * * */ PAL_Result PAL_cppi4EnableRxChannel (PAL_Cppi4RxChHnd * hnd, Ptr chCloseArgs) { PAL_Cppi4RxChObj *rxChObj = (PAL_Cppi4RxChObj *) hnd; Cppi4PALObj *palCppi4Obj = rxChObj->palCppi4Obj; CSL_Ch_Cfg_A_B_Regs *rxCfgRegs = &palCppi4Obj->dmaRegs->Ch_Cfg[rxChObj->chNum].Rx_Ch_Cfg; /* Initialize CPPI 4 Channel Config Registers */ rxCfgRegs->CfgA = (rxChObj->fbqIndex[3] << RXCFG_FBQ3INDEX_SHIFT) | (rxChObj->fbqIndex[2] << RXCFG_FBQ2INDEX_SHIFT) | (rxChObj->fbqIndex[1] << RXCFG_FBQ1INDEX_SHIFT) | (rxChObj->fbqIndex[0] << RXCFG_FBQ0INDEX_SHIFT); rxCfgRegs->CfgB = (1 /* Enable */ << RXCFG_ENABLE_SHIFT) | (rxChObj->endian << RXCFG_ENDIAN_SHIFT) | (rxChObj->chMode << RXCFG_CHMODE_SHIFT) | (rxChObj->errHandling << RXCFG_ERRHANDLING_SHIFT) | (rxChObj->sopOffset << RXCFG_SOPOFFSET_SHIFT) | (rxChObj->fdbIndex << RXCFG_FDPINDEX_SHIFT) | (rxChObj->rqIndex << RXCFG_RQINDEX_SHIFT); /* Mark channel open */ rxChObj->isEnabled = True; return (PAL_SOK); } /** * * PAL_cppi4EnableRxIntr * * - Enables the interrupt for the Rx queue. * * * */ PAL_Result PAL_cppi4EnableRxIntr (PAL_Cppi4RxChHnd * hnd, Ptr param) { PAL_Cppi4RxChObj *rxChObj = (PAL_Cppi4RxChObj *) hnd; Cppi4PALObj *palCppi4Obj = rxChObj->palCppi4Obj; /* Enable the channelinterrupt */ palCppi4Obj->qmRegs->Rx_Queue_Int_Mask_Set = (1 << ((rxChObj->rqIndex & 0xfc) / 4)); return (PAL_SOK); } /* EXPORT_SYMBOL(PAL_cppi4Init); EXPORT_SYMBOL(PAL_cppi4TxChOpen); EXPORT_SYMBOL(PAL_cppi4TxChClose); EXPORT_SYMBOL(PAL_cppi4RxChOpen); EXPORT_SYMBOL(PAL_cppi4RxChClose); EXPORT_SYMBOL(PAL_cppi4GetTxTeardownBD); EXPORT_SYMBOL(PAL_cppi4GetRxTeardownBD); EXPORT_SYMBOL(PAL_cppi4EnableTxIntr); EXPORT_SYMBOL(PAL_cppi4DisableTxChannel); EXPORT_SYMBOL(PAL_cppi4EnableTxChannel); EXPORT_SYMBOL(PAL_cppi4EnableRxChannel); EXPORT_SYMBOL(PAL_cppi4EnableRxIntr); */