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 #include "tcp3d_drv_sample.h"\r
47 \r
48 extern unsigned int ccXferCompInt[][EDMA3_MAX_REGIONS];\r
49 extern unsigned int ccErrorInt[];\r
50 extern unsigned int tcErrorInt[][EDMA3_MAX_TC];\r
51 extern unsigned int numEdma3Tc[];\r
52 \r
53 #define DEBUG_PRINTS 0\r
54 #define MAP_ONCE_ONLY 1\r
55 #define ISR_APPROACH_WHILE 1 // 0 would make the code to hang\r
56 \r
57 #if EDMA_LOCAL_COMP_ISR\r
58 #include <ti/csl/soc.h>\r
59 #include <ti/csl/cslr_tpcc.h>\r
60 \r
61 //extern CSL_TpccRegs *tpcc2Regs;\r
62 extern unsigned int tpccRegionUsedLoc;\r
63 \r
64 tccCallbackParams edma3IntrParamsLoc[64];\r
65 unsigned int allocatedTCCsLoc[2u] = {0x0u, 0x0u};\r
66 \r
67 static void edma3ComplHandlerLoc (unsigned int edma3Id);\r
68 #endif\r
69 \r
70 void (*ptrEdma3TcIsrHandler[EDMA3_MAX_TC])(unsigned int arg) =\r
71 {\r
72 &lisrEdma3TC0ErrHandler0,\r
73 &lisrEdma3TC1ErrHandler0,\r
74 &lisrEdma3TC2ErrHandler0,\r
75 &lisrEdma3TC3ErrHandler0,\r
76 &lisrEdma3TC4ErrHandler0,\r
77 &lisrEdma3TC5ErrHandler0,\r
78 &lisrEdma3TC6ErrHandler0,\r
79 &lisrEdma3TC7ErrHandler0,\r
80 };\r
81 \r
82 unsigned int hwiInterrupt = 8;\r
83 \r
84 unsigned int gemEvents[2];\r
85 \r
86 /* Host interrupts for transfer completion (per spec intc_1.3.4.12.xlsx) */\r
87 /* First 4 cores are connected from CP_INTC0 and last 4 cores are connected from CP_INTC1 */\r
88 //unsigned int ccXferHostInt[NUM_EDMA3_INSTANCES][NUM_DSPS] = {\r
89 /* CP_INTC0 | CP_INTC1 */\r
90 #ifndef SOC_C6657\r
91 unsigned int ccXferHostInt[5][8] = {\r
92 {68u, 78u, 88u, 98u, 68u, 78u, 88u, 98u},\r
93 {69u, 79u, 89u, 99u, 69u, 79u, 89u, 99u},\r
94 {70u, 80u, 90u, 100u, 70u, 80u, 90u, 100u},\r
95 {71u, 81u, 91u, 101u, 71u, 81u, 91u, 101u},\r
96 {72u, 82u, 92u, 102u, 72u, 82u, 92u, 102u},\r
97 };\r
98 unsigned int edma3ErrHostInt[5][8] = {\r
99 {73u, 83u, 93u, 103u, 73u, 83u, 93u, 103u},\r
100 {64u, 74u, 84u, 94u, 64u, 74u, 84u, 94u},\r
101 {65u, 75u, 85u, 95u, 65u, 75u, 85u, 95u},\r
102 {66u, 76u, 86u, 96u, 66u, 76u, 86u, 96u},\r
103 {67u, 77u, 87u, 97u, 67u, 77u, 87u, 97u},\r
104 };\r
105 \r
106 #else /* SOC_C6657 */\r
107 /* only CP_INTC0 for C6657 */\r
108 \r
109 unsigned int ccXferHostInt[5][8] = {\r
110 {0u, 20u, 255u, 255u, 255u, 255u, 255u, 255u},\r
111 {1u, 21u, 255u, 255u, 255u, 255u, 255u, 255u},\r
112 {2u, 22u, 255u, 255u, 255u, 255u, 255u, 255u},\r
113 {3u, 23u, 255u, 255u, 255u, 255u, 255u, 255u},\r
114 {4u, 24u, 255u, 255u, 255u, 255u, 255u, 255u},\r
115 };\r
116 unsigned int edma3ErrHostInt[5][8] = {\r
117 {6u, 26u, 255u, 255u, 255u, 255u, 255u, 255u},\r
118 {7u, 27u, 255u, 255u, 255u, 255u, 255u, 255u},\r
119 {5u, 25u, 255u, 255u, 255u, 255u, 255u, 255u},\r
120 {8u, 28u, 255u, 255u, 255u, 255u, 255u, 255u},\r
121 {9u, 29u, 255u, 255u, 255u, 255u, 255u, 255u},\r
122 };\r
123 #endif\r
124 \r
125 //extern unsigned int dsp_num;\r
126 //extern unsigned int tpccRegionUsed;\r
127 #if USE_LOCAL_CPINTC_DISPATCH\r
128 extern Void CpIntc_dispatchLoc(UInt hostInt);\r
129 #endif\r
130 \r
131 /** To Register the ISRs with the underlying OS, if required */\r
132 void registerEdma3Interrupts ( unsigned int edma3Id,\r
133 unsigned int tpccRegionUsed,\r
134 unsigned int dsp_num)\r
135 {\r
136 static UInt32 cookie = 0;\r
137 Int eventId = 0; /* GEM event id */\r
138 unsigned int numTc = 0;\r
139 #if MAP_ONCE_ONLY\r
140 static UInt32 mapDone = 0;\r
141 #endif\r
142 unsigned int cpIntcNum = WHICH_CPINTC_NUM(dsp_num);//(dsp_num > 3)? 1: 0;\r
143 \r
144 /* Disabling the global interrupts */\r
145 cookie = Hwi_disable();\r
146 \r
147 /* Transfer completion ISR */\r
148 CpIntc_dispatchPlug(ccXferCompInt[edma3Id][tpccRegionUsed],\r
149 #if EDMA_LOCAL_COMP_ISR\r
150 edma3ComplHandlerLoc,\r
151 #else\r
152 lisrEdma3ComplHandler0,\r
153 #endif\r
154 edma3Id,\r
155 TRUE);\r
156 #if MAP_ONCE_ONLY\r
157 if (!mapDone)\r
158 #endif\r
159 CpIntc_mapSysIntToHostInt(cpIntcNum, ccXferCompInt[edma3Id][tpccRegionUsed],\r
160 ccXferHostInt[edma3Id][dsp_num]);\r
161 CpIntc_enableHostInt(cpIntcNum, ccXferHostInt[edma3Id][dsp_num]);\r
162 eventId = CpIntc_getEventId(ccXferHostInt[edma3Id][dsp_num]);\r
163 EventCombiner_dispatchPlug (eventId,\r
164 #if USE_LOCAL_CPINTC_DISPATCH\r
165 CpIntc_dispatchLoc,\r
166 #else\r
167 CpIntc_dispatch,\r
168 #endif\r
169 ccXferHostInt[edma3Id][dsp_num],\r
170 TRUE);\r
171 #if DEBUG_PRINTS\r
172 System_printf("\t\t ccXferCompInt : %d \n", ccXferCompInt[edma3Id][tpccRegionUsed]);\r
173 System_printf("\t\t ccXferHostInt : %d \n", ccXferHostInt[edma3Id][dsp_num]);\r
174 System_printf("\t\t eventId : %d \n", eventId);\r
175 #endif\r
176 gemEvents[0] = eventId;\r
177 \r
178 /* CC Error ISR */\r
179 CpIntc_dispatchPlug(ccErrorInt[edma3Id], lisrEdma3CCErrHandler0,\r
180 edma3Id, TRUE);\r
181 #if MAP_ONCE_ONLY\r
182 if (!mapDone)\r
183 #endif\r
184 CpIntc_mapSysIntToHostInt(cpIntcNum, ccErrorInt[edma3Id],\r
185 edma3ErrHostInt[edma3Id][dsp_num]);\r
186 #if DEBUG_PRINTS\r
187 System_printf("\t\t ccErrorInt : %d \n", ccErrorInt[edma3Id]);\r
188 System_printf("\t\t edma3ErrHostInt : %d \n", edma3ErrHostInt[edma3Id][dsp_num]);\r
189 #endif\r
190 \r
191 /* TC Error ISR */\r
192 while (numTc < numEdma3Tc[edma3Id])\r
193 {\r
194 CpIntc_dispatchPlug(tcErrorInt[edma3Id][numTc],\r
195 (CpIntc_FuncPtr )(ptrEdma3TcIsrHandler[numTc]),\r
196 edma3Id, TRUE);\r
197 #if MAP_ONCE_ONLY\r
198 if (!mapDone)\r
199 #endif\r
200 CpIntc_mapSysIntToHostInt(cpIntcNum, tcErrorInt[edma3Id][numTc],\r
201 edma3ErrHostInt[edma3Id][dsp_num]);\r
202 #if DEBUG_PRINTS\r
203 System_printf("\t\t tcErrorInt : %d \n", tcErrorInt[edma3Id][numTc]);\r
204 System_printf("\t\t edma3ErrHostInt : %d \n", edma3ErrHostInt[edma3Id][dsp_num]);\r
205 #endif\r
206 numTc++;\r
207 }\r
208 /* Enable the host interrupt which is common for both CC and TC error */\r
209 CpIntc_enableHostInt(cpIntcNum, edma3ErrHostInt[edma3Id][dsp_num]);\r
210 eventId = CpIntc_getEventId(edma3ErrHostInt[edma3Id][dsp_num]);\r
211 EventCombiner_dispatchPlug (eventId,\r
212 #if USE_LOCAL_CPINTC_DISPATCH\r
213 CpIntc_dispatchLoc,\r
214 #else\r
215 CpIntc_dispatch,\r
216 #endif\r
217 edma3ErrHostInt[edma3Id][dsp_num],\r
218 TRUE);\r
219 #if DEBUG_PRINTS\r
220 System_printf("\t\t eventId : %d \n", eventId);\r
221 #endif\r
222 gemEvents[1] = eventId;\r
223 \r
224 //Hwi_enableInterrupt(hwiInterrupt);\r
225 \r
226 /* enable the 'global' switch */\r
227 CpIntc_enableAllHostInts(cpIntcNum);\r
228 \r
229 #if EDMA_LOCAL_COMP_ISR\r
230 tpccRegionUsedLoc = tpccRegionUsed;\r
231 #endif\r
232 \r
233 #if MAP_ONCE_ONLY\r
234 mapDone = 1;\r
235 #endif\r
236 \r
237 /* Restore interrupts */\r
238 Hwi_restore(cookie);\r
239 }\r
240 \r
241 /** To Unregister the ISRs with the underlying OS, if previously registered. */\r
242 void unregisterEdma3Interrupts (unsigned int edma3Id, unsigned int dsp_num)\r
243 {\r
244 static UInt32 cookie = 0;\r
245 Int eventId = 0; /* GEM event id */\r
246 // unsigned int numTc = 0;\r
247 unsigned int cpIntcNum = WHICH_CPINTC_NUM(dsp_num);//(dsp_num > 3)? 1: 0;\r
248 \r
249 /* Disabling the global interrupts */\r
250 cookie = Hwi_disable();\r
251 \r
252 /* Transfer completion ISR */\r
253 CpIntc_disableHostInt(cpIntcNum, ccXferHostInt[edma3Id][dsp_num]);\r
254 eventId = CpIntc_getEventId(ccXferHostInt[edma3Id][dsp_num]);\r
255 EventCombiner_disableEvent(eventId);\r
256 \r
257 /* CC/TC Error ISR */\r
258 CpIntc_disableHostInt(cpIntcNum, edma3ErrHostInt[edma3Id][dsp_num]);\r
259 eventId = CpIntc_getEventId(edma3ErrHostInt[edma3Id][dsp_num]);\r
260 EventCombiner_disableEvent(eventId);\r
261 \r
262 /**\r
263 * Clear all system interrupt to host interrupt mapping.\r
264 * - might not be needed\r
265 * - doing to get clean numbers from cpintc dispatcher for debugging\r
266 * - DID NOT HELP, so commenting for now\r
267 */\r
268 // CpIntc_mapSysIntToHostInt(cpIntcNum, ccXferCompInt[edma3Id][tpccRegionUsedLoc], 0);\r
269 // CpIntc_mapSysIntToHostInt(cpIntcNum, ccErrorInt[edma3Id], 0);\r
270 // while (numTc < numEdma3Tc[edma3Id])\r
271 // {\r
272 // CpIntc_mapSysIntToHostInt(cpIntcNum, tcErrorInt[edma3Id][numTc], 0);\r
273 // numTc++;\r
274 // }\r
275 \r
276 /* Restore interrupts */\r
277 Hwi_restore(cookie);\r
278 }\r
279 \r
280 #if EDMA_LOCAL_COMP_ISR\r
281 /**\r
282 * edma3ComplHandler\r
283 * \brief Interrupt handler for successful transfer completion.\r
284 *\r
285 * \note This function first disables its own interrupt to make it non-\r
286 * entrant. Later, after calling all the callback functions, it\r
287 * re-enables its own interrupt.\r
288 *\r
289 * \return None.\r
290 */\r
291 UInt32 tpccIsrCntr = 0;\r
292 UInt32 tpccCbCntr = 0;\r
293 static void edma3ComplHandlerLoc (unsigned int edma3Id)\r
294 {\r
295 #if !ISR_APPROACH_WHILE\r
296 unsigned int Cnt;\r
297 #endif\r
298 volatile CSL_TPCC_ShadowRegs *shadowRegs = NULL;\r
299 volatile unsigned int pendingIrqs;\r
300 unsigned int indexl;\r
301 unsigned int indexh;\r
302 CSL_TpccRegs *tpcc2Regs = (CSL_TpccRegs *) CSL_EDMACC_2_REGS;\r
303 \r
304 tpccIsrCntr++;\r
305 \r
306 if (tpcc2Regs != NULL)\r
307 {\r
308 shadowRegs = (volatile CSL_TPCC_ShadowRegs *)\r
309 (&tpcc2Regs->SHADOW[tpccRegionUsedLoc]);\r
310 }\r
311 \r
312 #if !ISR_APPROACH_WHILE\r
313 Cnt = 0u;\r
314 #endif\r
315 pendingIrqs = 0u;\r
316 indexl = 1u;\r
317 indexh = 1u;\r
318 \r
319 #if ISR_APPROACH_WHILE\r
320 while((shadowRegs->TPCC_IPR !=0 ) || (shadowRegs->TPCC_IPRH !=0 ))\r
321 {\r
322 /* Loop for EDMA3_RM_COMPL_HANDLER_RETRY_COUNT number of time,\r
323 breaks when no pending interrupt is found */\r
324 indexl = 0u;\r
325 pendingIrqs = shadowRegs->TPCC_IPR;\r
326 \r
327 /**\r
328 * Choose interrupts coming from our allocated TCCs\r
329 * and MASK remaining ones.\r
330 */\r
331 pendingIrqs = (pendingIrqs & allocatedTCCsLoc[0u]);\r
332 \r
333 while (pendingIrqs)\r
334 {\r
335 /*Process all the pending interrupts*/\r
336 if((pendingIrqs & 1u) == TRUE)\r
337 {\r
338 /**\r
339 * If the user has not given any callback function\r
340 * while requesting the TCC, its TCC specific bit\r
341 * in the IPR register will NOT be cleared.\r
342 */\r
343 if(edma3IntrParamsLoc[indexl].tccCb != NULL)\r
344 {\r
345 /* here write to ICR to clear the corresponding IPR bits*/\r
346 shadowRegs->TPCC_ICR = (1u << indexl);\r
347 \r
348 tpccCbCntr++;\r
349 \r
350 edma3IntrParamsLoc[indexl].tccCb (indexl,\r
351 EDMA3_RM_XFER_COMPLETE,\r
352 edma3IntrParamsLoc[indexl].cbData);\r
353 }\r
354 }\r
355 ++indexl;\r
356 pendingIrqs >>= 1u;\r
357 }\r
358 \r
359 indexh = 0u;\r
360 pendingIrqs = shadowRegs->TPCC_IPRH;\r
361 \r
362 /**\r
363 * Choose interrupts coming from our allocated TCCs\r
364 * and MASK remaining ones.\r
365 */\r
366 pendingIrqs = (pendingIrqs & allocatedTCCsLoc[1u]);\r
367 \r
368 while (pendingIrqs)\r
369 {\r
370 /*Process all the pending interrupts*/\r
371 if((pendingIrqs & 1u)==TRUE)\r
372 {\r
373 /**\r
374 * If the user has not given any callback function\r
375 * while requesting the TCC, its TCC specific bit\r
376 * in the IPRH register will NOT be cleared.\r
377 */\r
378 if(edma3IntrParamsLoc[32u+indexh].tccCb!=NULL)\r
379 {\r
380 /* here write to ICR to clear the corresponding IPR bits*/\r
381 shadowRegs->TPCC_ICRH = (1u << indexh);\r
382 \r
383 edma3IntrParamsLoc[32u+indexh].tccCb(32u+indexh,\r
384 EDMA3_RM_XFER_COMPLETE,\r
385 edma3IntrParamsLoc[32u+indexh].cbData);\r
386 }\r
387 }\r
388 ++indexh;\r
389 pendingIrqs >>= 1u;\r
390 }\r
391 }\r
392 #else // ISR_APPROACH_WHILE\r
393 if((shadowRegs->TPCC_IPR !=0 ) || (shadowRegs->TPCC_IPRH !=0 ))\r
394 {\r
395 /**\r
396 * Since an interrupt has found, we have to make sure that this\r
397 * interrupt (TCC) belongs to the TCCs allocated by us only.\r
398 * It might happen that someone else, who is using EDMA3 also,\r
399 * is the owner of this interrupt channel i.e. the TCC.\r
400 * For this, use the allocatedTCCs[], to check which all interrupt\r
401 * channels are owned by the EDMA3 RM Instances.\r
402 */\r
403 \r
404 edma3OsProtectEntry (edma3Id,\r
405 EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION,\r
406 NULL);\r
407 \r
408 /* Loop for EDMA3_RM_COMPL_HANDLER_RETRY_COUNT number of time,\r
409 breaks when no pending interrupt is found */\r
410 while ((Cnt < 10u)\r
411 && ((indexl != 0u) || (indexh != 0u)))\r
412 {\r
413 indexl = 0u;\r
414 pendingIrqs = shadowRegs->TPCC_IPR;\r
415 \r
416 /**\r
417 * Choose interrupts coming from our allocated TCCs\r
418 * and MASK remaining ones.\r
419 */\r
420 pendingIrqs = (pendingIrqs & allocatedTCCsLoc[0u]);\r
421 \r
422 while (pendingIrqs)\r
423 {\r
424 /*Process all the pending interrupts*/\r
425 if((pendingIrqs & 1u) == TRUE)\r
426 {\r
427 /**\r
428 * If the user has not given any callback function\r
429 * while requesting the TCC, its TCC specific bit\r
430 * in the IPR register will NOT be cleared.\r
431 */\r
432 if(edma3IntrParamsLoc[indexl].tccCb != NULL)\r
433 {\r
434 /* here write to ICR to clear the corresponding IPR bits*/\r
435 shadowRegs->TPCC_ICR = (1u << indexl);\r
436 \r
437 tpccCbCntr++;\r
438 \r
439 edma3IntrParamsLoc[indexl].tccCb (indexl,\r
440 EDMA3_RM_XFER_COMPLETE,\r
441 edma3IntrParamsLoc[indexl].cbData);\r
442 }\r
443 }\r
444 ++indexl;\r
445 pendingIrqs >>= 1u;\r
446 }\r
447 \r
448 indexh = 0u;\r
449 pendingIrqs = shadowRegs->TPCC_IPRH;\r
450 \r
451 /**\r
452 * Choose interrupts coming from our allocated TCCs\r
453 * and MASK remaining ones.\r
454 */\r
455 pendingIrqs = (pendingIrqs & allocatedTCCsLoc[1u]);\r
456 \r
457 while (pendingIrqs)\r
458 {\r
459 /*Process all the pending interrupts*/\r
460 if((pendingIrqs & 1u)==TRUE)\r
461 {\r
462 /**\r
463 * If the user has not given any callback function\r
464 * while requesting the TCC, its TCC specific bit\r
465 * in the IPRH register will NOT be cleared.\r
466 */\r
467 if(edma3IntrParamsLoc[32u+indexh].tccCb!=NULL)\r
468 {\r
469 /* here write to ICR to clear the corresponding IPR bits*/\r
470 shadowRegs->TPCC_ICRH = (1u << indexh);\r
471 \r
472 edma3IntrParamsLoc[32u+indexh].tccCb(32u+indexh,\r
473 EDMA3_RM_XFER_COMPLETE,\r
474 edma3IntrParamsLoc[32u+indexh].cbData);\r
475 }\r
476 }\r
477 ++indexh;\r
478 pendingIrqs >>= 1u;\r
479 }\r
480 \r
481 Cnt++;\r
482 }\r
483 \r
484 indexl = (shadowRegs->TPCC_IPR & allocatedTCCsLoc[0u]);\r
485 indexh = (shadowRegs->TPCC_IPRH & allocatedTCCsLoc[1u]);\r
486 \r
487 if((indexl !=0 ) || (indexh !=0 ))\r
488 {\r
489 shadowRegs->TPCC_IEVAL=0x1u;\r
490 }\r
491 \r
492 edma3OsProtectExit (edma3Id,\r
493 EDMA3_OS_PROTECT_INTERRUPT_XFER_COMPLETION,\r
494 NULL);\r
495 }\r
496 /* for testing only */\r
497 else\r
498 {\r
499 while(1);\r
500 }\r
501 #endif // ISR_APPROACH_WHILE\r
502 }\r
503 #endif // EDMA_LOCAL_COMP_ISR\r