I am working on communication between a TI TMS320C6678 DSP and an Altera Arria 10 FPGA via SRIO. I am able to send an NREAD and NWRITE packet using 16bit Device IDs(ID SIZE = b'01) to the FPGA and have verified this with Signal Tap. When I switch to 8 bit Device IDs (ID SIZE = b'00) I am not seeing the packets go through to the FPGA. Attached is the code i'm using to send the working 16 bit Device ID packets. For 8 bit Device IDs I simply change the idsize in srio_control.c to 0. I have verified that this is setting LSU_REG 4 to the proper value.
/*
* srio_control.cpp
*
* Created on: Jun 3, 2014
* Author: bsnedake
*/
#include <xdc/std.h>
#include <string.h>
#include <c6x.h>
#include <xdc/runtime/IHeap.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/Memory.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/heaps/HeapBuf.h>
#include <ti/sysbios/heaps/HeapMem.h>
#include <ti/sysbios/hal/Hwi.h>
#include <ti/sysbios/family/c64p/EventCombiner.h>
#include <ti/sysbios/family/c66/tci66xx/CpIntc.h>
#include <xdc/cfg/global.h>
/* SRIO Driver Include File. */
#include <ti/drv/srio/srio_drv.h>
#include <ti/drv/srio/srio_osal.h>
/* CPPI/QMSS Include Files. */
#include <ti/drv/cppi/cppi_drv.h>
#include <ti/drv/qmss/qmss_drv.h>
#include <ti/drv/qmss/qmss_firmware.h>
/* CSL Chip Functional Layer */
#include <ti/csl/csl_chip.h>
/* CSL Cache Functional Layer */
#include <ti/csl/csl_cacheAux.h>
/* PSC CSL Include Files */
#include <ti/csl/csl_psc.h>
#include <ti/csl/csl_pscAux.h>
/* CSL SRIO Functional Layer */
#include <ti/csl/csl_srio.h>
#include <ti/csl/csl_srioAux.h>
/* CSL CPINTC Include Files. */
#include<ti/csl/csl_cpIntc.h>
/**********************************************************************
************************** LOCAL Definitions *************************
**********************************************************************/
/* This is the Number of host descriptors which are available & configured
* in the memory region for this example. */
#define NUM_HOST_DESC 128
/* This is the size of each descriptor. */
#define SIZE_HOST_DESC 48
/* MTU of the SRIO Driver. We are currently operating @ MTU of 256 bytes. */
#define SRIO_MAX_MTU 256
/* This is the size of the data buffer which is used for DIO Sockets. */
//#define SIZE_DIO_PACKET 128
/* Defines the core number responsible for system initialization. */
#define CORE_SYS_INIT 0
/* Defines number of transfers done by DIO sockets in this example */
//#define SRIO_DIO_LSU_ISR_NUM_TRANSFERS 3
/* ISR timeout value (in cycles) used in this example */
#define SRIO_DIO_LSU_ISR_TIMEOUT 100000
/**********************************************************************
************************** Global Variables **************************
**********************************************************************/
/* Memory allocated for the descriptors. This is 16 bit aligned. */
#pragma DATA_ALIGN (host_region, 16)
Uint8 host_region[NUM_HOST_DESC * SIZE_HOST_DESC];
/* Memory used for the accumulator list. */
#pragma DATA_ALIGN (gHiPriAccumList, 16)
UInt32 gHiPriAccumList[64];
/* Global SRIO and QMSS Configuration */
Qmss_InitCfg qmssInitConfig;
/* Global Varialble which keeps track of the core number executing the
* application. */
UInt32 coreNum = 0xFFFF;
/* Shared Memory Variable to ensure synchronizing SRIO initialization
* with all the other cores. */
/* Created an array to pad the cache line with SRIO_MAX_CACHE_ALIGN size */
#pragma DATA_ALIGN (isSRIOInitialized, 128)
#pragma DATA_SECTION (isSRIOInitialized, ".srioSharedMem");
volatile Uint32 isSRIOInitialized[(SRIO_MAX_CACHE_ALIGN / sizeof(Uint32))] = { 0 };
Srio_DrvHandle hDrvManagedSrioDrv;
CSL_SrioHandle hSrioCSL;
/* These are the device identifiers used in the Example Application */
const uint32_t DEVICE_ID1_16BIT = 0xFFFF;
const uint32_t DEVICE_ID1_8BIT = 0xCD;
const uint32_t LOCAL_BUS_DEVICE_ID = 0xAB;
const uint32_t FPGA_DDR_DEVICE_ID = 0x1;
const uint32_t FPGA_TDW_DEVICE_ID = 0x2;
//const uint32_t DEVICE_ID2_16BIT = 0x4560;
//const uint32_t DEVICE_ID2_8BIT = 0xCD;
//const uint32_t DEVICE_ID3_16BIT = 0x1234;
//const uint32_t DEVICE_ID3_8BIT = 0x12;
//const uint32_t DEVICE_ID4_16BIT = 0x5678;
//const uint32_t DEVICE_ID4_8BIT = 0x56;
/* Array containing SRIO socket handles */
Srio_SockHandle srioSocket;
/* Global debug variable to track number of ISRs raised */
volatile UInt32 srioDbgDoorBellCnt = 0;
/* Global variable to indicate completion of ISR processing */
volatile UInt32 srioLsuIsrServiced = 0;
/* Global variables to count good and bad transfers */
//volatile UInt32 srioDioLsuGoodTransfers = 0;
//volatile UInt32 srioDioLsuBadTransfers = 0;
/**********************************************************************
************************ External Definitions ************************
**********************************************************************/
extern int32_t SrioDevice_init (void);
/* QMSS device specific configuration */
extern Qmss_GlobalConfigParams qmssGblCfgParams;
/* CPPI device specific configuration */
extern Cppi_GlobalConfigParams cppiGblCfgParams;
/* OSAL Data Buffer Memory Initialization. */
extern int32_t Osal_dataBufferInitMemory(uint32_t dataBufferSize);
/**
* @b Description
* @n
* Utility function which converts a local address to global.
*
* @param[in] addr
* Local address to be converted
*
* @retval
* Global Address
*/
static UInt32 l2_global_address (Uint32 addr)
{
UInt32 corenum;
/* Get the core number. */
corenum = CSL_chipReadReg(CSL_CHIP_DNUM);
/* Compute the global address. */
return (addr + (0x10000000 + (corenum*0x1000000)));
}
UInt32 get_core_num() {
return coreNum;
}
UInt32 get_doorbell_isr_count() {
return srioDbgDoorBellCnt;
}
/**
* @b Description
* @n
* This function enables the power/clock domains for SRIO.
*
* @retval
* Not Applicable.
*/
static Int32 enable_srio (void)
{
/* SRIO power domain is turned OFF by default. It needs to be turned on before doing any
* SRIO device register access. This not required for the simulator. */
/* Set SRIO Power domain to ON */
CSL_PSC_enablePowerDomain (CSL_PSC_PD_SRIO);
/* Enable the clocks too for SRIO */
CSL_PSC_setModuleNextState (CSL_PSC_LPSC_SRIO, PSC_MODSTATE_ENABLE);
/* Start the state transition */
CSL_PSC_startStateTransition (CSL_PSC_PD_SRIO);
/* Wait until the state transition process is completed. */
while (!CSL_PSC_isStateTransitionDone (CSL_PSC_PD_SRIO));
/* Return SRIO PSC status */
if ((CSL_PSC_getPowerDomainState(CSL_PSC_PD_SRIO) == PSC_PDSTATE_ON) &&
(CSL_PSC_getModuleState (CSL_PSC_LPSC_SRIO) == PSC_MODSTATE_ENABLE))
{
/* SRIO ON. Ready for use */
return 0;
}
else
{
/* SRIO Power on failed. Return error */
return -1;
}
}
/**
* @b Description
* @n
* System Initialization Code. This is added here only for illustrative
* purposes and needs to be invoked once during initialization at
* system startup.
*
* @retval
* Success - 0
* @retval
* Error - <0
*/
static Int32 system_init (Void)
{
Int32 result;
Qmss_MemRegInfo memRegInfo;
/* Initialize the QMSS Configuration block. */
memset (&qmssInitConfig, 0, sizeof (Qmss_InitCfg));
/* Initialize the Host Region. */
memset ((void *)&host_region, 0, sizeof(host_region));
/* Set up the linking RAM. Use the internal Linking RAM.
* LLD will configure the internal linking RAM address and maximum internal linking RAM size if
* a value of zero is specified. Linking RAM1 is not used */
qmssInitConfig.linkingRAM0Base = 0;
qmssInitConfig.linkingRAM0Size = 0;
qmssInitConfig.linkingRAM1Base = 0;
qmssInitConfig.maxDescNum = NUM_HOST_DESC;
/* PDSP Configuration: Little Endian */
qmssInitConfig.pdspFirmware[0].pdspId = Qmss_PdspId_PDSP1;
qmssInitConfig.pdspFirmware[0].firmware = (void*)acc48_le;
qmssInitConfig.pdspFirmware[0].size = sizeof (acc48_le);
/* Initialize Queue Manager Sub System */
result = Qmss_init (&qmssInitConfig, &qmssGblCfgParams);
if (result != QMSS_SOK)
{
System_printf ("Error initializing Queue Manager SubSystem error code : %d\n", result);
return -1;
}
/* Start the QMSS. */
if (Qmss_start() != QMSS_SOK)
{
System_printf ("Error: Unable to start the QMSS\n");
return -1;
}
/* Memory Region 0 Configuration */
memRegInfo.descBase = (UInt32 *)l2_global_address((UInt32)host_region);
memRegInfo.descSize = SIZE_HOST_DESC;
memRegInfo.descNum = NUM_HOST_DESC;
memRegInfo.manageDescFlag = Qmss_ManageDesc_MANAGE_DESCRIPTOR;
memRegInfo.memRegion = Qmss_MemRegion_MEMORY_REGION_NOT_SPECIFIED;
/* Initialize and inset the memory region. */
result = Qmss_insertMemoryRegion (&memRegInfo);
if (result < QMSS_SOK)
{
System_printf ("Error inserting memory region: %d\n", result);
return -1;
}
/* Initialize CPPI CPDMA */
result = Cppi_init (&cppiGblCfgParams);
if (result != CPPI_SOK)
{
System_printf ("Error initializing Queue Manager SubSystem error code : %d\n", result);
return -1;
}
/* CPPI and Queue Manager are initialized. */
System_printf ("Debug(Core %d): Queue Manager and CPPI are initialized.\n", coreNum);
System_printf ("Debug(Core %d): Host Region 0x%x\n", coreNum, host_region);
return 0;
}
/**
* Doorbell Interrupt Service Routine
*/
uint16_t doorbellStatus = 0;
Void DoorBellIsr (UArg arg)
{
Uint16 doorbellStatus;
Uint8 doorbellReg = coreNum % 4;
Uint16 mask = (Uint16)arg;
Uint16 doorbellBits;
/* Get the doorbell bits */
CSL_SRIO_GetDoorbellPendingInterrupt(hSrioCSL,doorbellReg,&doorbellStatus);
/* Mask off the bits that didn't cause the interrupt */
doorbellBits = doorbellStatus & mask;
if(doorbellBits > 0)
{
/* Clear the doorbell bits */
CSL_SRIO_ClearDoorbellPendingInterrupt(hSrioCSL,doorbellReg, doorbellBits);
/* Some cores use the high bits of the registers, shift them down if this
* is one of those cores */
if(doorbellBits > 0xFF) {
doorbellBits = doorbellBits >> 8;
}
/* Check which doorbell bits were set */
if(doorbellBits & (1 << 0)) {
/* This bit is used to indicate an LSU transaction completed */
srioDbgDoorBellCnt++;
srioLsuIsrServiced = 1;
}
/* These bits are currently not used, just count them */
if(doorbellBits & (1 << 1))
srioDbgDoorBellCnt++;
if(doorbellBits & (1 << 2))
srioDbgDoorBellCnt++;
if(doorbellBits & (1 << 3))
srioDbgDoorBellCnt++;
if(doorbellBits & (1 << 4))
srioDbgDoorBellCnt++;
if(doorbellBits & (1 << 5))
srioDbgDoorBellCnt++;
if(doorbellBits & (1 << 6))
srioDbgDoorBellCnt++;
if(doorbellBits & (1 << 7))
srioDbgDoorBellCnt++;
}
}
/**
* Function to create and bind SRIO socket
*/
static Int32 create_srio_sockets() {
UInt8 isAllocated;
Srio_DrvConfig drvCfg;
Srio_SockBindAddrInfo bindInfo;
Uint16 mask;
/* Initialize the SRIO Driver Configuration. */
memset ((Void *)&drvCfg, 0, sizeof(Srio_DrvConfig));
/* Initialize the OSAL */
if (Osal_dataBufferInitMemory(SRIO_MAX_MTU) < 0)
{
System_printf ("Error: Unable to initialize the OSAL. \n");
return -1;
}
/********************************************************************************
* The SRIO Driver Instance is going to be created with the following properties:
* - Driver Managed
* - Interrupt Support (Pass the Rx Completion Queue as NULL)
********************************************************************************/
/* Setup the SRIO Driver Managed Configuration. */
drvCfg.bAppManagedConfig = FALSE;
/* Driver Managed: Receive Configuration */
drvCfg.u.drvManagedCfg.bIsRxCfgValid = 1;
drvCfg.u.drvManagedCfg.rxCfg.rxMemRegion = Qmss_MemRegion_MEMORY_REGION0;
drvCfg.u.drvManagedCfg.rxCfg.numRxBuffers = 4;
drvCfg.u.drvManagedCfg.rxCfg.rxMTU = SRIO_MAX_MTU;
/* Accumulator Configuration. */
{
int32_t coreToQueueSelector[8];
/* This is the table which maps the core to a specific receive queue. */
coreToQueueSelector[0] = 704;
coreToQueueSelector[1] = 705;
coreToQueueSelector[2] = 706;
coreToQueueSelector[3] = 707;
coreToQueueSelector[4] = 708;
coreToQueueSelector[5] = 709;
coreToQueueSelector[6] = 710;
coreToQueueSelector[7] = 711;
/* Since we are programming the accumulator we want this queue to be a HIGH PRIORITY Queue */
drvCfg.u.drvManagedCfg.rxCfg.rxCompletionQueue = Qmss_queueOpen (Qmss_QueueType_HIGH_PRIORITY_QUEUE,
coreToQueueSelector[coreNum], &isAllocated);
if (drvCfg.u.drvManagedCfg.rxCfg.rxCompletionQueue < 0)
{
System_printf ("Error: Unable to open the SRIO Receive Completion Queue\n");
return -1;
}
/* Accumulator Configuration is VALID. */
drvCfg.u.drvManagedCfg.rxCfg.bIsAccumlatorCfgValid = 1;
/* Accumulator Configuration. */
drvCfg.u.drvManagedCfg.rxCfg.accCfg.channel = coreNum;
drvCfg.u.drvManagedCfg.rxCfg.accCfg.command = Qmss_AccCmd_ENABLE_CHANNEL;
drvCfg.u.drvManagedCfg.rxCfg.accCfg.queueEnMask = 0;
drvCfg.u.drvManagedCfg.rxCfg.accCfg.queMgrIndex = coreToQueueSelector[coreNum];
drvCfg.u.drvManagedCfg.rxCfg.accCfg.maxPageEntries = 2;
drvCfg.u.drvManagedCfg.rxCfg.accCfg.timerLoadCount = 0;
drvCfg.u.drvManagedCfg.rxCfg.accCfg.interruptPacingMode = Qmss_AccPacingMode_LAST_INTERRUPT;
drvCfg.u.drvManagedCfg.rxCfg.accCfg.listEntrySize = Qmss_AccEntrySize_REG_D;
drvCfg.u.drvManagedCfg.rxCfg.accCfg.listCountMode = Qmss_AccCountMode_ENTRY_COUNT;
drvCfg.u.drvManagedCfg.rxCfg.accCfg.multiQueueMode = Qmss_AccQueueMode_SINGLE_QUEUE;
/* Initialize the accumulator list memory */
memset ((Void *)&gHiPriAccumList[0], 0, sizeof(gHiPriAccumList));
drvCfg.u.drvManagedCfg.rxCfg.accCfg.listAddress = l2_global_address((UInt32)&gHiPriAccumList[0]);
}
/* Driver Managed: Transmit Configuration */
drvCfg.u.drvManagedCfg.bIsTxCfgValid = 1;
drvCfg.u.drvManagedCfg.txCfg.txMemRegion = Qmss_MemRegion_MEMORY_REGION0;
drvCfg.u.drvManagedCfg.txCfg.numTxBuffers = 4;
drvCfg.u.drvManagedCfg.txCfg.txMTU = SRIO_MAX_MTU;
/* Start the Driver Managed SRIO Driver. */
hDrvManagedSrioDrv = Srio_start(&drvCfg);
if (hDrvManagedSrioDrv == NULL)
{
System_printf ("Error(Core %d): SRIO Driver failed to start\n", coreNum);
return -1;
}
System_printf ("*************************************************************\n");
System_printf ("******* DIO Socket Example with Interrupts (Core %d) ********\n", coreNum);
System_printf ("*************************************************************\n");
/* Get the CSL SRIO Handle. */
hSrioCSL = CSL_SRIO_Open (0);
if (hSrioCSL == NULL)
return -1;
/**************************************************************
* INTERRUPT SETUP *
**************************************************************/
/***************** Doorbell Interrupts ************************/
/*
* Doorbell Interrupt Destinations 0 - 7 are routed to System Events INTDST 16 - 23
* respectively. This routing is handled in srio_device. The C66x CorePac routes
* System Events INTDST(coreNum + 16) to Event Number 20, so no special CorePac
* routing is needed to expose the doorbell interrupts.
*/
Hwi_Params hwiParams;
Error_Block eb;
Hwi_Params_init(&hwiParams);
Error_init(&eb);
/*
* Core numbers 0 - 3 get the lower 7 bits of Doorbell registers 0 - 3 respectively.
* Core numbers 4 - 7 get the upper 7 bits of Doorbell registers 0 - 3 respectively.
* Make the arg be the mask of the bits for the doorbell
*/
if(coreNum < 4) {
mask = 0x00FF;
} else {
mask = 0xFF00;
}
hwiParams.arg = mask;
/* Set the event id */
hwiParams.eventId = 20;
/* don't allow this interrupt to nest itself */
hwiParams.maskSetting = Hwi_MaskingOption_SELF;
/*
* Configure interrupt 4 to invoke the interrupt handler for the doorbells.
* This will automatically enable the interrupt
*/
Hwi_create(4, DoorBellIsr, &hwiParams, &eb);
/*
* Check the error code to make sure the interrupt handler was created
*/
if (Error_check(&eb)) {
System_printf("Error creating Doorbell ISR\n");
}
/****************** LSU Interrupts *****************************/
/* LSU Interrupts are routed based on the srcID in the socket binding. Each core
* is going to be creating two sockets, and the interrupts from both sockets
* will be routed to a common interrupt destination (INTDST). Routing is
* done through the Interrupt Condition Routing (ICR) register, and will
* be set up according to this table:
*
* Core SysID ICR INTDST Interrupts Expected
* ---- ----- --- ------ -------------------
* 0 0 0 0 N
* 0 1 1 0 Y
* 1 2 2 1 N
* 1 3 3 1 Y
* 2 4 4 2 N
* 2 5 5 2 Y
* 3 6 6 3 N
* 3 7 7 3 Y
* 4 8 8 4 N
* 4 9 9 4 Y
* 5 10 10 5 N
* 5 11 11 5 Y
* 6 12 12 6 N
* 6 13 13 6 Y
* 7 14 14 7 N
* 7 15 15 7 Y
*/
// /* Disable Interrupt Pacing for the INTDST */
// CSL_SRIO_DisableInterruptPacing (hSrioCSL, coreNum);
//
// /* Route LSU ICR to INTDST. This is the NO_INTERRUPT socket, so nothing is expected from this */
// CSL_SRIO_RouteLSUInterrupts (hSrioCSL, coreNum*2, coreNum);
//
// /* Route LSU ICR to INTDST. This is the INTERRUPT socket, so interrupts are expected from this */
// CSL_SRIO_RouteLSUInterrupts (hSrioCSL, coreNum*2+1, coreNum);
//
// /* The INTDST 0-7 lines do not route directly to the CorePac, instead we need to go
// * through the Chip Interrupt Controller (Sometimes called CIC, sometimes called INTC).
// * There are two CIC's, CIC0 routes to cores 0-3, CIC1 routes to cores 4-7. Figure out
// * which CIC and INTDST combo is needed based on the core number */
// switch(coreNum) {
// case 0:
// cic = 0;
// intcIntdst = CSL_INTC0_INTDST0;
// break;
// case 1:
// cic = 0;
// intcIntdst = CSL_INTC0_INTDST1;
// break;
// case 2:
// cic = 0;
// intcIntdst = CSL_INTC0_INTDST2;
// break;
// case 3:
// cic = 0;
// intcIntdst = CSL_INTC0_INTDST3;
// break;
// case 4:
// cic = 1;
// intcIntdst = CSL_INTC1_INTDST4;
// break;
// case 5:
// cic = 1;
// intcIntdst = CSL_INTC1_INTDST5;
// break;
// case 6:
// cic = 1;
// intcIntdst = CSL_INTC1_INTDST6;
// break;
// case 7:
// cic = 1;
// intcIntdst = CSL_INTC1_INTDST7;
// break;
// default:
// // This should never happen
// System_printf("Unknown core number %d\n", coreNum);
// intcIntdst = CSL_INTC0_INTDST0;
// }
//
// /* The CIC's are configured through the CorePac Interrupt Controller (CpIntc). Plug the
// * CIC INTDST System Interrupt with our Interrupt Service Routine */
// CpIntc_dispatchPlug(intcIntdst, (CpIntc_FuncPtr)myDioTxCompletionIsr, (UArg)hDrvManagedSrioDrv, TRUE);
//
// /* The INTDST's are System Interrupts, these need to be mapped to Host Interrupts, which are
// * linked to CorePac Event ID's. CorePac Event ID 92 is mapped according to this formula:
// * CIC0_OUT(CoreNum * 8 + 4) for core's 0 - 3
// * CIC1_OUT((CoreNum-4) * 8 + 4) for core's 4 - 7
// *
// * Compute the Host Interrupt number based on the coreNum */
// if(coreNum < 4) {
// hostInt = coreNum * 8 + 4;
// } else {
// hostInt = (coreNum - 4) * 8 + 4;
// }
//
// /* Map the INTDST System Interrupt to the Host Interrupt */
// CpIntc_mapSysIntToHostInt(cic, intcIntdst, hostInt);
//
// /* Enable Host Interrupt */
// CpIntc_enableHostInt(cic, hostInt);
//
// /* Enable System Interrupt */
// CpIntc_enableSysInt(cic, intcIntdst);
//
// /* Get the CorePac event number for the Host Interrupt. This should always return 92 */
// eventId = CpIntc_getEventId(hostInt);
//
// /* Setup the HW Interrupt Parameters */
// Hwi_Params_init(&hwiParams);
// hwiParams.arg = hostInt; /* Interrupts don't seem to work without arg set to hostInt */
// hwiParams.eventId = eventId;
// hwiParams.enableInt = TRUE;
//
// /* Configure interrupt 5 to invoke the interrupt. Because we had to map
// * the interrupt through the CpIntc, we need to route this interrupt through
// * the CpIntc dispatcher, which will map it to our ISR plug. This call
// * will automatically enable the interrupt */
// Hwi_create(5, &CpIntc_dispatch, &hwiParams, &eb);
//
// /*
// * Check the error code to make sure the interrupt handler was created
// */
// if (Error_check(&eb)) {
// System_printf("Error creating Doorbell ISR\n");
// }
/*****************************************************************
* Create the Sockets *
*****************************************************************/
/* Open DIO SRIO Non-Blocking Socket */
srioSocket = Srio_sockOpen (hDrvManagedSrioDrv, Srio_SocketType_DIO, FALSE);
if (srioSocket == NULL)
{
System_printf ("Error: Unable to open the DIO socket\n");
return -1;
}
/* DIO Binding Information: Use 8 bit identifiers and we are bound to the first source id.
* and we are using 8 bit device identifiers. */
bindInfo.dio.doorbellValid = 1;
bindInfo.dio.intrRequest = 0;
bindInfo.dio.supInt = 0;
bindInfo.dio.xambs = 0;
bindInfo.dio.priority = 0;
bindInfo.dio.outPortID = 0;
bindInfo.dio.idSize = 1;
bindInfo.dio.srcIDMap = 0;
bindInfo.dio.hopCount = 0;
bindInfo.dio.doorbellReg = coreNum % 4;
bindInfo.dio.doorbellBit = 8 * (coreNum / 4);
/* Bind the SRIO socket: DIO sockets do not need any binding information. */
if (Srio_sockBind_DIO (srioSocket, &bindInfo) < 0)
{
System_printf ("Error: Binding the SIO socket failed.\n");
return -1;
}
return 0;
}
/**
* SRIO Doorbell Send Function
*/
Int32 srio_send_doorbell(uint32_t doorbellRegister, uint32_t doorbellBit) {
Srio_SockAddrInfo to;
uint32_t doorbellInfo;
to.dio.rapidIOMSB = 0x0;
to.dio.rapidIOLSB = 0x0;
to.dio.dstID = LOCAL_BUS_DEVICE_ID;
to.dio.ttype = Srio_Ttype_Doorbell_DEFAULT;
to.dio.ftype = Srio_Ftype_DOORBELL;
doorbellInfo = SRIO_SET_DBELL_INFO(doorbellRegister, doorbellBit);
if (Srio_sockSend(srioSocket, (Srio_DrvBuffer)doorbellInfo, 0, &to) < 0) {
System_printf ("Debug(Core %d): Doorbell Send Failed\n", coreNum);
return -1;
}
return 0;
}
/**
* SRIO Transfer Function
*/
Int32 srio_transfer(uint32_t destination, uint8_t dioFtype, uint8_t dioTtype, uint32_t hwRegAddress, uint32_t dspRegAddress, uint32_t numRegisters, uint32_t waitForCompletion) {
Srio_SockAddrInfo to;
int32_t startTime;
/* Populate the DIO Address Information where the data is to be sent. */
to.dio.rapidIOMSB = 0x0;
to.dio.rapidIOLSB = hwRegAddress;
to.dio.dstID = destination;
to.dio.ttype = dioTtype;
to.dio.ftype = dioFtype;
if (waitForCompletion) {
srioLsuIsrServiced = 0;
}
/* Send the DIO Information. */
if (Srio_sockSend_DIO (srioSocket, (Srio_DrvBuffer)dspRegAddress, numRegisters*4, (Srio_SockAddrInfo*)&to) < 0)
{
System_printf ("Debug(Core %d): Socket Send Failed\n", coreNum);
return -1;
}
if(waitForCompletion) {
/* Wait for the interrupt to occur without touching the peripheral. */
/* Other useful work could be done here such as by invoking a scheduler */
startTime = TSCL;
while((! srioLsuIsrServiced) && ((TSCL - startTime) < SRIO_DIO_LSU_ISR_TIMEOUT));
if (! srioLsuIsrServiced) {
System_printf ("ISR didn't happen within set time - %d cycles. Example failed !!!\n", SRIO_DIO_LSU_ISR_TIMEOUT);
return -1;
}
}
return 0;
}
/**
* Function to read data over SRIO
*/
Int32 srio_read_regs(uint32_t* hw_reg_address, uint32_t* dest_reg_address, uint32_t numRegisters) {
Uint32 global_hw_reg_address = l2_global_address((Uint32)hw_reg_address);
//Uint32 global_hw_reg_address = (Uint32)hw_reg_address;
Uint32 global_dest_reg_address = l2_global_address((Uint32)dest_reg_address);
/* Transfer the data over the socket that generates an interrupt */
return srio_transfer(
FPGA_DDR_DEVICE_ID,
Srio_Ftype_REQUEST,
Srio_Ttype_Request_NREAD,
global_hw_reg_address,
global_dest_reg_address,
numRegisters,
1);
}
/**
* Function to write data over SRIO
*/
Int32 srio_write_regs(uint32_t* hw_reg_address, uint32_t* source_reg_address, uint32_t numRegisters) {
Uint32 global_hw_reg_address = l2_global_address((Uint32)hw_reg_address);
//Uint32 global_hw_reg_address = (Uint32)hw_reg_address;
Uint32 global_source_reg_address = l2_global_address((Uint32)source_reg_address);
/* Transfer the data over the socket that does not generate an interrupt */
return srio_transfer(
FPGA_DDR_DEVICE_ID,
Srio_Ftype_WRITE,
Srio_Ttype_Write_NWRITE_R,
global_hw_reg_address,
global_source_reg_address,
numRegisters,
0);
}
/**
* Function to initialize SRIO
*/
void srio_setup() {
/* Get the core number. */
coreNum = CSL_chipReadReg (CSL_CHIP_DNUM);
System_printf ("Initializing SRIO DEVICE\n");
/* Initialize the system only if the core was configured to do so. */
if (coreNum == CORE_SYS_INIT)
{
System_printf ("Debug(Core %d): System Initialization for CPPI & QMSS\n", coreNum);
/* System Initialization */
if (system_init() < 0)
return;
/* Power on SRIO peripheral before using it */
if (enable_srio () < 0)
{
System_printf ("Error: SRIO PSC Initialization Failed\n");
return;
}
/* Device Specific SRIO Initializations: This should always be called before
initializing the SRIO Driver.*/
if (SrioDevice_init() < 0)
return;
/* Initialize the SRIO Driver */
if (Srio_init () < 0)
{
System_printf ("Error: SRIO Driver Initialization Failed\n");
return;
}
/* SRIO Driver is operational at this time. */
System_printf ("Debug(Core %d): SRIO Driver has been initialized\n", coreNum);
/* Write to the SHARED memory location at this point in time. The other cores cannot execute
* till the SRIO Driver is up and running. */
isSRIOInitialized[0] = 1;
/* The SRIO IP block has been initialized. We need to writeback the cache here because it will
* ensure that the rest of the cores which are waiting for SRIO to be initialized would now be
* woken up. */
CACHE_wbL1d ((Uint32 *) &isSRIOInitialized[0], 128, CACHE_WAIT);
}
else
{
/* All other cores need to wait for the SRIO to be initialized before they proceed. */
System_printf ("Debug(Core %d): Waiting for SRIO to be initialized.\n", coreNum);
/* All other cores loop around forever till the SRIO is up and running.
* We need to invalidate the cache so that we always read this from the memory. */
while (isSRIOInitialized[0] == 0 )
CACHE_invL1d ((Uint32 *) &isSRIOInitialized[0], 128, CACHE_WAIT);
/* Start the QMSS. */
if (Qmss_start() != QMSS_SOK)
{
System_printf ("Error: Unable to start the QMSS\n");
return;
}
System_printf ("Debug(Core %d): SRIO can now be used.\n", coreNum);
}
create_srio_sockets();
}
/**
* @file device_srio.c
*
* @brief
* The 6608 SRIO Device specific code. The SRIO driver calls out
* this code to initialize the SRIO IP block. The file is provided as
* a sample configuration and should be modified by customers for
* their own platforms and configurations.
*
* \par
* NOTE:
* (C) Copyright 2010 Texas Instruments, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* \par
*/
/* SRIO Driver Includes. */
#include <ti/drv/srio/srio_types.h>
#include <ti/drv/srio/include/listlib.h>
#include <ti/drv/srio/srio_drv.h>
/* CSL SRIO Functional Layer */
#include <ti/csl/csl_srio.h>
#include <ti/csl/csl_srioAux.h>
#include <ti/csl/csl_srioAuxPhyLayer.h>
/* CSL BootCfg Module */
#include <ti/csl/csl_bootcfg.h>
#include <ti/csl/csl_bootcfgAux.h>
/* CSL Chip Functional Layer */
#include <ti/csl/csl_chip.h>
/* CSL PSC Module */
#include <ti/csl/csl_pscAux.h>
/* QMSS Include */
#include <ti/drv/qmss/qmss_drv.h>
/**********************************************************************
************************* LOCAL Definitions **************************
**********************************************************************/
/* These are the GARBAGE queues which are used by the TXU to dump the
* descriptor if there is an error instead of recycling the descriptor
* to the free queue. */
#define GARBAGE_LEN_QUEUE 905
#define GARBAGE_TOUT_QUEUE 906
#define GARBAGE_RETRY_QUEUE 907
#define GARBAGE_TRANS_ERR_QUEUE 908
#define GARBAGE_PROG_QUEUE 909
#define GARBAGE_SSIZE_QUEUE 910
/* SRIO Device Information
* - 16 bit Device Identifier.
* - 8 bit Device Identifier.
* - Vendor Identifier.
* - Device Revision. */
#define DEVICE_VENDOR_ID 0x30
#define DEVICE_REVISION 0x0
/* SRIO Assembly Information
* - Assembly Identifier
* - Assembly Vendor Identifier.
* - Assembly Device Revision.
* - Assembly Extension Features */
#define DEVICE_ASSEMBLY_ID 0x0
#define DEVICE_ASSEMBLY_VENDOR_ID 0x30
#define DEVICE_ASSEMBLY_REVISION 0x0
#define DEVICE_ASSEMBLY_INFO 0x0100
/**********************************************************************
************************* Extern Definitions *************************
**********************************************************************/
extern const uint32_t DEVICE_ID1_16BIT;
extern const uint32_t DEVICE_ID1_8BIT;
extern const uint32_t DEVICE_ID2_16BIT;
extern const uint32_t DEVICE_ID2_8BIT;
extern const uint32_t DEVICE_ID3_16BIT;
extern const uint32_t DEVICE_ID3_8BIT_ID;
extern const uint32_t DEVICE_ID4_16BIT;
extern const uint32_t DEVICE_ID4_8BIT_ID;
/**********************************************************************
*********************** DEVICE SRIO FUNCTIONS ***********************
**********************************************************************/
/** @addtogroup SRIO_DEVICE_API
@{ */
/**
* @b Description
* @n
* The function provides the initialization sequence for the SRIO IP
* block. This can be modified by customers for their application and
* configuration.
*
* @retval
* Success - 0
* @retval
* Error - <0
*/
#pragma CODE_SECTION(SrioDevice_init, ".text:SrioDevice_init");
int32_t SrioDevice_init (void)
{
CSL_SrioHandle hSrio;
int32_t i;
SRIO_PE_FEATURES peFeatures;
SRIO_OP_CAR opCar;
Qmss_QueueHnd queueHnd;
uint8_t isAllocated;
uint32_t gargbageQueue[] = { GARBAGE_LEN_QUEUE, GARBAGE_TOUT_QUEUE,
GARBAGE_RETRY_QUEUE,GARBAGE_TRANS_ERR_QUEUE,
GARBAGE_PROG_QUEUE, GARBAGE_SSIZE_QUEUE };
/* Get the CSL SRIO Handle. */
hSrio = CSL_SRIO_Open (0);
if (hSrio == NULL)
return -1;
/* Code to disable SRIO reset isolation */
if (CSL_PSC_isModuleResetIsolationEnabled(CSL_PSC_LPSC_SRIO))
CSL_PSC_disableModuleResetIsolation(CSL_PSC_LPSC_SRIO);
/* Disable the SRIO Global block */
CSL_SRIO_GlobalDisable (hSrio);
/* Disable each of the individual SRIO blocks. */
for(i = 0; i <= 9; i++)
CSL_SRIO_DisableBlock(hSrio, i);
/* Set boot complete to be 0; we are not done with the initialization. */
CSL_SRIO_SetBootComplete(hSrio, 0);
/* Now enable the SRIO block and all the individual blocks also. */
CSL_SRIO_GlobalEnable (hSrio);
for(i = 0; i <= 9; i++)
CSL_SRIO_EnableBlock(hSrio,i);
/* Configure SRIO ports to operate in loopback mode. */
//CSL_SRIO_SetLoopbackMode(hSrio, 0);
//CSL_SRIO_SetLoopbackMode(hSrio, 1);
//CSL_SRIO_SetLoopbackMode(hSrio, 2);
//CSL_SRIO_SetLoopbackMode(hSrio, 3);
/* Enable Automatic Priority Promotion of response packets. */
CSL_SRIO_EnableAutomaticPriorityPromotion(hSrio);
/* Set the SRIO Prescalar select to operate in the range of 44.7 to 89.5 */
CSL_SRIO_SetPrescalarSelect (hSrio, 0);
/* Unlock the Boot Configuration Kicker */
CSL_BootCfgUnlockKicker ();
/* Assuming the link rate is 312.5; program the PLL accordingly. */
CSL_BootCfgSetSRIOSERDESConfigPLL (0x241);
/* Configure the SRIO SERDES Receive Configuration. */
//CSL_BootCfgSetSRIOSERDESRxConfig (0, 0x00440495);
//CSL_BootCfgSetSRIOSERDESRxConfig (1, 0x00440495);
//CSL_BootCfgSetSRIOSERDESRxConfig (2, 0x00440495);
//CSL_BootCfgSetSRIOSERDESRxConfig (3, 0x00440495);
/* Configure the SRIO SERDES Transmit Configuration. */
//CSL_BootCfgSetSRIOSERDESTxConfig (0, 0x00180795);
//CSL_BootCfgSetSRIOSERDESTxConfig (1, 0x00180795);
//CSL_BootCfgSetSRIOSERDESTxConfig (2, 0x00180795);
//CSL_BootCfgSetSRIOSERDESTxConfig (3, 0x00180795);
/*1 lane at 1/4 speed*/
/* Configure the SRIO SERDES Receive Configuration. */
CSL_BootCfgSetSRIOSERDESRxConfig (0, 0x004404B5);
/* Configure the SRIO SERDES Transmit Configuration. */
CSL_BootCfgSetSRIOSERDESTxConfig (0, 0x001807B5);
#ifndef SIMULATOR_SUPPORT
/* Loop around till the SERDES PLL is not locked. */
while (1)
{
uint32_t status;
/* Get the SRIO SERDES Status */
CSL_BootCfgGetSRIOSERDESStatus(&status);
if (status & 0x1)
break;
}
#endif
/* Clear the LSU pending interrupts. */
CSL_SRIO_ClearLSUPendingInterrupt (hSrio, 0xFFFFFFFF, 0xFFFFFFFF);
/* Clear the doorbell pending interrupts */
for(i = 0; i < 4; i++)
CSL_SRIO_ClearDoorbellPendingInterrupt(hSrio, i, 0xFFFF);
/* Set the Device Information */
CSL_SRIO_SetDeviceInfo (hSrio, DEVICE_ID1_16BIT, DEVICE_VENDOR_ID, DEVICE_REVISION);
/* Set the Assembly Information */
CSL_SRIO_SetAssemblyInfo(hSrio, DEVICE_ASSEMBLY_ID, DEVICE_ASSEMBLY_VENDOR_ID,
DEVICE_ASSEMBLY_REVISION, DEVICE_ASSEMBLY_INFO);
/* TODO: Configure the processing element features
* The SRIO RL file is missing the Re-transmit Suppression Support (Bit6) field definition */
peFeatures.isBridge = 0;
peFeatures.isEndpoint = 0;
peFeatures.isProcessor = 1;
peFeatures.isSwitch = 0;
peFeatures.isMultiport = 0;
peFeatures.isFlowArbiterationSupported = 0;
peFeatures.isMulticastSupported = 0;
peFeatures.isExtendedRouteConfigSupported = 0;
peFeatures.isStandardRouteConfigSupported = 1;
peFeatures.isFlowControlSupported = 1;
peFeatures.isCRFSupported = 0;
peFeatures.isCTLSSupported = 1;
peFeatures.isExtendedFeaturePtrValid = 1;
peFeatures.numAddressBitSupported = 1;
CSL_SRIO_SetProcessingElementFeatures (hSrio, &peFeatures);
/* Configure the source operation CAR */
memset ((void *) &opCar, 0, sizeof (opCar));
opCar.portWriteOperationSupport = 1;
opCar.atomicClearSupport = 1;
opCar.atomicSetSupport = 1;
opCar.atomicDecSupport = 1;
opCar.atomicIncSupport = 1;
opCar.atomicTestSwapSupport = 1;
opCar.doorbellSupport = 1;
opCar.dataMessageSupport = 1;
opCar.writeResponseSupport = 1;
opCar.streamWriteSupport = 1;
opCar.writeSupport = 1;
opCar.readSupport = 1;
opCar.dataStreamingSupport = 1;
CSL_SRIO_SetSourceOperationCAR (hSrio, &opCar);
/* Configure the destination operation CAR */
memset ((void *) &opCar, 0, sizeof (opCar));
opCar.portWriteOperationSupport = 1;
opCar.doorbellSupport = 1;
opCar.dataMessageSupport = 1;
opCar.writeResponseSupport = 1;
opCar.streamWriteSupport = 1;
opCar.writeSupport = 1;
opCar.readSupport = 1;
CSL_SRIO_SetDestOperationCAR (hSrio, &opCar);
/* Set the 16 bit and 8 bit identifier for the SRIO Device. */
CSL_SRIO_SetDeviceIDCSR (hSrio, DEVICE_ID1_8BIT, DEVICE_ID1_16BIT);
/* Enable TLM Base Routing Information for Maintainance Requests & ensure that
* the BRR's can be used by all the ports. */
/* Note: Port 0, BRR 0 is enabled by default, so it doesn't need to
* be set up specifically like all the other Port/BRR combinations */
CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 0, 1, 1, 1, 0);
CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 0, 2, 1, 1, 0);
CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 0, 3, 1, 1, 0);
CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 1, 0, 1, 1, 0);
CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 1, 1, 1, 1, 0);
CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 1, 2, 1, 1, 0);
CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 1, 3, 1, 1, 0);
CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 2, 0, 1, 1, 0);
CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 2, 1, 1, 1, 0);
CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 2, 2, 1, 1, 0);
CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 2, 3, 1, 1, 0);
CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 3, 0, 1, 1, 0);
CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 3, 1, 1, 1, 0);
CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 3, 2, 1, 1, 0);
CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 3, 3, 1, 1, 0);
/* Configure the Base Routing Register to ensure that all packets matching the
* Device Identifier & the Secondary Device Id are admitted. */
CSL_SRIO_SetTLMPortBaseRoutingPatternMatch(hSrio, 0, 1, DEVICE_ID1_16BIT, 0xFFFF);
//CSL_SRIO_SetTLMPortBaseRoutingPatternMatch(hSrio, 0, 2, DEVICE_ID3_16BIT, 0xFFFF);
//CSL_SRIO_SetTLMPortBaseRoutingPatternMatch(hSrio, 0, 3, DEVICE_ID4_16BIT, 0xFFFF);
//CSL_SRIO_SetTLMPortBaseRoutingPatternMatch(hSrio, 1, 0, DEVICE_ID1_8BIT, 0xFF);
/* We need to open the Garbage collection queues in the QMSS. This is done to ensure that
* these queues are not opened by another system entity. */
for (i = 0; i < 6; i++)
{
/* Open the Garabage queues */
queueHnd = Qmss_queueOpen (Qmss_QueueType_GENERAL_PURPOSE_QUEUE, gargbageQueue[i], &isAllocated);
if (queueHnd < 0)
return -1;
/* Make sure the queue has not been opened already; we dont the queues to be shared by some other
* entity in the system. */
if (isAllocated > 1)
return -1;
}
/* Set the Transmit Garbage Collection Information. */
CSL_SRIO_SetTxGarbageCollectionInfo (hSrio, GARBAGE_LEN_QUEUE, GARBAGE_TOUT_QUEUE,
GARBAGE_RETRY_QUEUE, GARBAGE_TRANS_ERR_QUEUE,
GARBAGE_PROG_QUEUE, GARBAGE_SSIZE_QUEUE);
/* Set the Host Device Identifier. */
CSL_SRIO_SetHostDeviceID (hSrio, DEVICE_ID1_16BIT);
/* Configure the component tag CSR */
CSL_SRIO_SetCompTagCSR (hSrio, 0x00000000);
/* Configure the PLM for all the ports. */
for (i = 0; i < 4; i++)
{
/* Set the PLM Port Silence Timer. */
CSL_SRIO_SetPLMPortSilenceTimer (hSrio, i, 0x2);
/* TODO: We need to ensure that the Port 0 is configured to support both
* the 2x and 4x modes. The Port Width field is read only. So here we simply
* ensure that the Input and Output ports are enabled. */
CSL_SRIO_EnableInputPort (hSrio, i);
CSL_SRIO_EnableOutputPort (hSrio, i);
/* Set the PLM Port Discovery Timer. */
CSL_SRIO_SetPLMPortDiscoveryTimer (hSrio, i, 0x2);
/* Reset the Port Write Reception capture. */
CSL_SRIO_SetPortWriteReceptionCapture(hSrio, i, 0x0);
}
/* Set the Port link timeout CSR */
CSL_SRIO_SetPortLinkTimeoutCSR (hSrio, 0x000FFF);
/* Set the Port General CSR: Only executing as Master Enable */
CSL_SRIO_SetPortGeneralCSR (hSrio, 0, 1, 0);
/* Clear the sticky register bits. */
CSL_SRIO_SetLLMResetControl (hSrio, 1);
/* Set the device id to be 0 for the Maintenance Port-Write operation
* to report errors to a system host. */
CSL_SRIO_SetPortWriteDeviceId (hSrio, 0x0, 0x0, 0x0);
/* Set the Data Streaming MTU */
CSL_SRIO_SetDataStreamingMTU (hSrio, 64);
/* Configure the path mode for the ports. */
for(i = 0; i < 4; i++)
CSL_SRIO_SetPLMPortPathControlMode (hSrio, i, 0);
/* Set the LLM Port IP Prescalar. */
CSL_SRIO_SetLLMPortIPPrescalar (hSrio, 0x21);
/* Enable the peripheral. */
CSL_SRIO_EnablePeripheral(hSrio);
/* Configuration has been completed. */
CSL_SRIO_SetBootComplete(hSrio, 1);
#ifndef SIMULATOR_SUPPORT
/* This code checks if the ports are operational or not. The functionality is not supported
* on the simulator. */
//for(i = 0; i < 4; i++)
// while (CSL_SRIO_IsPortOk (hSrio, i) != TRUE);
// Check to see if Port 0 has a port ok (Testing with 1 Lane)
while (CSL_SRIO_IsPortOk (hSrio, 0) != TRUE);
#endif
/* Set all the queues 0 to operate at the same priority level and to send packets onto Port 0 */
for (i =0 ; i < 16; i++)
CSL_SRIO_SetTxQueueSchedInfo(hSrio, i, 0, 0);
/* Set the Doorbell route to determine which routing table is to be used
* This configuration implies that the Interrupt Routing Table is configured as
* follows:-
* Interrupt Destination 0 - INTDST 16
* Interrupt Destination 1 - INTDST 17
* Interrupt Destination 2 - INTDST 18
* Interrupt Destination 3 - INTDST 19
* Interrupt Destination 4 - INTDST 20
* Interrupt Destination 5 - INTDST 21
* Interrupt Destination 6 - INTDST 22
* Interrupt Destination 7 - INTDST 23
*/
CSL_SRIO_SetDoorbellRoute(hSrio, 0);
/* Route the Doorbell interrupts.
* Doorbell Register 0 - Doorbits 0 - 7 are routed to Interrupt Destination 0
* Doorbits 8 - 15 are routed to Interrupt Destination 4
* Doorbell Register 1 - Doorbits 0 - 7 are routed to Interrupt Destination 1
* Doorbits 8 - 15 are routed to Interrupt Destination 5
* Doorbell Register 2 - Doorbits 0 - 7 are routed to Interrupt Destination 2
* Doorbits 8 - 15 are routed to Interrupt Destination 6
* Doorbell Register 3 - Doorbits 0 - 7 are routed to Interrupt Destination 3
* Doorbits 8 - 15 are routed to Interrupt Destination 7 */
for (i = 0; i < 8; i++)
{
/* SRIO Handle, Doorbell, Doorbit, Interrupt Destination*/
CSL_SRIO_RouteDoorbellInterrupts( hSrio, 0, i, 0);
CSL_SRIO_RouteDoorbellInterrupts( hSrio, 0, i+8, 4);
CSL_SRIO_RouteDoorbellInterrupts( hSrio, 1, i, 1);
CSL_SRIO_RouteDoorbellInterrupts( hSrio, 1, i+8, 5);
CSL_SRIO_RouteDoorbellInterrupts( hSrio, 2, i, 2);
CSL_SRIO_RouteDoorbellInterrupts( hSrio, 2, i+8, 6);
CSL_SRIO_RouteDoorbellInterrupts( hSrio, 3, i, 3);
CSL_SRIO_RouteDoorbellInterrupts( hSrio, 3, i+8, 7);
}
/* Initialization has been completed. */
return 0;
}
/**
@}
*/
