#include // Broadly speaking csl_srio.h contains the CSL Functional Layer which I don't want to use // but I've included it because there are a few useful macros. #include #include "SrioCommon.h" CSL_SrioRegs *const srioRegisters = reinterpret_cast(CSL_SRIO_0_REGS); //#define ONEX_4X_MODE #define ONEX_1X_MODE #if defined(ONEX_4X_MODE) #define SRIO_SET_DEVICE_ID(base_dev_id, large_base_dev_id) \ CSL_FMK(SRIO_BASE_ID_BASE_DEVICEID, base_dev_id) | \ CSL_FMK(SRIO_BASE_ID_LARGE_BASE_DEVICEID, large_base_dev_id) namespace { // This function call generates quite a bit of code and it isn't very easy to control. // I timed it with the high-resolution timer in Release. // What I really want is a solution that generates a very small amount of code and // guarantees a minimum cycle count. #pragma FUNC_CANNOT_INLINE; Void Wait100Cycles() { #pragma MUST_ITERATE(3, 3 , 1); for (volatile Int i = 0; i < 3; ++i) { } } Void EnableSRIOPeripheral() { // See tms320c6455.pdf section 3 // Unlock command and write to Peripheral Configuration Register 0 need to be // within 16 SYSCLK3 cycles. // The SRIO peripheral is available 16 SYSCLK3 cycles after the write to PERCFG0 // (there is no SRIO entry in peripheral status registers). SYSCLK3 is CPU/6 // (see tms320c6455.pdf p.134) therefore 16 SYSCLK3 approximately equals 100 CPU cycles. CSL_DevRegs *const deviceStateControlRegisters = reinterpret_cast(CSL_DEV_REGS); deviceStateControlRegisters->PERLOCK = CSL_FMKT(DEV_PERLOCK_LOCKVAL, UNLOCK); CSL_FINST(deviceStateControlRegisters->PERCFG0, DEV_PERCFG0_SRIOCTL, ENABLE); Wait100Cycles(); } Void ClearCPPIInterrupts(Void) { srioRegisters->TX_CPPI_ICCR = CSL_FMK(SRIO_TX_CPPI_ICCR_ICC0, 1U) | CSL_FMK(SRIO_TX_CPPI_ICCR_ICC1, 1U) | CSL_FMK(SRIO_TX_CPPI_ICCR_ICC2, 1U) | CSL_FMK(SRIO_TX_CPPI_ICCR_ICC3, 1U) | CSL_FMK(SRIO_TX_CPPI_ICCR_ICC4, 1U) | CSL_FMK(SRIO_TX_CPPI_ICCR_ICC5, 1U) | CSL_FMK(SRIO_TX_CPPI_ICCR_ICC6, 1U) | CSL_FMK(SRIO_TX_CPPI_ICCR_ICC7, 1U) | CSL_FMK(SRIO_TX_CPPI_ICCR_ICC8, 1U) | CSL_FMK(SRIO_TX_CPPI_ICCR_ICC9, 1U) | CSL_FMK(SRIO_TX_CPPI_ICCR_ICC10, 1U) | CSL_FMK(SRIO_TX_CPPI_ICCR_ICC11, 1U) | CSL_FMK(SRIO_TX_CPPI_ICCR_ICC12, 1U) | CSL_FMK(SRIO_TX_CPPI_ICCR_ICC13, 1U) | CSL_FMK(SRIO_TX_CPPI_ICCR_ICC14, 1U) | CSL_FMK(SRIO_TX_CPPI_ICCR_ICC15, 1U); srioRegisters->RX_CPPI_ICCR = CSL_FMK(SRIO_RX_CPPI_ICCR_ICC0, 1U) | CSL_FMK(SRIO_RX_CPPI_ICCR_ICC1, 1U) | CSL_FMK(SRIO_RX_CPPI_ICCR_ICC2, 1U) | CSL_FMK(SRIO_RX_CPPI_ICCR_ICC3, 1U) | CSL_FMK(SRIO_RX_CPPI_ICCR_ICC4, 1U) | CSL_FMK(SRIO_RX_CPPI_ICCR_ICC5, 1U) | CSL_FMK(SRIO_RX_CPPI_ICCR_ICC6, 1U) | CSL_FMK(SRIO_RX_CPPI_ICCR_ICC7, 1U) | CSL_FMK(SRIO_RX_CPPI_ICCR_ICC8, 1U) | CSL_FMK(SRIO_RX_CPPI_ICCR_ICC9, 1U) | CSL_FMK(SRIO_RX_CPPI_ICCR_ICC10, 1U) | CSL_FMK(SRIO_RX_CPPI_ICCR_ICC11, 1U) | CSL_FMK(SRIO_RX_CPPI_ICCR_ICC12, 1U) | CSL_FMK(SRIO_RX_CPPI_ICCR_ICC13, 1U) | CSL_FMK(SRIO_RX_CPPI_ICCR_ICC14, 1U) | CSL_FMK(SRIO_RX_CPPI_ICCR_ICC15, 1U); } Void ClearLSUInterrupts(Void) { srioRegisters->LSU_ICCR = CSL_FMK(SRIO_LSU_ICCR_ICC0, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC1, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC2, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC3, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC4, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC5, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC6, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC7, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC8, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC9, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC10, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC11, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC12, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC13, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC14, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC15, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC16, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC17, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC18, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC19, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC20, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC21, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC22, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC23, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC24, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC25, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC26, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC27, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC28, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC29, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC30, 1U) | CSL_FMK(SRIO_LSU_ICCR_ICC31, 1U); } Void ClearDoorbellInterrupts(Void) { const Uint32 clearAllDoorbells = CSL_FMK(SRIO_DOORBELL_ICCR_ICC0, 1U) | CSL_FMK(SRIO_DOORBELL_ICCR_ICC1, 1U) | CSL_FMK(SRIO_DOORBELL_ICCR_ICC2, 1U) | CSL_FMK(SRIO_DOORBELL_ICCR_ICC3, 1U) | CSL_FMK(SRIO_DOORBELL_ICCR_ICC4, 1U) | CSL_FMK(SRIO_DOORBELL_ICCR_ICC5, 1U) | CSL_FMK(SRIO_DOORBELL_ICCR_ICC6, 1U) | CSL_FMK(SRIO_DOORBELL_ICCR_ICC7, 1U) | CSL_FMK(SRIO_DOORBELL_ICCR_ICC8, 1U) | CSL_FMK(SRIO_DOORBELL_ICCR_ICC9, 1U) | CSL_FMK(SRIO_DOORBELL_ICCR_ICC10, 1U) | CSL_FMK(SRIO_DOORBELL_ICCR_ICC11, 1U) | CSL_FMK(SRIO_DOORBELL_ICCR_ICC12, 1U) | CSL_FMK(SRIO_DOORBELL_ICCR_ICC13, 1U) | CSL_FMK(SRIO_DOORBELL_ICCR_ICC14, 1U) | CSL_FMK(SRIO_DOORBELL_ICCR_ICC15, 1U); srioRegisters->DOORBELL_INTR[0].DOORBELL_ICCR = clearAllDoorbells; srioRegisters->DOORBELL_INTR[1].DOORBELL_ICCR = clearAllDoorbells; srioRegisters->DOORBELL_INTR[2].DOORBELL_ICCR = clearAllDoorbells; srioRegisters->DOORBELL_INTR[3].DOORBELL_ICCR = clearAllDoorbells; } Void ClearErrorInterruprs(Void) { const Uint32 clearAll = CSL_FMK(SRIO_ERR_RST_EVNT_ICCR_ICC0, 1U) | CSL_FMK(SRIO_ERR_RST_EVNT_ICCR_ICC1, 1U) | CSL_FMK(SRIO_ERR_RST_EVNT_ICCR_ICC2, 1U) | CSL_FMK(SRIO_ERR_RST_EVNT_ICCR_ICC8, 1U) | CSL_FMK(SRIO_ERR_RST_EVNT_ICCR_ICC9, 1U) | CSL_FMK(SRIO_ERR_RST_EVNT_ICCR_ICC10, 1U) | CSL_FMK(SRIO_ERR_RST_EVNT_ICCR_ICC11, 1U) | CSL_FMK(SRIO_ERR_RST_EVNT_ICCR_ICC16, 1U); srioRegisters->ERR_RST_EVNT_ICCR = clearAll; } Void ClearAllSrioInterrupts(Void) { ClearCPPIInterrupts(); ClearLSUInterrupts(); ClearDoorbellInterrupts(); ClearErrorInterruprs(); } Void DisableAllSrioInterruptRouting(Void) { srioRegisters->TX_CPPI_ICRR = CSL_FMK(SRIO_TX_CPPI_ICRR_ICR0, 0xFFU) | CSL_FMK(SRIO_TX_CPPI_ICRR_ICR1, 0xFFU) | CSL_FMK(SRIO_TX_CPPI_ICRR_ICR2, 0xFFU) | CSL_FMK(SRIO_TX_CPPI_ICRR_ICR3, 0xFFU) | CSL_FMK(SRIO_TX_CPPI_ICRR_ICR4, 0xFFU) | CSL_FMK(SRIO_TX_CPPI_ICRR_ICR5, 0xFFU) | CSL_FMK(SRIO_TX_CPPI_ICRR_ICR6, 0xFFU) | CSL_FMK(SRIO_TX_CPPI_ICRR_ICR7, 0xFFU); srioRegisters->TX_CPPI_ICRR2 = CSL_FMK(SRIO_TX_CPPI_ICRR2_ICR0, 0xFFU) | CSL_FMK(SRIO_TX_CPPI_ICRR2_ICR1, 0xFFU) | CSL_FMK(SRIO_TX_CPPI_ICRR2_ICR2, 0xFFU) | CSL_FMK(SRIO_TX_CPPI_ICRR2_ICR3, 0xFFU) | CSL_FMK(SRIO_TX_CPPI_ICRR2_ICR4, 0xFFU) | CSL_FMK(SRIO_TX_CPPI_ICRR2_ICR5, 0xFFU) | CSL_FMK(SRIO_TX_CPPI_ICRR2_ICR6, 0xFFU) | CSL_FMK(SRIO_TX_CPPI_ICRR2_ICR7, 0xFFU); srioRegisters->RX_CPPI_ICRR = CSL_FMK(SRIO_RX_CPPI_ICRR_ICR0, 0xFFU) | CSL_FMK(SRIO_RX_CPPI_ICRR_ICR1, 0xFFU) | CSL_FMK(SRIO_RX_CPPI_ICRR_ICR2, 0xFFU) | CSL_FMK(SRIO_RX_CPPI_ICRR_ICR3, 0xFFU) | CSL_FMK(SRIO_RX_CPPI_ICRR_ICR4, 0xFFU) | CSL_FMK(SRIO_RX_CPPI_ICRR_ICR5, 0xFFU) | CSL_FMK(SRIO_RX_CPPI_ICRR_ICR6, 0xFFU) | CSL_FMK(SRIO_RX_CPPI_ICRR_ICR7, 0xFFU); srioRegisters->RX_CPPI_ICRR2 = CSL_FMK(SRIO_RX_CPPI_ICRR2_ICR0, 0xFFU) | CSL_FMK(SRIO_RX_CPPI_ICRR2_ICR1, 0xFFU) | CSL_FMK(SRIO_RX_CPPI_ICRR2_ICR2, 0xFFU) | CSL_FMK(SRIO_RX_CPPI_ICRR2_ICR3, 0xFFU) | CSL_FMK(SRIO_RX_CPPI_ICRR2_ICR4, 0xFFU) | CSL_FMK(SRIO_RX_CPPI_ICRR2_ICR5, 0xFFU) | CSL_FMK(SRIO_RX_CPPI_ICRR2_ICR6, 0xFFU) | CSL_FMK(SRIO_RX_CPPI_ICRR2_ICR7, 0xFFU); srioRegisters->LSU_ICRR[0] = CSL_FMK(SRIO_LSU_ICRR_ICR0, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR1, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR2, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR3, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR4, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR5, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR6, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR7, 0xFFU); // CSL V03.00.10.02 doesn't have macros for all 4 ICRRs. srioRegisters->LSU_ICRR[1] = CSL_FMK(SRIO_LSU_ICRR_ICR0, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR1, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR2, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR3, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR4, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR5, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR6, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR7, 0xFFU); srioRegisters->LSU_ICRR[2] = CSL_FMK(SRIO_LSU_ICRR_ICR0, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR1, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR2, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR3, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR4, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR5, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR6, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR7, 0xFFU); srioRegisters->LSU_ICRR[3] = CSL_FMK(SRIO_LSU_ICRR_ICR0, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR1, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR2, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR3, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR4, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR5, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR6, 0xFFU) | CSL_FMK(SRIO_LSU_ICRR_ICR7, 0xFFU); } Void ResetSrioInterrupts(Void) { ClearAllSrioInterrupts(); DisableAllSrioInterruptRouting(); } Void ResetMapping(Void) { // Single segment messages, mailbox 0 and letter 0 are mapped to queue 0 if the source is 0x0000. // In other words most messages should be rejected. const Int numberOfMappers = 32; // spru976b.pdf section 5.49 Int i; for (i = 0; i < numberOfMappers; i++) { srioRegisters->MAP[i].RXU_MAP_L = CSL_FMKT(SRIO_RXU_MAP_L_LETTER_MASK, RESETVAL) | CSL_FMKT(SRIO_RXU_MAP_L_MAILBOX_MASK, RESETVAL) | CSL_FMKT(SRIO_RXU_MAP_L_LETTER, RESETVAL) | CSL_FMKT(SRIO_RXU_MAP_L_MAILBOX, RESETVAL) | CSL_FMKT(SRIO_RXU_MAP_L_SOURCEID, RESETVAL); srioRegisters->MAP[i].RXU_MAP_H = CSL_FMKT(SRIO_RXU_MAP_H_TT, RESETVAL) | CSL_FMKT(SRIO_RXU_MAP_H_QUEUE_ID, RESETVAL) | CSL_FMKT(SRIO_RXU_MAP_H_PROMISCUOUS, RESETVAL) | CSL_FMKT(SRIO_RXU_MAP_H_SEGMENT_MAPPING, RESETVAL); } } Void ResetMessageRxQueues(Void) { Int i; for (i = 0; i < numberOfQueues; i++) { srioRegisters->QUEUE_RXDMA_HDP[i] = 0; } } Void EnableAllBlocks() { for (Int i = 0; i < CSL_SRIO_BLOCKS_MAX; ++i) { srioRegisters->BLK_ENABLE[i].BLK_EN = CSL_FMKT(SRIO_BLK_EN_EN, ENABLE); } } Void SetPeripheralControlRegister() { srioRegisters->PER_SET_CNTL = CSL_FMKT(SRIO_PER_SET_CNTL_SW_MEM_SLEEP_OVERRIDE, ENABLE) | CSL_FMKT(SRIO_PER_SET_CNTL_LOOPBACK, NORMAL) | CSL_FMKT(SRIO_PER_SET_CNTL_BOOT_COMPLETE, WRITE_DISABLE) | CSL_FMK(SRIO_PER_SET_CNTL_TX_PRI2_WM, 0) | CSL_FMK(SRIO_PER_SET_CNTL_TX_PRI1_WM, 0) | CSL_FMK(SRIO_PER_SET_CNTL_TX_PRI0_WM, 0) | CSL_FMK(SRIO_PER_SET_CNTL_CBA_TRANS_PRI, 1) | CSL_FMKT(SRIO_PER_SET_CNTL_1X_MODE, DISABLE) | CSL_FMKT(SRIO_PER_SET_CNTL_PRESCALER_SELECT, 6); } Void SetDeviceIds(const Uint16 largeDeviceId, const Uint8 smallDeviceId) { srioRegisters->DEVICEID_REG1 = SRIO_SET_DEVICE_ID(smallDeviceId, largeDeviceId); // This is for multi-cast so all DSPs have the same(?) srioRegisters->DEVICEID_REG2 = SRIO_SET_DEVICE_ID(0xDE, 0xABCD); } Void SetHardwarePacketForwarding() { for (Int i = 0; i < CSL_SRIO_PORTS_MAX; ++i) { CSL_FINS(srioRegisters->HW_PKT_FWD[i].PF_16BIT_CNTL, SRIO_PF_16BIT_CNTL_16BIT_DEVID_UP_BOUND, 0xFFFFu); CSL_FINS(srioRegisters->HW_PKT_FWD[i].PF_16BIT_CNTL, SRIO_PF_16BIT_CNTL_16BIT_DEVID_LOW_BOUND, 0xFFFFu); CSL_FINS(srioRegisters->HW_PKT_FWD[i].PF_8BIT_CNTL, SRIO_PF_8BIT_CNTL_OUT_BOUND_PORT, CSL_SRIO_PORT_3); CSL_FINS(srioRegisters->HW_PKT_FWD[i].PF_8BIT_CNTL, SRIO_PF_8BIT_CNTL_8BIT_DEVID_UP_BOUND, 0xFF); CSL_FINS(srioRegisters->HW_PKT_FWD[i].PF_8BIT_CNTL, SRIO_PF_8BIT_CNTL_8BIT_DEVID_LOW_BOUND, 0xFF); } } Void SetSERDES0MacroConfiguration() { srioRegisters->SERDES_CFG_CNTL[0] = CSL_FMKT(SRIO_SERDES_CFG_CNTL_LB, FREQ_DEP) | CSL_FMKT(SRIO_SERDES_CFG_CNTL_MPY, 12_5) | CSL_FMKT(SRIO_SERDES_CFG_CNTL_ENPLL, ENABLE); } Void SetUnusedSERDESMacroConfiguration() { // See spru976b.pdf Table 63 srioRegisters->SERDES_CFG_CNTL[1] = 0x0; srioRegisters->SERDES_CFG_CNTL[2] = 0x0; srioRegisters->SERDES_CFG_CNTL[3] = 0x0; } Void SetSERDESMacroConfiguration() { SetSERDES0MacroConfiguration(); SetUnusedSERDESMacroConfiguration(); } Void SetSERDESRxConfiguration() { srioRegisters->SERDES_CFGRX_CNTL[0] = CSL_FMK(SRIO_SERDES_CFGRX_CNTL_EQ, 0x01) | CSL_FMK(SRIO_SERDES_CFGRX_CNTL_CDR, 0x00) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_LOS, DISABLED) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_ALIGN, COMMA) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_TERM, VDDT) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_INVPAIR, NORMAL) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_RATE, FULL) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_BUSWIDTH, 10BIT) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_ENRX, ENABLE); srioRegisters->SERDES_CFGRX_CNTL[1] = CSL_FMK(SRIO_SERDES_CFGRX_CNTL_EQ, 0x01) | CSL_FMK(SRIO_SERDES_CFGRX_CNTL_CDR, 0x00) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_LOS, DISABLED) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_ALIGN, COMMA) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_TERM, VDDT) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_INVPAIR, NORMAL) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_RATE, FULL) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_BUSWIDTH, 10BIT) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_ENRX, ENABLE); srioRegisters->SERDES_CFGRX_CNTL[2] = CSL_FMK(SRIO_SERDES_CFGRX_CNTL_EQ, 0x01) | CSL_FMK(SRIO_SERDES_CFGRX_CNTL_CDR, 0x00) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_LOS, DISABLED) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_ALIGN, COMMA) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_TERM, VDDT) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_INVPAIR, NORMAL) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_RATE, FULL) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_BUSWIDTH, 10BIT) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_ENRX, ENABLE); srioRegisters->SERDES_CFGRX_CNTL[3] = CSL_FMK(SRIO_SERDES_CFGRX_CNTL_EQ, 0x01) | CSL_FMK(SRIO_SERDES_CFGRX_CNTL_CDR, 0x00) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_LOS, DISABLED) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_ALIGN, COMMA) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_TERM, VDDT) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_INVPAIR, NORMAL) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_RATE, FULL) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_BUSWIDTH, 10BIT) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_ENRX, ENABLE); } Void SetSERDESTxConfiguration() { srioRegisters->SERDES_CFGTX_CNTL[0] = CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_ENFTP, FIXED) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_DE, RESETVAL) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_SWING, 1000) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_CM, RAISED) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_INVPAIR, NORMAL) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_RATE, FULL) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_BUSWIDTH, 10BIT) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_ENTX, ENABLE); srioRegisters->SERDES_CFGTX_CNTL[1] = CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_ENFTP, FIXED) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_DE, RESETVAL) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_SWING, 1000) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_CM, RAISED) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_INVPAIR, NORMAL) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_RATE, FULL) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_BUSWIDTH, 10BIT) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_ENTX, ENABLE); srioRegisters->SERDES_CFGTX_CNTL[2] = CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_ENFTP, FIXED) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_DE, RESETVAL) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_SWING, 1000) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_CM, RAISED) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_INVPAIR, NORMAL) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_RATE, FULL) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_BUSWIDTH, 10BIT) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_ENTX, ENABLE); srioRegisters->SERDES_CFGTX_CNTL[3] = CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_ENFTP, FIXED) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_DE, RESETVAL) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_SWING, 1000) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_CM, RAISED) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_INVPAIR, NORMAL) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_RATE, FULL) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_BUSWIDTH, 10BIT) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_ENTX, ENABLE); } Void SetSERDESConfiguration() { SetSERDESMacroConfiguration(); SetSERDESRxConfiguration(); SetSERDESTxConfiguration(); } Void SetFlowControl(const Uint16 largeDeviceId) { for (Int i = 0; i < CSL_SRIO_FLOW_CONTROL_REG_MAX; ++i) { CSL_FINS(srioRegisters->FLOW_CNTL[i], SRIO_FLOW_CNTL_TT, 0x1); CSL_FINS(srioRegisters->FLOW_CNTL[i], SRIO_FLOW_CNTL_FLOW_CNTL_ID, 0x0000); } CSL_FINS(srioRegisters->FLOW_CNTL[0], SRIO_FLOW_CNTL_FLOW_CNTL_ID, largeDeviceId); } Void SetPortControl() { srioRegisters->PORT[0].SP_CTL = CSL_FMKT(SRIO_SP_CTL_PORT_WIDTH, RESETVAL) | CSL_FMKT(SRIO_SP_CTL_INITIALIZED_PORT_WIDTH, RESETVAL) | CSL_FMKT(SRIO_SP_CTL_PORT_WIDTH_OVERRIDE, NO_OVERRIDE) | CSL_FMK(SRIO_SP_CTL_PORT_DISABLE, 0) | CSL_FMK(SRIO_SP_CTL_OUTPUT_PORT_ENABLE, 1) | CSL_FMK(SRIO_SP_CTL_INPUT_PORT_ENABLE, 1) | CSL_FMK(SRIO_SP_CTL_STOP_PORT_FLD_ENC_ENABLE, 1) | CSL_FMK(SRIO_SP_CTL_DROP_PACKET_ENABLE, 1) | CSL_FMK(SRIO_SP_CTL_PORT_LOCKOUT, 0); srioRegisters->PORT[1].SP_CTL = CSL_FMKT(SRIO_SP_CTL_PORT_WIDTH, RESETVAL) | CSL_FMKT(SRIO_SP_CTL_INITIALIZED_PORT_WIDTH, RESETVAL) | CSL_FMKT(SRIO_SP_CTL_PORT_WIDTH_OVERRIDE, NO_OVERRIDE) | CSL_FMK(SRIO_SP_CTL_PORT_DISABLE, 1) | CSL_FMK(SRIO_SP_CTL_OUTPUT_PORT_ENABLE, 0) | CSL_FMK(SRIO_SP_CTL_INPUT_PORT_ENABLE, 0) | CSL_FMK(SRIO_SP_CTL_STOP_PORT_FLD_ENC_ENABLE, 1) | CSL_FMK(SRIO_SP_CTL_DROP_PACKET_ENABLE, 1) | CSL_FMK(SRIO_SP_CTL_PORT_LOCKOUT, 0); srioRegisters->PORT[2].SP_CTL = CSL_FMKT(SRIO_SP_CTL_PORT_WIDTH, RESETVAL) | CSL_FMKT(SRIO_SP_CTL_INITIALIZED_PORT_WIDTH, RESETVAL) | CSL_FMKT(SRIO_SP_CTL_PORT_WIDTH_OVERRIDE, NO_OVERRIDE) | CSL_FMK(SRIO_SP_CTL_PORT_DISABLE, 1) | CSL_FMK(SRIO_SP_CTL_OUTPUT_PORT_ENABLE, 0) | CSL_FMK(SRIO_SP_CTL_INPUT_PORT_ENABLE, 0) | CSL_FMK(SRIO_SP_CTL_STOP_PORT_FLD_ENC_ENABLE, 1) | CSL_FMK(SRIO_SP_CTL_DROP_PACKET_ENABLE, 1) | CSL_FMK(SRIO_SP_CTL_PORT_LOCKOUT, 0); srioRegisters->PORT[3].SP_CTL = CSL_FMKT(SRIO_SP_CTL_PORT_WIDTH, RESETVAL) | CSL_FMKT(SRIO_SP_CTL_INITIALIZED_PORT_WIDTH, RESETVAL) | CSL_FMKT(SRIO_SP_CTL_PORT_WIDTH_OVERRIDE, NO_OVERRIDE) | CSL_FMK(SRIO_SP_CTL_PORT_DISABLE, 1) | CSL_FMK(SRIO_SP_CTL_OUTPUT_PORT_ENABLE, 0) | CSL_FMK(SRIO_SP_CTL_INPUT_PORT_ENABLE, 0) | CSL_FMK(SRIO_SP_CTL_STOP_PORT_FLD_ENC_ENABLE, 1) | CSL_FMK(SRIO_SP_CTL_DROP_PACKET_ENABLE, 1) | CSL_FMK(SRIO_SP_CTL_PORT_LOCKOUT, 0); } Void SetPortConfiguration() { CSL_FINS(srioRegisters->SP_LT_CTL, SRIO_SP_LT_CTL_TIMEOUT_VALUE, 0xFFFFF); CSL_FINS(srioRegisters->SP_RT_CTL, SRIO_SP_RT_CTL_TIMEOUT_VALUE, 0xFFFFF); CSL_FINS(srioRegisters->SP_GEN_CTL, SRIO_SP_GEN_CTL_HOST, 0); CSL_FINS(srioRegisters->SP_GEN_CTL, SRIO_SP_GEN_CTL_MASTER_ENABLE, 1); SetPortControl(); } Void SetPortErrorConfiguration() { srioRegisters->PORT_ERROR[0].SP_RATE_EN = CSL_SRIO_ERR_IMP_SPECIFIC_ENABLE | CSL_SRIO_CORRUPT_CNTL_SYM_ENABLE | CSL_SRIO_CNTL_SYM_UNEXPECTED_ACKID_ENABLE | CSL_SRIO_RCVD_PKT_NOT_ACCPT_ENABLE | CSL_SRIO_PKT_UNEXPECTED_ACKID_ENABLE | CSL_SRIO_RCVD_PKT_WITH_BAD_CRC_ENABLE | CSL_SRIO_RCVD_PKT_OVER_276B_ENABLE | CSL_SRIO_NON_OUTSTANDING_ACKID_ENABLE | CSL_SRIO_PROTOCOL_ERROR_ENABLE | CSL_SRIO_UNSOLICITED_ACK_CNTL_SYM_ENABLE | CSL_SRIO_LINK_TIMEOUT_ENABLE; CSL_FINS(srioRegisters->PORT_ERROR[0].SP_ERR_RATE, SRIO_SP_ERR_RATE_ERROR_RATE_BIAS, CSL_SRIO_ERR_RATE_BIAS_1S); CSL_FINS(srioRegisters->PORT_ERROR[0].SP_ERR_RATE, SRIO_SP_ERR_RATE_ERROR_RATE_RECOVERY, CSL_SRIO_ERR_RATE_COUNT_2); CSL_FINS(srioRegisters->PORT_ERROR[0].SP_ERR_THRESH, SRIO_SP_ERR_THRESH_ERROR_RATE_FAILED_THRESHOLD, 10); CSL_FINS(srioRegisters->PORT_ERROR[0].SP_ERR_THRESH, SRIO_SP_ERR_THRESH_ERROR_RATE_DEGRADED_THRES, 10); srioRegisters->PORT_ERROR[1].SP_RATE_EN = CSL_SRIO_SP_RATE_EN_RESETVAL; CSL_FINS(srioRegisters->PORT_ERROR[1].SP_ERR_RATE, SRIO_SP_ERR_RATE_ERROR_RATE_BIAS, CSL_SRIO_SP_ERR_RATE_ERROR_RATE_BIAS_RESETVAL); CSL_FINS(srioRegisters->PORT_ERROR[1].SP_ERR_RATE, SRIO_SP_ERR_RATE_ERROR_RATE_RECOVERY, CSL_SRIO_SP_ERR_RATE_ERROR_RATE_RECOVERY_RESETVAL); CSL_FINS(srioRegisters->PORT_ERROR[1].SP_ERR_THRESH, SRIO_SP_ERR_THRESH_ERROR_RATE_FAILED_THRESHOLD, CSL_SRIO_SP_ERR_THRESH_ERROR_RATE_FAILED_THRESHOLD_RESETVAL); CSL_FINS(srioRegisters->PORT_ERROR[1].SP_ERR_THRESH, SRIO_SP_ERR_THRESH_ERROR_RATE_DEGRADED_THRES, CSL_SRIO_SP_ERR_THRESH_ERROR_RATE_DEGRADED_THRES_RESETVAL); srioRegisters->PORT_ERROR[2].SP_RATE_EN = CSL_SRIO_SP_RATE_EN_RESETVAL; CSL_FINS(srioRegisters->PORT_ERROR[2].SP_ERR_RATE, SRIO_SP_ERR_RATE_ERROR_RATE_BIAS, CSL_SRIO_SP_ERR_RATE_ERROR_RATE_BIAS_RESETVAL); CSL_FINS(srioRegisters->PORT_ERROR[2].SP_ERR_RATE, SRIO_SP_ERR_RATE_ERROR_RATE_RECOVERY, CSL_SRIO_SP_ERR_RATE_ERROR_RATE_RECOVERY_RESETVAL); CSL_FINS(srioRegisters->PORT_ERROR[2].SP_ERR_THRESH, SRIO_SP_ERR_THRESH_ERROR_RATE_FAILED_THRESHOLD, CSL_SRIO_SP_ERR_THRESH_ERROR_RATE_FAILED_THRESHOLD_RESETVAL); CSL_FINS(srioRegisters->PORT_ERROR[2].SP_ERR_THRESH, SRIO_SP_ERR_THRESH_ERROR_RATE_DEGRADED_THRES, CSL_SRIO_SP_ERR_THRESH_ERROR_RATE_DEGRADED_THRES_RESETVAL); srioRegisters->PORT_ERROR[3].SP_RATE_EN = CSL_SRIO_SP_RATE_EN_RESETVAL; CSL_FINS(srioRegisters->PORT_ERROR[3].SP_ERR_RATE, SRIO_SP_ERR_RATE_ERROR_RATE_BIAS, CSL_SRIO_SP_ERR_RATE_ERROR_RATE_BIAS_RESETVAL); CSL_FINS(srioRegisters->PORT_ERROR[3].SP_ERR_RATE, SRIO_SP_ERR_RATE_ERROR_RATE_RECOVERY, CSL_SRIO_SP_ERR_RATE_ERROR_RATE_RECOVERY_RESETVAL); CSL_FINS(srioRegisters->PORT_ERROR[3].SP_ERR_THRESH, SRIO_SP_ERR_THRESH_ERROR_RATE_FAILED_THRESHOLD, CSL_SRIO_SP_ERR_THRESH_ERROR_RATE_FAILED_THRESHOLD_RESETVAL); CSL_FINS(srioRegisters->PORT_ERROR[3].SP_ERR_THRESH, SRIO_SP_ERR_THRESH_ERROR_RATE_DEGRADED_THRES, CSL_SRIO_SP_ERR_THRESH_ERROR_RATE_DEGRADED_THRES_RESETVAL); } Void SetAllRegisters(const Uint16 largeDeviceId, const Uint8 smallDeviceId) { srioRegisters->GBL_EN = CSL_FMKT(SRIO_GBL_EN_EN, ENABLE); EnableAllBlocks(); SetPeripheralControlRegister(); SetDeviceIds(largeDeviceId, smallDeviceId); SetHardwarePacketForwarding(); SetSERDESConfiguration(); SetFlowControl(largeDeviceId); srioRegisters->PE_LL_CTL = CSL_SRIO_ADDR_SELECT_34BIT; CSL_FINS(srioRegisters->BASE_ID, SRIO_BASE_ID_BASE_DEVICEID, smallDeviceId); CSL_FINS(srioRegisters->BASE_ID, SRIO_BASE_ID_LARGE_BASE_DEVICEID, largeDeviceId); CSL_FINS(srioRegisters->HOST_BASE_ID_LOCK, SRIO_HOST_BASE_ID_LOCK_HOST_BASE_DEVICEID, largeDeviceId); srioRegisters->COMP_TAG = CSL_SRIO_COMP_TAG_COMPONENT_TAG_RESETVAL; SetPortConfiguration(); srioRegisters->ERR_EN = CSL_SRIO_IO_ERR_RESP_ENABLE | CSL_SRIO_ILL_TRANS_DECODE_ENABLE | CSL_SRIO_ILL_TRANS_TARGET_ERR_ENABLE | CSL_SRIO_PKT_RESP_TIMEOUT_ENABLE | CSL_SRIO_UNSOLICITED_RESP_ENABLE | CSL_SRIO_UNSUPPORTED_TRANS_ENABLE; SetPortErrorConfiguration(); CSL_FINS(srioRegisters->SP_IP_DISCOVERY_TIMER, SRIO_SP_IP_DISCOVERY_TIMER_DISCOVERY_TIMER, CSL_SRIO_SP_IP_DISCOVERY_TIMER_DISCOVERY_TIMER_RESETVAL); CSL_FINS(srioRegisters->SP_IP_DISCOVERY_TIMER, SRIO_SP_IP_DISCOVERY_TIMER_PW_TIMER, CSL_SRIO_PW_TIME_8); srioRegisters->SP_IP_MODE = CSL_FMK(SRIO_SP_IP_MODE_SP_MODE, 00) // 00b = RapidIO Physical Layer 1x/4x LP-Serial Specification, 01b = 4 ports | CSL_FMKT(SRIO_SP_IP_MODE_IDLE_ERR_DIS, ENABLE) | CSL_FMKT(SRIO_SP_IP_MODE_TX_FIFO_BYPASS, DISABLE) // TX_FIFO is operational | CSL_FMKT(SRIO_SP_IP_MODE_PW_DIS, ENABLE) | CSL_FMK(SRIO_SP_IP_MODE_TGT_ID_DIS, 0) // packet accepted if DestID != BaseID | CSL_FMKT(SRIO_SP_IP_MODE_SELF_RST, DISABLE) | CSL_FMKT(SRIO_SP_IP_MODE_MLTC_EN, ENABLE) | CSL_FMK(SRIO_SP_IP_MODE_MLTC_IRQ, CSL_SRIO_SP_IP_MODE_MLTC_IRQ_RESETVAL) | CSL_FMKT(SRIO_SP_IP_MODE_RST_EN, ENABLE) | CSL_FMKT(SRIO_SP_IP_MODE_PW_EN, ENABLE); /* Configure the SP_IP_PRESCALE register assuming 333 MHz frequency */ CSL_FINS(srioRegisters->IP_PRESCAL, SRIO_IP_PRESCAL_PRESCALE, 33); /* setups for silence timer and Port control independent error * register */ for (Int i = 0; i < CSL_SRIO_PORTS_MAX; ++i) { CSL_FINS(srioRegisters->PORT_OPTION[i].SP_SILENCE_TIMER, SRIO_SP_SILENCE_TIMER_SILENCE_TIMER, CSL_SRIO_SP_SILENCE_TIMER_SILENCE_TIMER_RESETVAL); srioRegisters->PORT_OPTION[i].SP_CTL_INDEP = CSL_SRIO_SP_CTL_INDEP_RESETVAL; } /* Port control independent error reporting enable. Macros can be ORed * to get the value */ /* TX_FLW - 0; Receive link flow control SOFT_REC - 0; Hardware controlled error recovery FORCE_REINIT - 0; Reinitialization process NOT forced TRANS_MODE - 01; transfer mode - Store & Forward Mode DEBUG - 1; Debug enable SEND_DBG_PKT - 0; Do not force a debug packet ILL_TRANS_EN - 1; Illegal Transfer Error reporting Enable MAX_RETRY_EN - 1; Max_retry_error report enable MAX_RETRY_THR - 0x01; Maximum Retry Threshold Trigger IRQ_EN - 1; Interrupt error report Enable */ srioRegisters->PORT_OPTION[0].SP_CTL_INDEP = 0x01A20180; // Manually reset the SRIO peripheral because this won't happen by default when restarting in the debugger. ResetSrioInterrupts(); ResetMapping(); ResetMessageRxQueues(); // Periperal enable // "This should be the last enable bit to toggle when bringing the device out of reset to begin normal operation." // See spru976b.pdf Table 29 srioRegisters->PCR = CSL_FMKT(SRIO_PCR_PEREN, ENABLE) | CSL_FMK(SRIO_PCR_SOFT, CSL_SRIO_PCR_SOFT_RESETVAL) | CSL_FMK(SRIO_PCR_FREE, CSL_SRIO_PCR_FREE_RESETVAL); } /* Spin in a delay loop for delay iterations */ // Bit dubious in a driver!! Void delay(Uint32 delay) { volatile Uint32 i, n; n = 0; for (i = 0; i < delay; i++) { n = n + 1; } } } Void InitialiseSrio(const Uint16 largeDeviceId, const Uint8 smallDeviceId) { EnableSRIOPeripheral(); SetAllRegisters(largeDeviceId, smallDeviceId); // Some examples set the registers and then enter a loop waiting for the port // to indicate that it is initialised other examples do not bother. // It will wait in this loop until the other DSP is initialised. // I suppose it is important to wait for the port to become initialised if // you're going to try and transmit but if you're only receiving I don't know // what difference it is going to make. do { delay(100000); } while (CSL_FEXT(srioRegisters->PORT[0].SP_ERR_STAT, SRIO_SP_ERR_STAT_PORT_UNINITIALIZED) == 1); } #elif defined(ONEX_1X_MODE) namespace { // This function call generates quite a bit of code and it isn't very easy to control. // I timed it with the high-resolution timer in Release. // What I really want is a solution that generates a very small amount of code and // guarantees a minimum cycle count. #pragma FUNC_CANNOT_INLINE; Void Wait100Cycles() { #pragma MUST_ITERATE(3, 3 , 1); for (volatile Int i = 0; i < 3; ++i) { } } Void EnableSRIOPeripheral() { // See tms320c6455.pdf section 3 // Unlock command and write to Peripheral Configuration Register 0 need to be // within 16 SYSCLK3 cycles. // The SRIO peripheral is available 16 SYSCLK3 cycles after the write to PERCFG0 // (there is no SRIO entry in peripheral status registers). SYSCLK3 is CPU/6 // (see tms320c6455.pdf p.134) therefore 16 SYSCLK3 approximately equals 100 CPU cycles. CSL_DevRegs *const deviceStateControlRegisters = reinterpret_cast(CSL_DEV_REGS); deviceStateControlRegisters->PERLOCK = CSL_FMKT(DEV_PERLOCK_LOCKVAL, UNLOCK); CSL_FINST(deviceStateControlRegisters->PERCFG0, DEV_PERCFG0_SRIOCTL, ENABLE); Wait100Cycles(); } Void GlobalAndBlockEnable() { srioRegisters->GBL_EN = CSL_FMKT(SRIO_GBL_EN_EN, ENABLE); srioRegisters->BLK_ENABLE[0].BLK_EN = CSL_FMKT(SRIO_BLK_EN_EN, ENABLE); srioRegisters->BLK_ENABLE[1].BLK_EN = CSL_FMKT(SRIO_BLK_EN_EN, ENABLE); srioRegisters->BLK_ENABLE[2].BLK_EN = CSL_FMKT(SRIO_BLK_EN_EN, ENABLE); srioRegisters->BLK_ENABLE[3].BLK_EN = CSL_FMKT(SRIO_BLK_EN_EN, ENABLE); srioRegisters->BLK_ENABLE[4].BLK_EN = CSL_FMKT(SRIO_BLK_EN_EN, ENABLE); srioRegisters->BLK_ENABLE[5].BLK_EN = CSL_FMKT(SRIO_BLK_EN_EN, ENABLE); srioRegisters->BLK_ENABLE[6].BLK_EN = CSL_FMKT(SRIO_BLK_EN_EN, ENABLE); srioRegisters->BLK_ENABLE[7].BLK_EN = CSL_FMKT(SRIO_BLK_EN_EN, ENABLE); srioRegisters->BLK_ENABLE[8].BLK_EN = CSL_FMKT(SRIO_BLK_EN_EN, ENABLE); // I've copied this from MQT rapidiotest.c which says // "Small delay (>32 cycles) to let the blocks become enabled". // I can't find a reference to this delay in spru976c.pdf but it makes some sense. for (volatile Int i = 0; i < 100; ++i); } Void SetPllMpyAndEnablePll() { // Desired line rate is 1.25 Gbps and RIOCLK is 125 MHz // hence from Table 8 in spru976c.pdf MPY = 10 (and RATESCALE = full). srioRegisters->SERDES_CFG_CNTL[0] = CSL_FMKT(SRIO_SERDES_CFG_CNTL_LB, FREQ_DEP) | CSL_FMKT(SRIO_SERDES_CFG_CNTL_MPY, 10) | CSL_FMKT(SRIO_SERDES_CFG_CNTL_ENPLL, ENABLE); // Should allow 1 usec for the regulator to stabilise see spru976c.pdf section 2.3.2.1 // but the examples don't bother. } Void SetReceieverConfiguration() { // Desired line rate is 1.25 Gbps and RIOCLK is 125 MHz // hence from Table 8 in spru976c.pdf RATESCALE = half (and MPY = 10). const Uint32 configuration = CSL_FMK(SRIO_SERDES_CFGRX_CNTL_EQ, 0x01) | CSL_FMK(SRIO_SERDES_CFGRX_CNTL_CDR, 0x00) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_LOS, DISABLED) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_ALIGN, COMMA) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_TERM, VDDT) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_INVPAIR, NORMAL) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_RATE, HALF) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_BUSWIDTH, 10BIT) | CSL_FMKT(SRIO_SERDES_CFGRX_CNTL_ENRX, ENABLE); srioRegisters->SERDES_CFGRX_CNTL[0] = configuration; srioRegisters->SERDES_CFGRX_CNTL[1] = configuration; srioRegisters->SERDES_CFGRX_CNTL[2] = configuration; srioRegisters->SERDES_CFGRX_CNTL[3] = configuration; } Void SetTransmitterConfiguration() { const Uint32 configuration = CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_ENFTP, FIXED) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_DE, RESETVAL) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_SWING, 1000) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_CM, NORMAL) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_INVPAIR, NORMAL) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_RATE, HALF) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_BUSWIDTH, 10BIT) | CSL_FMKT(SRIO_SERDES_CFGTX_CNTL_ENTX, ENABLE); srioRegisters->SERDES_CFGTX_CNTL[0] = configuration; srioRegisters->SERDES_CFGTX_CNTL[1] = configuration; srioRegisters->SERDES_CFGTX_CNTL[2] = configuration; srioRegisters->SERDES_CFGTX_CNTL[3] = configuration; } Void ConfigureSerDesMacros() { SetPllMpyAndEnablePll(); SetReceieverConfiguration(); SetTransmitterConfiguration(); } Void ConfigurePorts() { const Uint32 configuration = CSL_FMKT(SRIO_SP_CTL_PORT_WIDTH, RESETVAL) | CSL_FMKT(SRIO_SP_CTL_INITIALIZED_PORT_WIDTH, RESETVAL) | CSL_FMKT(SRIO_SP_CTL_PORT_WIDTH_OVERRIDE, NO_OVERRIDE) | CSL_FMK(SRIO_SP_CTL_PORT_DISABLE, 0) | CSL_FMK(SRIO_SP_CTL_OUTPUT_PORT_ENABLE, 1) | CSL_FMK(SRIO_SP_CTL_INPUT_PORT_ENABLE, 1) | CSL_FMKT(SRIO_SP_CTL_ERROR_CHECK_DISABLE, RESETVAL) | CSL_FMKT(SRIO_SP_CTL_MULTICAST_PARTICIPANT, RESETVAL) | CSL_FMK(SRIO_SP_CTL_STOP_PORT_FLD_ENC_ENABLE, 1) | CSL_FMK(SRIO_SP_CTL_DROP_PACKET_ENABLE, 1) | CSL_FMK(SRIO_SP_CTL_PORT_LOCKOUT, 0) | CSL_FMKT(SRIO_SP_CTL_PORT_TYPE, RESETVAL); srioRegisters->PORT[0].SP_CTL = configuration; srioRegisters->PORT[1].SP_CTL = configuration; srioRegisters->PORT[2].SP_CTL = configuration; srioRegisters->PORT[3].SP_CTL = configuration; } Void ConfigureDeviceId(const Uint8 smallDeviceId) { // On C645x the BASE_ID value is not automatically copied to the DEVICEID_REG1 register. // See spru967c.pdf section 2.3.15 srioRegisters->BASE_ID = CSL_FMK(SRIO_BASE_ID_BASE_DEVICEID, smallDeviceId) | CSL_FMKT(SRIO_BASE_ID_LARGE_BASE_DEVICEID, RESETVAL); srioRegisters->DEVICEID_REG1 = CSL_FMK(SRIO_DEVICEID_REG1_8BNODEID, smallDeviceId) | CSL_FMKT(SRIO_DEVICEID_REG1_16BNODEID, RESETVAL); } Void EnableLogicalLayerErrorReporting() { // Clear error bits incase we've just done a soft restart. srioRegisters->ERR_DET = CSL_SRIO_ERR_DET_RESETVAL; srioRegisters->ERR_EN = CSL_FMK(SRIO_ERR_EN_IO_ERR_RESP_ENABLE, 1U) | CSL_FMK(SRIO_ERR_EN_MSG_ERR_RESP_ENABLE, 1U) | CSL_FMK(SRIO_ERR_EN_GSM_ERR_RESP_ENABLE, 1U) | CSL_FMK(SRIO_ERR_EN_ERR_MSG_FORMAT_ENABLE, 1U) | CSL_FMK(SRIO_ERR_EN_ILL_TRANS_DECODE_ENABLE, 1U) | CSL_FMK(SRIO_ERR_EN_ILL_TRANS_TARGET_ERR_ENABLE, 1U) | CSL_FMK(SRIO_ERR_EN_MSG_REQ_TIMEOUT_ENABLE, 1U) | CSL_FMK(SRIO_ERR_EN_PKT_RESP_TIMEOUT_ENABLE, 1U) | CSL_FMK(SRIO_ERR_EN_UNSOLICITED_RESP_ENABLE, 1U) | CSL_FMK(SRIO_ERR_EN_UNSUPPORTED_TRANS_ENABLE, 1U) | CSL_FMK(SRIO_ERR_EN_RX_CPPI_SECURITY, 1U) | CSL_FMK(SRIO_ERR_EN_RX_IO_SECURITY, 1U); } Void EnablePortErrorRateCounter() { srioRegisters->PORT_ERROR[0].SP_RATE_EN = CSL_FMK(SRIO_SP_RATE_EN_EN_IMP_SPECIFIC, 1U) | CSL_FMK(SRIO_SP_RATE_EN_CORRUPT_CNTL_SYM_ENABLE, 1U) | CSL_FMK(SRIO_SP_RATE_EN_CNTL_SYM_UNEXPECTED_ACKID_EN, 1U) | CSL_FMK(SRIO_SP_RATE_EN_RCVED_PKT_NOT_ACCPT_EN, 1U) | CSL_FMK(SRIO_SP_RATE_EN_PKT_UNEXPECTED_ACKID_EN, 1U) | CSL_FMK(SRIO_SP_RATE_EN_RCVED_PKT_WITH_BAD_CRC_EN, 1U) | CSL_FMK(SRIO_SP_RATE_EN_RCVED_PKT_OVER_276B_EN, 1U) | CSL_FMK(SRIO_SP_RATE_EN_NON_OUTSTANDING_ACKID_EN, 1U) | CSL_FMK(SRIO_SP_RATE_EN_PROTOCOL_ERROR_EN, 1U) | CSL_FMK(SRIO_SP_RATE_EN_DELINEATION_ERROR_EN, 1U) | CSL_FMK(SRIO_SP_RATE_EN_UNSOLICITED_ACK_CNTL_SYM_EN, 1U) | CSL_FMK(SRIO_SP_RATE_EN_LINK_TIMEOUT_EN, 1U); srioRegisters->PORT_ERROR[0].SP_ERR_RATE = CSL_FMK(SRIO_SP_ERR_RATE_ERROR_RATE_BIAS, 0U) | CSL_FMK(SRIO_SP_ERR_RATE_ERROR_RATE_RECOVERY, 3U) | CSL_FMK(SRIO_SP_ERR_RATE_PEAK_ERROR_RATE, 0U) | CSL_FMK(SRIO_SP_ERR_RATE_ERROR_RATE_COUNTER, 0U); } } Void ClearPortErrorStatus() { const Uint32 readWriteBits = CSL_SRIO_SP_ERR_STAT_OUTPUT_PKT_DROP_MASK | CSL_SRIO_SP_ERR_STAT_OUTPUT_FLD_ENC_MASK | CSL_SRIO_SP_ERR_STAT_OUTPUT_DEGRD_ENC_MASK | CSL_SRIO_SP_ERR_STAT_OUTPUT_RETRY_ENC_MASK | CSL_SRIO_SP_ERR_STAT_OUTPUT_ERROR_ENC_MASK | CSL_SRIO_SP_ERR_STAT_INPUT_ERROR_ENC_MASK | CSL_SRIO_SP_ERR_STAT_PORT_WRITE_PND_MASK | CSL_SRIO_SP_ERR_STAT_PORT_ERROR_MASK; srioRegisters->PORT[0].SP_ERR_STAT &= readWriteBits; } Void InitialiseSrio(const Uint16 largeDeviceId, const Uint8 smallDeviceId) { EnableSRIOPeripheral(); GlobalAndBlockEnable(); // The port initialisation process has already been completed by the bootloader. // I believe setting BOOT_COMPLETE = WRITE_ENABLE means I can write some registers // but it shouldn't affect the link. // See spru976c.pdf table 43. srioRegisters->PER_SET_CNTL = CSL_FMKT(SRIO_PER_SET_CNTL_SW_MEM_SLEEP_OVERRIDE, ENABLE) | CSL_FMKT(SRIO_PER_SET_CNTL_LOOPBACK, NORMAL) | CSL_FMKT(SRIO_PER_SET_CNTL_BOOT_COMPLETE, WRITE_ENABLE) | CSL_FMK(SRIO_PER_SET_CNTL_TX_PRI2_WM, 0) | CSL_FMK(SRIO_PER_SET_CNTL_TX_PRI1_WM, 0) | CSL_FMK(SRIO_PER_SET_CNTL_TX_PRI0_WM, 0) | CSL_FMK(SRIO_PER_SET_CNTL_CBA_TRANS_PRI, 1) | CSL_FMKT(SRIO_PER_SET_CNTL_1X_MODE, ENABLE) | CSL_FMKT(SRIO_PER_SET_CNTL_PRESCALER_SELECT, 6); ConfigureSerDesMacros(); ConfigurePorts(); ConfigureDeviceId(smallDeviceId); srioRegisters->IP_PRESCAL = CSL_FMK(SRIO_IP_PRESCAL_PRESCALE, 0x21); srioRegisters->SP_IP_MODE = CSL_FMK(SRIO_SP_IP_MODE_SP_MODE, 1) // 00b = RapidIO Physical Layer 1x/4x LP-Serial Specification, 01b = 4 ports (1x mode each) | CSL_FMKT(SRIO_SP_IP_MODE_IDLE_ERR_DIS, ENABLE) | CSL_FMKT(SRIO_SP_IP_MODE_TX_FIFO_BYPASS, DISABLE) // TX_FIFO is operational | CSL_FMKT(SRIO_SP_IP_MODE_PW_DIS, ENABLE) | CSL_FMK(SRIO_SP_IP_MODE_TGT_ID_DIS, 0) // packet accepted if DestID != BaseID | CSL_FMKT(SRIO_SP_IP_MODE_SELF_RST, DISABLE) | CSL_FMKT(SRIO_SP_IP_MODE_MLTC_EN, ENABLE) | CSL_FMKT(SRIO_SP_IP_MODE_MLTC_IRQ, RESETVAL) | CSL_FMKT(SRIO_SP_IP_MODE_RST_EN, ENABLE) | CSL_FMKT(SRIO_SP_IP_MODE_PW_EN, ENABLE) | CSL_FMKT(SRIO_SP_IP_MODE_PW_IRQ, RESETVAL); // Clear error bits incase we've just done a soft restart. ClearPortErrorStatus(); EnablePortErrorRateCounter(); EnableLogicalLayerErrorReporting(); // Set BOOT_COMPLETE to 1 (WRITE_DISABLE) to trigger physical layer port initialisation process // but this has already been done by the bootloader. // See spru976c.pdf table 43. srioRegisters->PER_SET_CNTL = CSL_FMKT(SRIO_PER_SET_CNTL_SW_MEM_SLEEP_OVERRIDE, ENABLE) | CSL_FMKT(SRIO_PER_SET_CNTL_LOOPBACK, NORMAL) | CSL_FMKT(SRIO_PER_SET_CNTL_BOOT_COMPLETE, WRITE_DISABLE) | CSL_FMK(SRIO_PER_SET_CNTL_TX_PRI2_WM, 0) | CSL_FMK(SRIO_PER_SET_CNTL_TX_PRI1_WM, 0) | CSL_FMK(SRIO_PER_SET_CNTL_TX_PRI0_WM, 0) | CSL_FMK(SRIO_PER_SET_CNTL_CBA_TRANS_PRI, 1) | CSL_FMKT(SRIO_PER_SET_CNTL_1X_MODE, ENABLE) | CSL_FMKT(SRIO_PER_SET_CNTL_PRESCALER_SELECT, 6); while (!(srioRegisters->PORT[0].SP_ERR_STAT & CSL_SRIO_SP_ERR_STAT_PORT_OK_MASK)) { } // Periperal enable // "This should be the last enable bit to toggle when bringing the device out of reset to begin normal operation." // See spru976b.pdf Table 29 srioRegisters->PCR = CSL_FMKT(SRIO_PCR_PEREN, ENABLE) | CSL_FMK(SRIO_PCR_SOFT, CSL_SRIO_PCR_SOFT_RESETVAL) | CSL_FMK(SRIO_PCR_FREE, CSL_SRIO_PCR_FREE_RESETVAL); } #endif