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