627a097d84766d08c9cce43eb175f8b77f5ecfdf
[keystone-rtos/tcp3d-lld.git] / test / src / sample_int_reg.c
1 /*\r
2  * sample_int_reg.c\r
3  *\r
4  * Platform specific interrupt registration and un-registration routines.\r
5  *\r
6  * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/\r
7  * \r
8  *  Redistribution and use in source and binary forms, with or without \r
9  *  modification, are permitted provided that the following conditions \r
10  *  are met:\r
11  *\r
12  *    Redistributions of source code must retain the above copyright \r
13  *    notice, this list of conditions and the following disclaimer.\r
14  *\r
15  *    Redistributions in binary form must reproduce the above copyright\r
16  *    notice, this list of conditions and the following disclaimer in the \r
17  *    documentation and/or other materials provided with the   \r
18  *    distribution.\r
19  *\r
20  *    Neither the name of Texas Instruments Incorporated nor the names of\r
21  *    its contributors may be used to endorse or promote products derived\r
22  *    from this software without specific prior written permission.\r
23  *\r
24  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \r
25  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT \r
26  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
27  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT \r
28  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, \r
29  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT \r
30  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
31  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
32  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
33  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
34  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
35  *\r
36 */\r
37 \r
38 #include <ti/sysbios/knl/Semaphore.h>\r
39 #include <ti/sysbios/family/c64p/Hwi.h>\r
40 #include <ti/sysbios/family/c64p/EventCombiner.h>\r
41 #include <ti/sysbios/family/c66/tci66xx/CpIntc.h>\r
42 \r
43 #include <xdc/runtime/System.h>\r
44 \r
45 #include "sample.h"\r
46 \r
47 extern unsigned int ccXferCompInt[][EDMA3_MAX_REGIONS];\r
48 extern unsigned int ccErrorInt[];\r
49 extern unsigned int tcErrorInt[][EDMA3_MAX_TC];\r
50 extern unsigned int numEdma3Tc[];\r
51 \r
52 #define DEBUG_PRINTS            0\r
53 #define MAP_ONCE_ONLY           1\r
54 #define ISR_APPROACH_WHILE      1   // 0 would make the code to hang\r
55 \r
56 #if EDMA_LOCAL_COMP_ISR\r
57 #include <ti/csl/soc.h>\r
58 #include <ti/csl/cslr_tpcc.h>\r
59 \r
60 //extern CSL_TpccRegs *tpcc2Regs;\r
61 extern unsigned int tpccRegionUsedLoc;\r
62 \r
63 tccCallbackParams edma3IntrParamsLoc[64];\r
64 unsigned int allocatedTCCsLoc[2u] = {0x0u, 0x0u};\r
65 \r
66 static void edma3ComplHandlerLoc (unsigned int edma3Id);\r
67 #endif\r
68 \r
69 void (*ptrEdma3TcIsrHandler[EDMA3_MAX_TC])(unsigned int arg) =\r
70                                                 {\r
71                                                 &lisrEdma3TC0ErrHandler0,\r
72                                                 &lisrEdma3TC1ErrHandler0,\r
73                                                 &lisrEdma3TC2ErrHandler0,\r
74                                                 &lisrEdma3TC3ErrHandler0,\r
75                                                 &lisrEdma3TC4ErrHandler0,\r
76                                                 &lisrEdma3TC5ErrHandler0,\r
77                                                 &lisrEdma3TC6ErrHandler0,\r
78                                                 &lisrEdma3TC7ErrHandler0,\r
79                                                 };\r
80 \r
81 unsigned int hwiInterrupt = 8;\r
82 \r
83 unsigned int gemEvents[2];\r
84 \r
85 /* Host interrupts for transfer completion (per spec intc_1.3.4.12.xlsx) */\r
86 /* First 4 cores are connected from CP_INTC0 and last 4 cores are connected from CP_INTC1 */\r
87 //unsigned int ccXferHostInt[NUM_EDMA3_INSTANCES][NUM_DSPS] = {\r
88                                                                             /*    CP_INTC0      |     CP_INTC1      */\r
89 unsigned int ccXferHostInt[5][8] = {\r
90                                                                                 {68u, 78u, 88u, 98u, 68u, 78u, 88u, 98u},\r
91                                                                                 {69u, 79u, 89u, 99u, 69u, 79u, 89u, 99u},\r
92                                                                                 {70u, 80u, 90u, 100u, 70u, 80u, 90u, 100u},\r
93                                                                                 {71u, 81u, 91u, 101u, 71u, 81u, 91u, 101u},\r
94                                                                                 {72u, 82u, 92u, 102u, 72u, 82u, 92u, 102u},\r
95                                                                                 };\r
96 unsigned int edma3ErrHostInt[5][8] = {\r
97                                                                                 {73u, 83u, 93u, 103u, 73u, 83u, 93u, 103u},\r
98                                                                                 {64u, 74u, 84u, 94u, 64u, 74u, 84u, 94u},\r
99                                                                                 {65u, 75u, 85u, 95u, 65u, 75u, 85u, 95u},\r
100                                                                                 {66u, 76u, 86u, 96u, 66u, 76u, 86u, 96u},\r
101                                                                                 {67u, 77u, 87u, 97u, 67u, 77u, 87u, 97u},\r
102                                                                                 };\r
103 \r
104 //extern unsigned int dsp_num;\r
105 //extern unsigned int tpccRegionUsed;\r
106 #if USE_LOCAL_CPINTC_DISPATCH\r
107 extern Void CpIntc_dispatchLoc(UInt hostInt);\r
108 #endif\r
109 \r
110 /**  To Register the ISRs with the underlying OS, if required */\r
111 void registerEdma3Interrupts (  unsigned int edma3Id,\r
112                                 unsigned int tpccRegionUsed,\r
113                                 unsigned int dsp_num)\r
114     {\r
115     static UInt32 cookie = 0;\r
116     Int eventId = 0;    /* GEM event id */\r
117         unsigned int numTc = 0;\r
118 #if MAP_ONCE_ONLY\r
119     static UInt32 mapDone = 0;\r
120 #endif\r
121     unsigned int cpIntcNum = WHICH_CPINTC_NUM(dsp_num);//(dsp_num > 3)? 1: 0;\r
122 \r
123     /* Disabling the global interrupts */\r
124     cookie = Hwi_disable();\r
125 \r
126         /* Transfer completion ISR */\r
127         CpIntc_dispatchPlug(ccXferCompInt[edma3Id][tpccRegionUsed],\r
128 #if EDMA_LOCAL_COMP_ISR\r
129                         edma3ComplHandlerLoc,\r
130 #else\r
131                         lisrEdma3ComplHandler0,\r
132 #endif\r
133                         edma3Id,\r
134                                                 TRUE);\r
135 #if MAP_ONCE_ONLY\r
136         if (!mapDone)\r
137 #endif\r
138     CpIntc_mapSysIntToHostInt(cpIntcNum, ccXferCompInt[edma3Id][tpccRegionUsed],\r
139                                                                 ccXferHostInt[edma3Id][dsp_num]);\r
140         CpIntc_enableHostInt(cpIntcNum, ccXferHostInt[edma3Id][dsp_num]);\r
141     eventId = CpIntc_getEventId(ccXferHostInt[edma3Id][dsp_num]);\r
142     EventCombiner_dispatchPlug (eventId,\r
143 #if USE_LOCAL_CPINTC_DISPATCH\r
144                                 CpIntc_dispatchLoc,\r
145 #else\r
146                                 CpIntc_dispatch,\r
147 #endif\r
148                                 ccXferHostInt[edma3Id][dsp_num],\r
149                                 TRUE);\r
150 #if DEBUG_PRINTS\r
151     System_printf("\t\t ccXferCompInt : %d \n", ccXferCompInt[edma3Id][tpccRegionUsed]);\r
152     System_printf("\t\t ccXferHostInt : %d \n", ccXferHostInt[edma3Id][dsp_num]);\r
153     System_printf("\t\t eventId : %d \n", eventId);\r
154 #endif\r
155     gemEvents[0] = eventId;\r
156 \r
157         /* CC Error ISR */\r
158         CpIntc_dispatchPlug(ccErrorInt[edma3Id], lisrEdma3CCErrHandler0,\r
159                                                 edma3Id, TRUE);\r
160 #if MAP_ONCE_ONLY\r
161     if (!mapDone)\r
162 #endif\r
163         CpIntc_mapSysIntToHostInt(cpIntcNum, ccErrorInt[edma3Id],\r
164                                                                 edma3ErrHostInt[edma3Id][dsp_num]);\r
165 #if DEBUG_PRINTS\r
166     System_printf("\t\t ccErrorInt : %d \n", ccErrorInt[edma3Id]);\r
167     System_printf("\t\t edma3ErrHostInt : %d \n", edma3ErrHostInt[edma3Id][dsp_num]);\r
168 #endif\r
169 \r
170         /* TC Error ISR */\r
171     while (numTc < numEdma3Tc[edma3Id])\r
172             {\r
173                 CpIntc_dispatchPlug(tcErrorInt[edma3Id][numTc],\r
174                                                         (CpIntc_FuncPtr )(ptrEdma3TcIsrHandler[numTc]),\r
175                                                         edma3Id, TRUE);\r
176 #if MAP_ONCE_ONLY\r
177     if (!mapDone)\r
178 #endif\r
179                 CpIntc_mapSysIntToHostInt(cpIntcNum, tcErrorInt[edma3Id][numTc],\r
180                                                                         edma3ErrHostInt[edma3Id][dsp_num]);\r
181 #if DEBUG_PRINTS\r
182     System_printf("\t\t tcErrorInt : %d \n", tcErrorInt[edma3Id][numTc]);\r
183     System_printf("\t\t edma3ErrHostInt : %d \n", edma3ErrHostInt[edma3Id][dsp_num]);\r
184 #endif\r
185         numTc++;\r
186         }\r
187         /* Enable the host interrupt which is common for both CC and TC error */\r
188         CpIntc_enableHostInt(cpIntcNum, edma3ErrHostInt[edma3Id][dsp_num]);\r
189     eventId = CpIntc_getEventId(edma3ErrHostInt[edma3Id][dsp_num]);\r
190     EventCombiner_dispatchPlug (eventId,\r
191 #if USE_LOCAL_CPINTC_DISPATCH\r
192                                 CpIntc_dispatchLoc,\r
193 #else\r
194                                 CpIntc_dispatch,\r
195 #endif\r
196                                 edma3ErrHostInt[edma3Id][dsp_num],\r
197                                 TRUE);\r
198 #if DEBUG_PRINTS\r
199     System_printf("\t\t eventId : %d \n", eventId);\r
200 #endif\r
201     gemEvents[1] = eventId;\r
202 \r
203     //Hwi_enableInterrupt(hwiInterrupt);\r
204 \r
205     /* enable the 'global' switch */\r
206     CpIntc_enableAllHostInts(cpIntcNum);\r
207 \r
208 #if EDMA_LOCAL_COMP_ISR\r
209     tpccRegionUsedLoc = tpccRegionUsed;\r
210 #endif\r
211 \r
212 #if MAP_ONCE_ONLY\r
213     mapDone = 1;\r
214 #endif\r
215 \r
216     /* Restore interrupts */\r
217     Hwi_restore(cookie);\r
218     }\r
219 \r
220 /**  To Unregister the ISRs with the underlying OS, if previously registered. */\r
221 void unregisterEdma3Interrupts (unsigned int edma3Id, unsigned int dsp_num)\r
222     {\r
223     static UInt32 cookie = 0;\r
224     Int eventId = 0;    /* GEM event id */\r
225 //    unsigned int numTc = 0;\r
226     unsigned int cpIntcNum = WHICH_CPINTC_NUM(dsp_num);//(dsp_num > 3)? 1: 0;\r
227 \r
228     /* Disabling the global interrupts */\r
229     cookie = Hwi_disable();\r
230 \r
231         /* Transfer completion ISR */\r
232         CpIntc_disableHostInt(cpIntcNum, ccXferHostInt[edma3Id][dsp_num]);\r
233     eventId = CpIntc_getEventId(ccXferHostInt[edma3Id][dsp_num]);\r
234         EventCombiner_disableEvent(eventId);\r
235 \r
236         /* CC/TC Error ISR */\r
237         CpIntc_disableHostInt(cpIntcNum, edma3ErrHostInt[edma3Id][dsp_num]);\r
238     eventId = CpIntc_getEventId(edma3ErrHostInt[edma3Id][dsp_num]);\r
239         EventCombiner_disableEvent(eventId);\r
240 \r
241     /**\r
242      * Clear all system interrupt to host interrupt mapping.\r
243      * - might not be needed\r
244      * - doing to get clean numbers from cpintc dispatcher for debugging\r
245      * - DID NOT HELP, so commenting for now\r
246      */\r
247 //    CpIntc_mapSysIntToHostInt(cpIntcNum, ccXferCompInt[edma3Id][tpccRegionUsedLoc], 0);\r
248 //    CpIntc_mapSysIntToHostInt(cpIntcNum, ccErrorInt[edma3Id], 0);\r
249 //    while (numTc < numEdma3Tc[edma3Id])\r
250 //        {\r
251 //        CpIntc_mapSysIntToHostInt(cpIntcNum, tcErrorInt[edma3Id][numTc], 0);\r
252 //        numTc++;\r
253 //        }\r
254 \r
255     /* Restore interrupts */\r
256     Hwi_restore(cookie);\r
257     }\r
258 \r
259 #if EDMA_LOCAL_COMP_ISR\r
260 /**\r
261  * edma3ComplHandler\r
262  * \brief   Interrupt handler for successful transfer completion.\r
263  *\r
264  * \note    This function first disables its own interrupt to make it non-\r
265  *          entrant. Later, after calling all the callback functions, it\r
266  *          re-enables its own interrupt.\r
267  *\r
268  * \return  None.\r
269  */\r
270 UInt32 tpccIsrCntr = 0;\r
271 UInt32 tpccCbCntr = 0;\r
272 static void edma3ComplHandlerLoc (unsigned int edma3Id)\r
273     {\r
274 #if !ISR_APPROACH_WHILE\r
275     unsigned int Cnt;\r
276 #endif\r
277     volatile CSL_TPCC_ShadowRegs *shadowRegs = NULL;\r
278     volatile unsigned int pendingIrqs;\r
279     unsigned int indexl;\r
280     unsigned int indexh;\r
281     CSL_TpccRegs *tpcc2Regs = (CSL_TpccRegs *) CSL_EDMACC_2_REGS;\r
282 \r
283     tpccIsrCntr++;\r
284 \r
285     if (tpcc2Regs != NULL)\r
286         {\r
287         shadowRegs = (volatile CSL_TPCC_ShadowRegs *)\r
288                                     (&tpcc2Regs->SHADOW[tpccRegionUsedLoc]);\r
289         }\r
290 \r
291 #if !ISR_APPROACH_WHILE\r
292     Cnt = 0u;\r
293 #endif\r
294     pendingIrqs = 0u;\r
295     indexl = 1u;\r
296     indexh = 1u;\r
297 \r
298 #if ISR_APPROACH_WHILE\r
299     while((shadowRegs->TPCC_IPR !=0 ) || (shadowRegs->TPCC_IPRH !=0 ))\r
300         {\r
301         /* Loop for EDMA3_RM_COMPL_HANDLER_RETRY_COUNT number of time,\r
302            breaks when no pending interrupt is found */\r
303             indexl = 0u;\r
304             pendingIrqs = shadowRegs->TPCC_IPR;\r
305 \r
306             /**\r
307              * Choose interrupts coming from our allocated TCCs\r
308              * and MASK remaining ones.\r
309              */\r
310             pendingIrqs = (pendingIrqs & allocatedTCCsLoc[0u]);\r
311 \r
312             while (pendingIrqs)\r
313                 {\r
314                 /*Process all the pending interrupts*/\r
315                 if((pendingIrqs & 1u) == TRUE)\r
316                     {\r
317                     /**\r
318                      * If the user has not given any callback function\r
319                      * while requesting the TCC, its TCC specific bit\r
320                      * in the IPR register will NOT be cleared.\r
321                      */\r
322                     if(edma3IntrParamsLoc[indexl].tccCb != NULL)\r
323                         {\r
324                          /* here write to ICR to clear the corresponding IPR bits*/\r
325                         shadowRegs->TPCC_ICR = (1u << indexl);\r
326 \r
327                                 tpccCbCntr++;\r
328                                 \r
329                         edma3IntrParamsLoc[indexl].tccCb (indexl,\r
330                                     EDMA3_RM_XFER_COMPLETE,\r
331                                     edma3IntrParamsLoc[indexl].cbData);\r
332                         }\r
333                     }\r
334                 ++indexl;\r
335                 pendingIrqs >>= 1u;\r
336                 }\r
337 \r
338             indexh = 0u;\r
339             pendingIrqs = shadowRegs->TPCC_IPRH;\r
340 \r
341             /**\r
342              * Choose interrupts coming from our allocated TCCs\r
343              * and MASK remaining ones.\r
344              */\r
345             pendingIrqs = (pendingIrqs & allocatedTCCsLoc[1u]);\r
346 \r
347             while (pendingIrqs)\r
348                 {\r
349                 /*Process all the pending interrupts*/\r
350                 if((pendingIrqs & 1u)==TRUE)\r
351                     {\r
352                     /**\r
353                      * If the user has not given any callback function\r
354                      * while requesting the TCC, its TCC specific bit\r
355                      * in the IPRH register will NOT be cleared.\r
356                      */\r
357                     if(edma3IntrParamsLoc[32u+indexh].tccCb!=NULL)\r
358                         {\r
359                          /* here write to ICR to clear the corresponding IPR bits*/\r
360                         shadowRegs->TPCC_ICRH = (1u << indexh);\r
361 \r
362                         edma3IntrParamsLoc[32u+indexh].tccCb(32u+indexh,\r
363                                     EDMA3_RM_XFER_COMPLETE,\r
364                                     edma3IntrParamsLoc[32u+indexh].cbData);\r
365                         }\r
366                     }\r
367                 ++indexh;\r
368                 pendingIrqs >>= 1u;\r
369                 }\r
370         }\r
371 #else // ISR_APPROACH_WHILE\r
372     if((shadowRegs->TPCC_IPR !=0 ) || (shadowRegs->TPCC_IPRH !=0 ))\r
373         {\r
374         /**\r
375          * Since an interrupt has found, we have to make sure that this\r
376          * interrupt (TCC) belongs to the TCCs allocated by us only.\r
377          * It might happen that someone else, who is using EDMA3 also,\r
378          * is the owner of this interrupt channel i.e. the TCC.\r
379          * For this, use the allocatedTCCs[], to check which all interrupt\r
380          * channels are owned by the EDMA3 RM Instances.\r
381          */\r
382 \r
383         edma3OsProtectEntry (edma3Id,\r
384                             EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION,\r
385                             NULL);\r
386 \r
387         /* Loop for EDMA3_RM_COMPL_HANDLER_RETRY_COUNT number of time,\r
388            breaks when no pending interrupt is found */\r
389         while ((Cnt < 10u)\r
390                     && ((indexl != 0u) || (indexh != 0u)))\r
391             {\r
392             indexl = 0u;\r
393             pendingIrqs = shadowRegs->TPCC_IPR;\r
394 \r
395             /**\r
396              * Choose interrupts coming from our allocated TCCs\r
397              * and MASK remaining ones.\r
398              */\r
399             pendingIrqs = (pendingIrqs & allocatedTCCsLoc[0u]);\r
400 \r
401             while (pendingIrqs)\r
402                 {\r
403                 /*Process all the pending interrupts*/\r
404                 if((pendingIrqs & 1u) == TRUE)\r
405                     {\r
406                     /**\r
407                      * If the user has not given any callback function\r
408                      * while requesting the TCC, its TCC specific bit\r
409                      * in the IPR register will NOT be cleared.\r
410                      */\r
411                     if(edma3IntrParamsLoc[indexl].tccCb != NULL)\r
412                         {\r
413                          /* here write to ICR to clear the corresponding IPR bits*/\r
414                         shadowRegs->TPCC_ICR = (1u << indexl);\r
415 \r
416                                 tpccCbCntr++;\r
417                                 \r
418                         edma3IntrParamsLoc[indexl].tccCb (indexl,\r
419                                     EDMA3_RM_XFER_COMPLETE,\r
420                                     edma3IntrParamsLoc[indexl].cbData);\r
421                         }\r
422                     }\r
423                 ++indexl;\r
424                 pendingIrqs >>= 1u;\r
425                 }\r
426 \r
427             indexh = 0u;\r
428             pendingIrqs = shadowRegs->TPCC_IPRH;\r
429 \r
430             /**\r
431              * Choose interrupts coming from our allocated TCCs\r
432              * and MASK remaining ones.\r
433              */\r
434             pendingIrqs = (pendingIrqs & allocatedTCCsLoc[1u]);\r
435 \r
436             while (pendingIrqs)\r
437                 {\r
438                 /*Process all the pending interrupts*/\r
439                 if((pendingIrqs & 1u)==TRUE)\r
440                     {\r
441                     /**\r
442                      * If the user has not given any callback function\r
443                      * while requesting the TCC, its TCC specific bit\r
444                      * in the IPRH register will NOT be cleared.\r
445                      */\r
446                     if(edma3IntrParamsLoc[32u+indexh].tccCb!=NULL)\r
447                         {\r
448                          /* here write to ICR to clear the corresponding IPR bits*/\r
449                         shadowRegs->TPCC_ICRH = (1u << indexh);\r
450 \r
451                         edma3IntrParamsLoc[32u+indexh].tccCb(32u+indexh,\r
452                                     EDMA3_RM_XFER_COMPLETE,\r
453                                     edma3IntrParamsLoc[32u+indexh].cbData);\r
454                         }\r
455                     }\r
456                 ++indexh;\r
457                 pendingIrqs >>= 1u;\r
458                 }\r
459 \r
460             Cnt++;\r
461             }\r
462 \r
463         indexl = (shadowRegs->TPCC_IPR & allocatedTCCsLoc[0u]);\r
464         indexh = (shadowRegs->TPCC_IPRH & allocatedTCCsLoc[1u]);\r
465 \r
466         if((indexl !=0 ) || (indexh !=0 ))\r
467             {\r
468             shadowRegs->TPCC_IEVAL=0x1u;\r
469             }\r
470 \r
471         edma3OsProtectExit (edma3Id,\r
472                             EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION,\r
473                             NULL);\r
474         }\r
475         /* for testing only */\r
476         else\r
477         {\r
478             while(1);\r
479         }\r
480 #endif // ISR_APPROACH_WHILE\r
481     }\r
482 #endif // EDMA_LOCAL_COMP_ISR\r