[processor-sdk/pdk.git] / packages / ti / transport / c6670 / ipc / examples / srioIpcBenchmark / device_srio.c
1 /**
2 * @file device_srio.c
3 *
4 * @brief
5 * The 6670 SRIO Device specific code. The SRIO driver calls out
6 * this code to initialize the SRIO IP block. The file is provided as
7 * a sample configuration and should be modified by customers for
8 * their own platforms and configurations.
9 *
10 * \par
11 * NOTE:
12 * (C) Copyright 2011 Texas Instruments, Inc.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 *
18 * Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 *
21 * Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the
24 * distribution.
25 *
26 * Neither the name of Texas Instruments Incorporated nor the names of
27 * its contributors may be used to endorse or promote products derived
28 * from this software without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
33 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
34 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
35 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
36 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 *
42 * \par
43 */
45 #include <xdc/runtime/System.h>
47 /* SRIO Driver Includes. */
48 #include <ti/drv/srio/srio_types.h>
49 #include <ti/drv/srio/include/listlib.h>
50 #include <ti/drv/srio/srio_drv.h>
52 /* CSL SRIO Functional Layer */
53 #include <ti/csl/csl_srio.h>
54 #include <ti/csl/csl_srioAux.h>
55 #include <ti/csl/csl_srioAuxPhyLayer.h>
57 /* CSL BootCfg Module */
58 #include <ti/csl/csl_bootcfg.h>
59 #include <ti/csl/csl_bootcfgAux.h>
61 /* CSL Chip Functional Layer */
62 #include <ti/csl/csl_chip.h>
64 /* QMSS Include */
65 #include <ti/drv/qmss/qmss_drv.h>
67 /* PDK module Headers */
68 #include <ti/platform/platform.h>
70 /**********************************************************************
71 ************************* LOCAL Definitions **************************
72 **********************************************************************/
74 /* These are the GARBAGE queues which are used by the TXU to dump the
75 * descriptor if there is an error instead of recycling the descriptor
76 * to the free queue. */
77 extern const UInt32 GARBAGE_LEN_QUEUE;
78 extern const UInt32 GARBAGE_TOUT_QUEUE;
79 extern const UInt32 GARBAGE_RETRY_QUEUE;
80 extern const UInt32 GARBAGE_TRANS_ERR_QUEUE;
81 extern const UInt32 GARBAGE_PROG_QUEUE;
82 extern const UInt32 GARBAGE_SSIZE_QUEUE;
84 /* SRIO Device Information
85 * - 16 bit Device Identifier.
86 * - 8 bit Device Identifier.
87 * - Vendor Identifier.
88 * - Device Revision. */
89 #define DEVICE_VENDOR_ID 0x30
90 #define DEVICE_REVISION 0x0
92 /* SRIO Assembly Information
93 * - Assembly Identifier
94 * - Assembly Vendor Identifier.
95 * - Assembly Device Revision.
96 * - Assembly Extension Features */
97 #define DEVICE_ASSEMBLY_ID 0x0
98 #define DEVICE_ASSEMBLY_VENDOR_ID 0x30
99 #define DEVICE_ASSEMBLY_REVISION 0x0
100 #define DEVICE_ASSEMBLY_INFO 0x0100
102 /**********************************************************************
103 ************************* Extern Definitions *************************
104 **********************************************************************/
106 extern const UInt32 DEVICE_ID1_16BIT;
107 extern const UInt32 DEVICE_ID1_8BIT;
108 extern const UInt32 DEVICE_ID2_16BIT;
109 extern const UInt32 DEVICE_ID2_8BIT;
110 extern const UInt32 DEVICE_ID3_16BIT;
111 extern const UInt32 DEVICE_ID3_8BIT;
112 extern const UInt32 DEVICE_ID4_16BIT;
113 extern const UInt32 DEVICE_ID4_8BIT;
115 /**********************************************************************
116 *********************** DEVICE SRIO FUNCTIONS ***********************
117 **********************************************************************/
119 /** @addtogroup SRIO_DEVICE_API
120 @{ */
122 /**
123 * @b Description
124 * @n
125 * The function provides the initialization sequence for the SRIO IP
126 * block. This can be modified by customers for their application and
127 * configuration.
128 *
129 * @retval
130 * Success - 0
131 * @retval
132 * Error - <0
133 */
134 int32_t SrioDevice_init (void)
135 {
136 CSL_SrioHandle hSrio;
137 int32_t i, j;
138 SRIO_PE_FEATURES peFeatures;
139 SRIO_OP_CAR opCar;
140 Qmss_QueueHnd queueHnd;
141 Qmss_Queue queueInfo;
142 uint8_t isAllocated;
143 Bool sameGarbageQ;
144 uint32_t garbageQueue[6];
146 garbageQueue[0] = GARBAGE_LEN_QUEUE;
147 garbageQueue[1] = GARBAGE_TOUT_QUEUE;
148 garbageQueue[2] = GARBAGE_RETRY_QUEUE;
149 garbageQueue[3] = GARBAGE_TRANS_ERR_QUEUE;
150 garbageQueue[4] = GARBAGE_PROG_QUEUE;
151 garbageQueue[5] = GARBAGE_SSIZE_QUEUE;
153 /* Get the CSL SRIO Handle. */
154 hSrio = CSL_SRIO_Open (0);
155 if (hSrio == NULL)
156 return -1;
158 /* Disable the SRIO Global block */
159 CSL_SRIO_GlobalDisable (hSrio);
161 /* Disable each of the individual SRIO blocks. */
162 for(i = 0; i <= 9; i++)
163 CSL_SRIO_DisableBlock(hSrio, i);
165 /* Set boot complete to be 0; we are not done with the initialization. */
166 CSL_SRIO_SetBootComplete(hSrio, 0);
168 /* Now enable the SRIO block and all the individual blocks also. */
169 CSL_SRIO_GlobalEnable (hSrio);
170 for(i = 0; i <= 9; i++)
171 CSL_SRIO_EnableBlock(hSrio,i);
173 /* Configure SRIO to operate in loopback mode. */
174 // CSL_SRIO_SetLoopbackMode(hSrio,0);
175 // CSL_SRIO_SetLoopbackMode(hSrio,1);
176 // CSL_SRIO_SetLoopbackMode(hSrio,2);
177 // CSL_SRIO_SetLoopbackMode(hSrio,3);
179 /* Configure SRIO to operate in normal mode. */
180 CSL_SRIO_SetNormalMode(hSrio,0);
181 CSL_SRIO_SetNormalMode(hSrio,1);
182 CSL_SRIO_SetNormalMode(hSrio,2);
183 CSL_SRIO_SetNormalMode(hSrio,3);
185 /* Enable Automatic Priority Promotion of response packets. */
186 CSL_SRIO_EnableAutomaticPriorityPromotion(hSrio);
188 /* Set the SRIO Prescalar select to operate in the range of 44.7 to 89.5 */
189 CSL_SRIO_SetPrescalarSelect (hSrio, 0);
191 /* Unlock the Boot Configuration Kicker */
192 CSL_BootCfgUnlockKicker ();
194 /* Assuming the ref_clock of 250.0 MHz and link rate is 3.125 Gbps; program the PLL accordingly. */
195 CSL_BootCfgSetSRIOSERDESConfigPLL (0x233);
197 /* Configure the SRIO SERDES Receive Configuration. */
198 /* loopback mode */
199 // CSL_BootCfgSetSRIOSERDESRxConfig (0, 0x01C40495);
200 // CSL_BootCfgSetSRIOSERDESRxConfig (1, 0x01C40495);
201 // CSL_BootCfgSetSRIOSERDESRxConfig (2, 0x01C40495);
202 // CSL_BootCfgSetSRIOSERDESRxConfig (3, 0x01C40495);
204 /* Non-loopback */
205 CSL_BootCfgSetSRIOSERDESRxConfig (0, 0x00440495);
206 CSL_BootCfgSetSRIOSERDESRxConfig (1, 0x00440495);
207 CSL_BootCfgSetSRIOSERDESRxConfig (2, 0x00440495);
208 CSL_BootCfgSetSRIOSERDESRxConfig (3, 0x00440495);
210 /* Configure the SRIO SERDES Transmit Configuration. */
211 /* loopback mode */
212 // CSL_BootCfgSetSRIOSERDESTxConfig (0, 0x00780795);
213 // CSL_BootCfgSetSRIOSERDESTxConfig (1, 0x00780795);
214 // CSL_BootCfgSetSRIOSERDESTxConfig (2, 0x00780795);
215 // CSL_BootCfgSetSRIOSERDESTxConfig (3, 0x00780795);
217 /* Non-loopback */
218 CSL_BootCfgSetSRIOSERDESTxConfig (0, 0x00180795);
219 CSL_BootCfgSetSRIOSERDESTxConfig (1, 0x00180795);
220 CSL_BootCfgSetSRIOSERDESTxConfig (2, 0x00180795);
221 CSL_BootCfgSetSRIOSERDESTxConfig (3, 0x00180795);
223 #ifndef SIMULATOR_SUPPORT
224 /* Loop around till the SERDES PLL is not locked. */
225 while (1)
226 {
227 uint32_t status;
229 /* Get the SRIO SERDES Status */
230 CSL_BootCfgGetSRIOSERDESStatus(&status);
231 if (status & 0x1)
232 break;
233 }
234 #endif
236 /* Clear the LSU pending interrupts. */
237 CSL_SRIO_ClearLSUPendingInterrupt (hSrio, 1, 0xFF);
238 CSL_SRIO_ClearLSUPendingInterrupt (hSrio, 2, 0xFF);
239 CSL_SRIO_ClearLSUPendingInterrupt (hSrio, 3, 0xFF);
240 CSL_SRIO_ClearLSUPendingInterrupt (hSrio, 4, 0xFF);
241 CSL_SRIO_ClearLSUPendingInterrupt (hSrio, 5, 0xFF);
242 CSL_SRIO_ClearLSUPendingInterrupt (hSrio, 6, 0xFF);
243 CSL_SRIO_ClearLSUPendingInterrupt (hSrio, 7, 0xFF);
244 CSL_SRIO_ClearLSUPendingInterrupt (hSrio, 8, 0xFF);
246 /* Set the Device Information */
247 CSL_SRIO_SetDeviceInfo (hSrio, DEVICE_ID1_8BIT, DEVICE_VENDOR_ID, DEVICE_REVISION);
249 /* Set the Assembly Information */
250 CSL_SRIO_SetAssemblyInfo(hSrio, DEVICE_ASSEMBLY_ID, DEVICE_ASSEMBLY_VENDOR_ID,
251 DEVICE_ASSEMBLY_REVISION, DEVICE_ASSEMBLY_INFO);
253 /* TODO: Configure the processing element features
254 * The SRIO RL file is missing the Re-transmit Suppression Support (Bit6) field definition */
255 peFeatures.isBridge = 0;
256 peFeatures.isEndpoint = 0;
257 peFeatures.isProcessor = 1;
258 peFeatures.isSwitch = 0;
259 peFeatures.isMultiport = 0;
260 peFeatures.isFlowArbiterationSupported = 0;
261 peFeatures.isMulticastSupported = 0;
262 peFeatures.isExtendedRouteConfigSupported = 0;
263 peFeatures.isStandardRouteConfigSupported = 1;
264 peFeatures.isFlowControlSupported = 1;
265 peFeatures.isCRFSupported = 0;
266 peFeatures.isCTLSSupported = 1;
267 peFeatures.isExtendedFeaturePtrValid = 1;
268 peFeatures.numAddressBitSupported = 1;
269 CSL_SRIO_SetProcessingElementFeatures (hSrio, &peFeatures);
271 /* Configure the source operation CAR */
272 memset ((Void *) &opCar, 0, sizeof (opCar));
273 opCar.portWriteOperationSupport = 1;
274 opCar.atomicClearSupport = 1;
275 opCar.atomicSetSupport = 1;
276 opCar.atomicDecSupport = 1;
277 opCar.atomicIncSupport = 1;
278 opCar.atomicTestSwapSupport = 1;
279 opCar.doorbellSupport = 1;
280 opCar.dataMessageSupport = 1;
281 opCar.writeResponseSupport = 1;
282 opCar.streamWriteSupport = 1;
283 opCar.writeSupport = 1;
284 opCar.readSupport = 1;
285 opCar.dataStreamingSupport = 1;
286 CSL_SRIO_SetSourceOperationCAR (hSrio, &opCar);
288 /* Configure the destination operation CAR */
289 memset ((Void *) &opCar, 0, sizeof (opCar));
290 opCar.portWriteOperationSupport = 1;
291 opCar.doorbellSupport = 1;
292 opCar.dataMessageSupport = 1;
293 opCar.writeResponseSupport = 1;
294 opCar.streamWriteSupport = 1;
295 opCar.writeSupport = 1;
296 opCar.readSupport = 1;
297 CSL_SRIO_SetDestOperationCAR (hSrio, &opCar);
299 /* Set the 16 bit and 8 bit identifier for the SRIO Device. */
300 CSL_SRIO_SetDeviceIDCSR (hSrio, DEVICE_ID1_8BIT, DEVICE_ID1_16BIT);
302 /* Enable TLM Base Routing Information for Maintainance Requests & ensure that
303 * the BRR's can be used by all the ports. */
304 CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 0, 1, 1, 1, 0);
305 CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 0, 2, 1, 1, 0);
306 CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 0, 3, 1, 1, 0);
307 CSL_SRIO_SetTLMPortBaseRoutingInfo(hSrio, 1, 0, 1, 1, 0);
309 /* Configure the Base Routing Register to ensure that all packets matching the
310 * Device Identifier & the Secondary Device Id are admitted. */
311 CSL_SRIO_SetTLMPortBaseRoutingPatternMatch(hSrio, 0, 1, DEVICE_ID2_8BIT, 0xFF);
312 CSL_SRIO_SetTLMPortBaseRoutingPatternMatch(hSrio, 0, 2, DEVICE_ID3_8BIT, 0xFF);
313 CSL_SRIO_SetTLMPortBaseRoutingPatternMatch(hSrio, 0, 3, DEVICE_ID4_8BIT, 0xFF);
314 CSL_SRIO_SetTLMPortBaseRoutingPatternMatch(hSrio, 1, 0, DEVICE_ID2_16BIT, 0xFFFF);
316 /* We need to open the Garbage collection queues in the QMSS. This is done to ensure that
317 * these queues are not opened by another system entity. */
318 for (i = 0; i < 6; i++)
319 {
320 /* Open the Garabage queues */
321 queueHnd = Qmss_queueOpen (Qmss_QueueType_GENERAL_PURPOSE_QUEUE, garbageQueue[i], &isAllocated);
322 if (queueHnd < 0)
323 return -1;
325 /* Make sure the queue has not been opened already; we dont the queues to be shared by some other
326 * entity in the system. */
327 if (isAllocated > 1)
328 {
329 /* Check if the already allocated queue is for another garbage Q. Can group garbage queues
330 * for error handling */
331 sameGarbageQ = FALSE;
332 queueInfo = Qmss_getQueueNumber (queueHnd);
334 /* Check all previously allocated garbage Qs */
335 for (j = 0; j < i; j++)
336 {
337 if (queueInfo.qNum == garbageQueue[j])
338 {
339 sameGarbageQ = TRUE;
340 }
341 }
343 if (!sameGarbageQ)
344 {
345 return -1;
346 }
347 }
348 }
350 /* Set the Transmit Garbage Collection Information. */
351 CSL_SRIO_SetTxGarbageCollectionInfo (hSrio, GARBAGE_LEN_QUEUE, GARBAGE_TOUT_QUEUE,
352 GARBAGE_RETRY_QUEUE, GARBAGE_TRANS_ERR_QUEUE,
353 GARBAGE_PROG_QUEUE, GARBAGE_SSIZE_QUEUE);
355 /* Set the Host Device Identifier. */
356 CSL_SRIO_SetHostDeviceID (hSrio, DEVICE_ID1_8BIT);
358 /* Configure the component tag CSR */
359 CSL_SRIO_SetCompTagCSR (hSrio, 0x00000000);
361 /* Configure the PLM for all the ports. */
362 for (i = 0; i < 4; i++)
363 {
364 /* Set the PLM Port Silence Timer. */
365 CSL_SRIO_SetPLMPortSilenceTimer (hSrio, i, 0x2);
367 /* TODO: We need to ensure that the Port 0 is configured to support both
368 * the 2x and 4x modes. The Port Width field is read only. So here we simply
369 * ensure that the Input and Output ports are enabled. */
370 CSL_SRIO_EnableInputPort (hSrio, i);
371 CSL_SRIO_EnableOutputPort (hSrio, i);
373 /* Set the PLM Port Discovery Timer. */
374 CSL_SRIO_SetPLMPortDiscoveryTimer (hSrio, i, 0x2);
376 /* Reset the Port Write Reception capture. */
377 CSL_SRIO_SetPortWriteReceptionCapture(hSrio, i, 0x0);
378 }
380 /* Set the Port link timeout CSR */
381 CSL_SRIO_SetPortLinkTimeoutCSR (hSrio, 0x000FFF);
383 /* Set the Port General CSR: Only executing as Master Enable */
384 CSL_SRIO_SetPortGeneralCSR (hSrio, 0, 1, 0);
386 /* Clear the sticky register bits. */
387 CSL_SRIO_SetLLMResetControl (hSrio, 1);
389 /* Set the device id to be 0 for the Maintenance Port-Write operation
390 * to report errors to a system host. */
391 CSL_SRIO_SetPortWriteDeviceId (hSrio, 0x0, 0x0, 0x0);
393 /* Set the Data Streaming MTU */
394 CSL_SRIO_SetDataStreamingMTU (hSrio, 64);
396 /* Configure the path mode for the ports. */
397 for(i = 0; i < 4; i++)
398 CSL_SRIO_SetPLMPortPathControlMode (hSrio, i, 0);
400 /* Set the LLM Port IP Prescalar. */
401 CSL_SRIO_SetLLMPortIPPrescalar (hSrio, 0x21);
403 /* Enable the peripheral. */
404 CSL_SRIO_EnablePeripheral(hSrio);
406 /* Configuration has been completed. */
407 CSL_SRIO_SetBootComplete(hSrio, 1);
409 #ifndef SIMULATOR_SUPPORT
410 /* This code checks if the ports are operational or not. The functionality is not supported
411 * on the simulator. */
412 for(i = 0; i < 4; i++)
413 {
414 UInt waitLength = 0;
415 UInt portIsOkay = 0;
417 /* Check SRIO ports every millisecond for 2 seconds */
418 while (waitLength < 2000)
419 {
420 if (CSL_SRIO_IsPortOk (hSrio, i) == TRUE)
421 {
422 portIsOkay = 1;
423 break;
424 }
425 platform_delay(1000);
426 waitLength++;
427 }
429 if (portIsOkay)
430 {
431 System_printf ("Port %d is okay\n", i);
432 }
433 else
434 {
435 System_printf ("Port %d did not initialize\n", i);
436 }
437 }
438 #endif
440 /* Set all the queues 0 to operate at the same priority level and to send packets onto Port 0 */
441 for (i =0 ; i < 16; i++)
442 CSL_SRIO_SetTxQueueSchedInfo(hSrio, i, 0, 0);
444 /* Set the Doorbell route to determine which routing table is to be used
445 * This configuration implies that the Interrupt Routing Table is configured as
446 * follows:-
447 * Interrupt Destination 0 - INTDST 16
448 * Interrupt Destination 1 - INTDST 17
449 * Interrupt Destination 2 - INTDST 18
450 * Interrupt Destination 3 - INTDST 19
451 */
452 CSL_SRIO_SetDoorbellRoute(hSrio, 0);
454 /* Route the Doorbell interrupts.
455 * Doorbell Register 0 - All 16 Doorbits are routed to Interrupt Destination 0.
456 * Doorbell Register 1 - All 16 Doorbits are routed to Interrupt Destination 1.
457 * Doorbell Register 2 - All 16 Doorbits are routed to Interrupt Destination 2.
458 * Doorbell Register 3 - All 16 Doorbits are routed to Interrupt Destination 3. */
459 for (i = 0; i < 16; i++)
460 {
461 CSL_SRIO_RouteDoorbellInterrupts(hSrio, 0, i, 0);
462 CSL_SRIO_RouteDoorbellInterrupts(hSrio, 1, i, 1);
463 CSL_SRIO_RouteDoorbellInterrupts(hSrio, 2, i, 2);
464 CSL_SRIO_RouteDoorbellInterrupts(hSrio, 3, i, 3);
465 }
467 /* Initialization has been completed. */
468 return 0;
469 }
471 /**
472 @}
473 */