]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - src/ti/sdo/ipc/family/ti81xx/InterruptDucati.c
Added linux-side executable, libraries and object files to the .gitignore list
[ipc/ipcdev.git] / src / ti / sdo / ipc / family / ti81xx / InterruptDucati.c
1 /*
2  * Copyright (c) 2012-2013, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /*
33  *  ======== InterruptDucati.c ========
34  *  Ducati/TI81xx based interupt manager
35  */
37 #include <xdc/std.h>
38 #include <xdc/runtime/Assert.h>
40 #include <ti/sysbios/BIOS.h>
41 #include <ti/sysbios/family/arm/m3/Hwi.h>
42 #include <ti/sysbios/family/arm/ducati/Core.h>
43 #include <ti/sdo/ipc/notifyDrivers/IInterrupt.h>
44 #include <ti/sdo/ipc/_Ipc.h>
45 #include <ti/sdo/utils/_MultiProc.h>
47 #include "package/internal/InterruptDucati.xdc.h"
49 /* Register access method. */
50 #define REG16(A)   (*(volatile UInt16 *) (A))
51 #define REG32(A)   (*(volatile UInt32 *) (A))
53 /*
54  *  Ducati control register that maintains inter-core interrupt bits.
55  *
56  *  Using separate VIDEO and VPSS values to do 16-bit reads/writes
57  *  because we do not want to overwrite the other cores value.
58  */
59 #define INTERRUPT_VIDEO           (InterruptDucati_ducatiCtrlBaseAddr)
60 #define INTERRUPT_VPSS            (InterruptDucati_ducatiCtrlBaseAddr + 2)
62 /* Assigned mailboxes */
63 #define DSP_TO_HOST      0
64 #define DSP_TO_VIDEO     1
65 #define DSP_TO_VPSS      2
66 #define HOST_TO_DSP      3
67 #define HOST_TO_VIDEO    4
68 #define HOST_TO_VPSS     5
69 #define VIDEO_TO_HOST    6
70 #define VIDEO_TO_DSP     7
71 #define VPSS_TO_HOST     8
72 #define VPSS_TO_DSP      9
74 #define MAILBOX_REG_VAL(M)   (0x1 << (2 * M))
76 #define MAILBOX_MESSAGE(M) (InterruptDucati_mailboxBaseAddr + 0x040 + (0x4 * M))
77 #define MAILBOX_STATUS(M)  (InterruptDucati_mailboxBaseAddr + 0x0C0 + (0x4 * M))
79 /* VIDEO registers */
80 #define MAILBOX_IRQSTATUS_CLR_VIDEO    (InterruptDucati_mailboxBaseAddr + 0x124)
81 #define MAILBOX_IRQENABLE_SET_VIDEO    (InterruptDucati_mailboxBaseAddr + 0x128)
82 #define MAILBOX_IRQENABLE_CLR_VIDEO    (InterruptDucati_mailboxBaseAddr + 0x12C)
84 /* VPSS registers */
85 #define MAILBOX_IRQSTATUS_CLR_VPSS     (InterruptDucati_mailboxBaseAddr + 0x134)
86 #define MAILBOX_IRQENABLE_SET_VPSS     (InterruptDucati_mailboxBaseAddr + 0x138)
87 #define MAILBOX_IRQENABLE_CLR_VPSS     (InterruptDucati_mailboxBaseAddr + 0x13C)
89 #define HOSTINT                77
90 #define M3VIDEOINT             53
91 #define M3DSSINT               54
92 #define DSPINT                 56
93 #define M3INT                  19
95 /*
96  *************************************************************************
97  *                      Module functions
98  *************************************************************************
99  */
101 /*!
102  *  ======== InterruptDucati_intEnable ========
103  *  Enable remote processor interrupt
104  */
105 Void InterruptDucati_intEnable(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo)
107     /*
108      *  If the remote processor communicates via mailboxes, we should enable
109      *  the Mailbox IRQ instead of enabling the Hwi because multiple mailboxes
110      *  share the same Hwi
111      */
112     if ((BIOS_smpEnabled) || (Core_getId() == 0)) {
113         if (remoteProcId == InterruptDucati_hostProcId) {
114             REG32(MAILBOX_IRQENABLE_SET_VIDEO) = MAILBOX_REG_VAL(HOST_TO_VIDEO);
115         }
116         else if (remoteProcId == InterruptDucati_dspProcId) {
117             REG32(MAILBOX_IRQENABLE_SET_VIDEO) = MAILBOX_REG_VAL(DSP_TO_VIDEO);
118         }
119         else {
120             Hwi_enableInterrupt(M3INT);
121         }
122     }
123     else {
124         if (remoteProcId == InterruptDucati_hostProcId) {
125             REG32(MAILBOX_IRQENABLE_SET_VPSS) = MAILBOX_REG_VAL(HOST_TO_VPSS);
126         }
127         else if (remoteProcId == InterruptDucati_dspProcId) {
128             REG32(MAILBOX_IRQENABLE_SET_VPSS) = MAILBOX_REG_VAL(DSP_TO_VPSS);
129         }
130         else {
131             Hwi_enableInterrupt(M3INT);
132         }
133     }
136 /*!
137  *  ======== InterruptDucati_intDisable ========
138  *  Disables remote processor interrupt
139  */
140 Void InterruptDucati_intDisable(UInt16 remoteProcId,
141                                 IInterrupt_IntInfo *intInfo)
143     /*
144      *  If the remote processor communicates via mailboxes, we should disable
145      *  the Mailbox IRQ instead of disabling the Hwi because multiple mailboxes
146      *  share the same Hwi
147      */
148     if ((BIOS_smpEnabled) || (Core_getId() == 0)) {
149         if (remoteProcId == InterruptDucati_hostProcId) {
150             REG32(MAILBOX_IRQENABLE_CLR_VIDEO) = MAILBOX_REG_VAL(HOST_TO_VIDEO);
151         }
152         else if (remoteProcId == InterruptDucati_dspProcId) {
153             REG32(MAILBOX_IRQENABLE_CLR_VIDEO) = MAILBOX_REG_VAL(DSP_TO_VIDEO);
154         }
155         else {
156             Hwi_disableInterrupt(M3INT);
157         }
158     }
159     else {
160         if (remoteProcId == InterruptDucati_hostProcId) {
161             REG32(MAILBOX_IRQENABLE_CLR_VPSS) = MAILBOX_REG_VAL(HOST_TO_VPSS);
162         }
163         else if (remoteProcId == InterruptDucati_dspProcId) {
164             REG32(MAILBOX_IRQENABLE_CLR_VPSS) = MAILBOX_REG_VAL(DSP_TO_VPSS);
165         }
166         else {
167             Hwi_disableInterrupt(M3INT);
168         }
169     }
172 /*!
173  *  ======== InterruptDucati_intRegister ========
174  */
175 Void InterruptDucati_intRegister(UInt16 remoteProcId,
176                                  IInterrupt_IntInfo *intInfo,
177                                  Fxn func, UArg arg)
179     Hwi_Params  hwiAttrs;
180     UInt        key;
181     Int         index;
182     InterruptDucati_FxnTable *table;
184     Assert_isTrue(remoteProcId < ti_sdo_utils_MultiProc_numProcessors,
185             ti_sdo_ipc_Ipc_A_internal);
187     /* Assert that our MultiProc id is set correctly */
188     Assert_isTrue((InterruptDucati_videoProcId == MultiProc_self()) ||
189                   (InterruptDucati_vpssProcId == MultiProc_self()),
190                   ti_sdo_ipc_Ipc_A_internal);
192     /*
193      *  VPSS-M3 & VIDEO-M3 each have a unique interrupt ID for receiving
194      *  interrupts external to the Ducati subsystem.  (M3DSSINT & M3VIDEOINT).
195      *  However, they have a separate interrupt ID for receving interrupt from
196      *  each other(M3INT).
197      *
198      *  Store the interrupt id in the intInfo so it can be used during
199      *  intUnregiseter.
200      */
201     if (remoteProcId == InterruptDucati_dspProcId) {
202         index = 0;
203         if ((BIOS_smpEnabled) || (Core_getId() == 0)) {
204             intInfo->localIntId = M3VIDEOINT;
205         }
206         else {
207             intInfo->localIntId = M3DSSINT;
208         }
209     }
210     else if (remoteProcId == InterruptDucati_hostProcId) {
211         index = 1;
212         if ((BIOS_smpEnabled) || (Core_getId() == 0)) {
213             intInfo->localIntId = M3VIDEOINT;
214         }
215         else {
216             intInfo->localIntId = M3DSSINT;
217         }
218     }
219     else {
220         /* Going to the other M3 */
221         index = 2;
222         intInfo->localIntId = M3INT;
223     }
225     /* Disable global interrupts */
226     key = Hwi_disable();
228     table = &(InterruptDucati_module->fxnTable[index]);
229     table->func = func;
230     table->arg  = arg;
232     InterruptDucati_intClear(remoteProcId, intInfo);
234     Hwi_Params_init(&hwiAttrs);
235     hwiAttrs.maskSetting = Hwi_MaskingOption_LOWER;
237     /* Make sure the interrupt only gets plugged once */
238     if (remoteProcId == InterruptDucati_videoProcId ||
239         remoteProcId == InterruptDucati_vpssProcId) {
240         Hwi_create(intInfo->localIntId,
241                    (Hwi_FuncPtr)InterruptDucati_intShmDucatiStub,
242                    &hwiAttrs,
243                    NULL);
244     }
245     else {
246         InterruptDucati_module->numPlugged++;
247         if (InterruptDucati_module->numPlugged == 1) {
248             Hwi_create(intInfo->localIntId,
249                        (Hwi_FuncPtr)InterruptDucati_intShmMbxStub,
250                        &hwiAttrs,
251                        NULL);
253             /* Interrupt_intEnable won't enable the Hwi */
254             Hwi_enableInterrupt(intInfo->localIntId);
255         }
256     }
258     InterruptDucati_intEnable(remoteProcId, intInfo);
260     /* Restore global interrupts */
261     Hwi_restore(key);
264 /*!
265  *  ======== InterruptDucati_intUnregister ========
266  */
267 Void InterruptDucati_intUnregister(UInt16 remoteProcId,
268                                    IInterrupt_IntInfo *intInfo)
270     Int         index;
271     InterruptDucati_FxnTable *table;
272     Hwi_Handle  hwiHandle;
274     if (remoteProcId == InterruptDucati_dspProcId) {
275         index = 0;
276     }
277     else if (remoteProcId == InterruptDucati_hostProcId) {
278         index = 1;
279     }
280     else {
281         /* Going to the other M3 */
282         index = 2;
283     }
285     /* Disable the mailbox interrupt source */
286     InterruptDucati_intDisable(remoteProcId, intInfo);
288     /* Disable the interrupt itself */
289     if (remoteProcId == InterruptDucati_videoProcId ||
290         remoteProcId == InterruptDucati_vpssProcId) {
291         hwiHandle = Hwi_getHandle(M3INT);
292         Hwi_delete(&hwiHandle);
293     }
294     else {
295         InterruptDucati_module->numPlugged--;
296         if (InterruptDucati_module->numPlugged == 0) {
297             hwiHandle = Hwi_getHandle(intInfo->localIntId);
298             Hwi_delete(&hwiHandle);
299         }
300     }
302     /* Clear the FxnTable entry for the remote processor */
303     table = &(InterruptDucati_module->fxnTable[index]);
304     table->func = NULL;
305     table->arg  = 0;
309 /*!
310  *  ======== InterruptDucati_intSend ========
311  *  Send interrupt to the remote processor
312  */
313 Void InterruptDucati_intSend(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo,
314                              UArg arg)
316     UInt key;
318     if (remoteProcId == InterruptDucati_videoProcId ||
319         remoteProcId == InterruptDucati_vpssProcId) {
320         if (!(BIOS_smpEnabled) && (Core_getId() == 1)) {
321             /* VPSS-M3 to VIDEO-M3 */
322             REG16(INTERRUPT_VIDEO) |= 0x1;
323         }
324         else {
325             /* VIDEO-M3 to VPSS-M3 */
326             REG16(INTERRUPT_VPSS) |= 0x1;
327         }
328     }
329     else if (remoteProcId == InterruptDucati_dspProcId) {
330         if (!(BIOS_smpEnabled) && (Core_getId() == 1)) {
331             /* VPSS-M3 to DSP */
332             key = Hwi_disable();
333             if (REG32(MAILBOX_STATUS(VPSS_TO_DSP)) == 0) {
334                 REG32(MAILBOX_MESSAGE(VPSS_TO_DSP)) = arg;
335             }
336             Hwi_restore(key);
337         }
338         else {
339             /* VIDEO-M3 to DSP */
340             key = Hwi_disable();
341             if (REG32(MAILBOX_STATUS(VIDEO_TO_DSP)) == 0) {
342                 REG32(MAILBOX_MESSAGE(VIDEO_TO_DSP)) = arg;
343             }
344             Hwi_restore(key);
345         }
346     }
347     else { /* HOSTINT */
348         if (!(BIOS_smpEnabled) && (Core_getId() == 1)) {
349             /* VPSS-M3 to HOST */
350             key = Hwi_disable();
351             if (REG32(MAILBOX_STATUS(VPSS_TO_HOST)) == 0) {
352                 REG32(MAILBOX_MESSAGE(VPSS_TO_HOST)) = arg;
353             }
354             Hwi_restore(key);
355         }
356         else {
357             /* VIDEO-M3 to HOST */
358             key = Hwi_disable();
359             if (REG32(MAILBOX_STATUS(VIDEO_TO_HOST)) == 0) {
360                 REG32(MAILBOX_MESSAGE(VIDEO_TO_HOST)) = arg;
361             }
362             Hwi_restore(key);
363         }
364     }
368 /*!
369  *  ======== InterruptDucati_intPost ========
370  *  Simulate an interrupt from a remote processor
371  */
372 Void InterruptDucati_intPost(UInt16 srcProcId, IInterrupt_IntInfo *intInfo,
373                              UArg arg)
375     UInt key;
377     if (srcProcId == InterruptDucati_videoProcId ||
378         srcProcId == InterruptDucati_vpssProcId) {
379         if (!(BIOS_smpEnabled) && (Core_getId() == 1)) {
380             /* VIDEO-M3 to VPSS-M3 */
381             REG16(INTERRUPT_VPSS) |= 0x1;
382         }
383         else {
384             /* VPSS-M3 to VIDEO-M3 */
385             REG16(INTERRUPT_VIDEO) |= 0x1;
386         }
387     }
388     else if (srcProcId == InterruptDucati_dspProcId) {
389         if (!(BIOS_smpEnabled) && (Core_getId() == 1)) {
390             /* DSP to VPSS-M3 */
391             key = Hwi_disable();
392             if (REG32(MAILBOX_STATUS(DSP_TO_VPSS)) == 0) {
393                 REG32(MAILBOX_MESSAGE(DSP_TO_VPSS)) = arg;
394             }
395             Hwi_restore(key);
396         }
397         else {
398             /* DSP to VIDEO-M3 */
399             key = Hwi_disable();
400             if (REG32(MAILBOX_STATUS(DSP_TO_VIDEO)) == 0) {
401                 REG32(MAILBOX_MESSAGE(DSP_TO_VIDEO)) = arg;
402             }
403             Hwi_restore(key);
404         }
405     }
406     else { /* HOSTINT */
407         if (!(BIOS_smpEnabled) && (Core_getId() == 1)) {
408             /* HOST to VPSS-M3 */
409             key = Hwi_disable();
410             if (REG32(MAILBOX_STATUS(HOST_TO_VPSS)) == 0) {
411                 REG32(MAILBOX_MESSAGE(HOST_TO_VPSS)) = arg;
412             }
413             Hwi_restore(key);
414         }
415         else {
416             /* HOST to VIDEO-M3 */
417             key = Hwi_disable();
418             if (REG32(MAILBOX_STATUS(HOST_TO_VIDEO)) == 0) {
419                 REG32(MAILBOX_MESSAGE(HOST_TO_VIDEO)) = arg;
420             }
421             Hwi_restore(key);
422         }
423     }
427 /*!
428  *  ======== InterruptDucati_intClear ========
429  *  Clear interrupt
430  */
431 UInt InterruptDucati_intClear(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo)
433     UInt arg;
435     if (remoteProcId == InterruptDucati_videoProcId ||
436         remoteProcId == InterruptDucati_vpssProcId) {
437         arg = REG32(InterruptDucati_ducatiCtrlBaseAddr);
439         /* Look at BIOS's ducati Core id */
440         if ((BIOS_smpEnabled) || (Core_getId() == 0)) {
441             if ((REG16(INTERRUPT_VIDEO) & 0x1) == 0x1) {
442                 /* VPSS-M3 to VIDEO-M3 */
443                 REG16(INTERRUPT_VIDEO) &= ~(0x1);
444             }
445         }
446         else {
447             if ((REG16(INTERRUPT_VPSS) & 0x1) == 0x1) {
448                 /* VIDEO-M3 to VPSS-M3 */
449                 REG16(INTERRUPT_VPSS) &= ~(0x1);
450             }
451         }
452     }
453     else if ((BIOS_smpEnabled) || (Core_getId() == 0)) {
454         if (remoteProcId == InterruptDucati_hostProcId) {
455             /* HOST to VIDEO-M3 */
456             arg = REG32(MAILBOX_MESSAGE(HOST_TO_VIDEO));
457             REG32(MAILBOX_IRQSTATUS_CLR_VIDEO) = MAILBOX_REG_VAL(HOST_TO_VIDEO);
458         }
459         else {
460             /* DSP to VIDEO-M3 */
461             arg = REG32(MAILBOX_MESSAGE(DSP_TO_VIDEO));
462             REG32(MAILBOX_IRQSTATUS_CLR_VIDEO) = MAILBOX_REG_VAL(DSP_TO_VIDEO);
463         }
464     }
465     else { /* M3DSSINT */
466         if (remoteProcId == InterruptDucati_hostProcId) {
467             /* HOST to VPSS-M3 */
468             arg = REG32(MAILBOX_MESSAGE(HOST_TO_VPSS));
469             REG32(MAILBOX_IRQSTATUS_CLR_VPSS) = MAILBOX_REG_VAL(HOST_TO_VPSS);
470         }
471         else {
472             /* DSP to VPSS-M3 */
473             arg = REG32(MAILBOX_MESSAGE(DSP_TO_VPSS));
474             REG32(MAILBOX_IRQSTATUS_CLR_VPSS) = MAILBOX_REG_VAL(DSP_TO_VPSS);
475         }
476     }
478     return (arg);
481 /*
482  *************************************************************************
483  *                      Internals functions
484  *************************************************************************
485  */
487 /*!
488  *  ======== InterruptDucati_intShmDucatiStub ========
489  */
490 Void InterruptDucati_intShmDucatiStub(UArg arg)
492     InterruptDucati_FxnTable *table;
494     table = &(InterruptDucati_module->fxnTable[2]);
495     (table->func)(table->arg);
498 /*!
499  *  ======== InterruptDucati_intShmMbxStub ========
500  */
501 Void InterruptDucati_intShmMbxStub(UArg arg)
503     InterruptDucati_FxnTable *table;
505     if ((BIOS_smpEnabled) || (Core_getId() == 0)) {
506         if ((REG32(MAILBOX_IRQENABLE_SET_VIDEO) &
507                 MAILBOX_REG_VAL(DSP_TO_VIDEO)) &&
508             REG32(MAILBOX_STATUS(DSP_TO_VIDEO)) != 0) { /* DSP to VIDEO-M3 */
509             table = &(InterruptDucati_module->fxnTable[0]);
510             (table->func)(table->arg);
511         }
512         if ((REG32(MAILBOX_IRQENABLE_SET_VIDEO) &
513                 MAILBOX_REG_VAL(HOST_TO_VIDEO)) &&
514             REG32(MAILBOX_STATUS(HOST_TO_VIDEO)) != 0) { /* HOST to VIDEO-M3 */
515             table = &(InterruptDucati_module->fxnTable[1]);
516             (table->func)(table->arg);
517         }
518     }
519     else {
520         if ((REG32(MAILBOX_IRQENABLE_SET_VPSS) &
521                 MAILBOX_REG_VAL(DSP_TO_VPSS)) &&
522              REG32(MAILBOX_STATUS(DSP_TO_VPSS)) != 0) { /* DSP to VPSS-M3 */
523             table = &(InterruptDucati_module->fxnTable[0]);
524             (table->func)(table->arg);
525         }
526         if ((REG32(MAILBOX_IRQENABLE_SET_VPSS) &
527                 MAILBOX_REG_VAL(HOST_TO_VPSS)) &&
528             REG32(MAILBOX_STATUS(HOST_TO_VPSS)) != 0) { /* HOST to VPSS-M3 */
529             table = &(InterruptDucati_module->fxnTable[1]);
530             (table->func)(table->arg);
531         }
532     }