8b0fdbe2c9e1c6afe3cb8a5f0ebc69875ab2e8cd
[ipc/ipcdev.git] / packages / ti / sdo / ipc / family / vayu / InterruptArp32.c
1 /*
2  * Copyright (c) 2012-2014 Texas Instruments Incorporated - http://www.ti.com
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  */
33 /*
34  *  ======== InterruptArp32.c ========
35  *  ARP32 mailbox based interrupt manager
36  */
37 #include <xdc/std.h>
38 #include <xdc/runtime/Assert.h>
39 #include <xdc/runtime/Error.h>
41 #include <ti/sysbios/family/arp32/Hwi.h>
43 #include <ti/sdo/ipc/_Ipc.h>
44 #include <ti/sdo/ipc/family/vayu/NotifySetup.h>
45 #include <ti/sdo/ipc/notifyDrivers/IInterrupt.h>
46 #include <ti/sdo/utils/_MultiProc.h>
48 #include "package/internal/InterruptArp32.xdc.h"
50 /* Register access method. */
51 #define REG16(A)   (*(volatile UInt16 *) (A))
52 #define REG32(A)   (*(volatile UInt32 *) (A))
54 #define PROCID(IDX)               (InterruptArp32_procIdTable[IDX])
55 #define MBX_TABLE_IDX(SRC, DST)   ((PROCID(SRC) * InterruptArp32_NUM_CORES) + \
56                                     PROCID(DST))
57 #define SUBMBX_IDX(IDX)           (InterruptArp32_mailboxTable[IDX] & 0xFF)
58 #define MBX_USER_IDX(IDX)         ((InterruptArp32_mailboxTable[IDX] >> 8) \
59                                     & 0xFF)
60 #define MBX_BASEADDR_IDX(IDX)     ((InterruptArp32_mailboxTable[IDX] >> 16) \
61                                     & 0xFFFF)
63 #define MAILBOX_REG_VAL(M)   (0x1 << (2 * M))
65 #define MAILBOX_MESSAGE(IDX) (InterruptArp32_mailboxBaseAddr[  \
66                                 MBX_BASEADDR_IDX(IDX)] + 0x040 \
67                                 + (0x4 * SUBMBX_IDX(IDX)))
68 #define MAILBOX_STATUS(IDX)  (InterruptArp32_mailboxBaseAddr[  \
69                                 MBX_BASEADDR_IDX(IDX)] + 0x0C0 \
70                                 + (0x4 * SUBMBX_IDX(IDX)))
72 #define MAILBOX_IRQSTATUS_CLR(IDX)  (InterruptArp32_mailboxBaseAddr[   \
73                                         MBX_BASEADDR_IDX(IDX)] + 0x104 \
74                                         + (MBX_USER_IDX(IDX) * 0x10))
75 #define MAILBOX_IRQENABLE_SET(IDX)  (InterruptArp32_mailboxBaseAddr[   \
76                                         MBX_BASEADDR_IDX(IDX)] + 0x108 \
77                                         + (MBX_USER_IDX(IDX) * 0x10))
78 #define MAILBOX_IRQENABLE_CLR(IDX)  (InterruptArp32_mailboxBaseAddr[   \
79                                         MBX_BASEADDR_IDX(IDX)] + 0x10C \
80                                         + (MBX_USER_IDX(IDX) * 0x10))
82 #define MAILBOX_EOI_REG(IDX)        (InterruptArp32_mailboxBaseAddr[   \
83                                         MBX_BASEADDR_IDX(IDX)] + 0x140)
85 /* This needs to match the virtual id from the TableInit.xs */
86 #define DSP1_ID     4
87 #define DSP2_ID     5
88 #define IPU1_ID     6
89 #define IPU2_ID     7
90 #define HOST_ID     8
91 #define IPU1_1_ID   9
92 #define IPU2_1_ID   10
94 /*
95  *************************************************************************
96  *                      Module functions
97  *************************************************************************
98  */
100 /*
101  *  ======== InterruptArp32_intEnable ========
102  *  Enable remote processor interrupt
103  */
104 Void InterruptArp32_intEnable(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo)
106     UInt16 index;
108     index = MBX_TABLE_IDX(remoteProcId, MultiProc_self());
110     REG32(MAILBOX_IRQENABLE_SET(index)) = MAILBOX_REG_VAL(SUBMBX_IDX(index));
113 /*
114  *  ======== InterruptArp32_intDisable ========
115  *  Disables remote processor interrupt
116  */
117 Void InterruptArp32_intDisable(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo)
119     UInt16 index;
121     index = MBX_TABLE_IDX(remoteProcId, MultiProc_self());
123     REG32(MAILBOX_IRQENABLE_CLR(index)) = MAILBOX_REG_VAL(SUBMBX_IDX(index));
126 /*
127  *  ======== InterruptArp32_intRegister ========
128  */
129 Void InterruptArp32_intRegister(UInt16 remoteProcId,
130         IInterrupt_IntInfo *intInfo, Fxn func, UArg arg)
132     UInt        key;
133     UInt16      index;
134     Error_Block eb;
135     InterruptArp32_FxnTable *table;
137     Assert_isTrue(remoteProcId < ti_sdo_utils_MultiProc_numProcessors,
138            ti_sdo_ipc_Ipc_A_internal);
140     /* Assert that our MultiProc id is set correctly */
141     Assert_isTrue((InterruptArp32_eve1ProcId == MultiProc_self()) ||
142                   (InterruptArp32_eve2ProcId == MultiProc_self()) ||
143                   (InterruptArp32_eve3ProcId == MultiProc_self()) ||
144                   (InterruptArp32_eve4ProcId == MultiProc_self()),
145                    ti_sdo_ipc_Ipc_A_internal);
147     /* init error block */
148     Error_init(&eb);
150     index = PROCID(remoteProcId);
152     /* Disable global interrupts */
153     key = Hwi_disable();
155     table = &(InterruptArp32_module->fxnTable[index]);
156     table->func = func;
157     table->arg  = arg;
159     InterruptArp32_intClear(remoteProcId, intInfo);
161     /* plug the cpu interrupt */
162     NotifySetup_plugHwi(remoteProcId, intInfo->intVectorId,
163             InterruptArp32_intShmStub);
165     /* enable the mailbox and Hwi */
166     InterruptArp32_intEnable(remoteProcId, intInfo);
168     /* Restore global interrupts */
169     Hwi_restore(key);
172 /*
173  *  ======== InterruptArp32_intUnregister ========
174  */
175 Void InterruptArp32_intUnregister(UInt16 remoteProcId,
176                                    IInterrupt_IntInfo *intInfo)
178     UInt16 index;
179     InterruptArp32_FxnTable *table;
181     index = PROCID(remoteProcId);
183     /* disable the mailbox interrupt source */
184     InterruptArp32_intDisable(remoteProcId, intInfo);
186     /* unplug isr */
187     NotifySetup_unplugHwi(remoteProcId, intInfo->intVectorId);
189     /* Clear the FxnTable entry for the remote processor */
190     table = &(InterruptArp32_module->fxnTable[index]);
191     table->func = NULL;
192     table->arg = 0;
195 /*
196  *  ======== InterruptArp32_intSend ========
197  *  Send interrupt to the remote processor
198  */
199 Void InterruptArp32_intSend(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo,
200                              UArg arg)
202     UInt key;
203     UInt16 index;
205     index = MBX_TABLE_IDX(MultiProc_self(), remoteProcId);
207     /* disable interrupts */
208     key = Hwi_disable();
210     if (REG32(MAILBOX_STATUS(index)) == 0) {
211         /* write the mailbox message to remote proc */
212         REG32(MAILBOX_MESSAGE(index)) = arg;
213     }
215     /* restore interrupts */
216     Hwi_restore(key);
219 /*
220  *  ======== InterruptArp32_intPost ========
221  *  Simulate an interrupt from a remote processor
222  */
223 Void InterruptArp32_intPost(UInt16 srcProcId, IInterrupt_IntInfo *intInfo,
224                              UArg arg)
226     UInt key;
227     UInt16 index;
229     index = MBX_TABLE_IDX(srcProcId, MultiProc_self());
231     /* disable interrupts */
232     key = Hwi_disable();
234     if (REG32(MAILBOX_STATUS(index)) == 0) {
235         /* write the mailbox message to arp32 */
236         REG32(MAILBOX_MESSAGE(index)) = arg;
237     }
239     /* restore interrupts */
240     Hwi_restore(key);
244 /*
245  *  ======== InterruptArp32_intClear ========
246  *  Clear interrupt
247  */
248 UInt InterruptArp32_intClear(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo)
250     UInt arg;
251     UInt16 index;
253     index = MBX_TABLE_IDX(remoteProcId, MultiProc_self());
255     arg = REG32(MAILBOX_MESSAGE(index));
256     /* clear the dsp mailbox */
257     REG32(MAILBOX_IRQSTATUS_CLR(index)) = MAILBOX_REG_VAL(SUBMBX_IDX(index));
259     /* Write to EOI (End Of Interrupt) register */
260     REG32(MAILBOX_EOI_REG(index)) = 0x1;
262     return (arg);
265 /*
266  *************************************************************************
267  *                      Internals functions
268  *************************************************************************
269  */
271 /*
272  *  ======== InterruptArp32_intShmStub ========
273  */
274 Void InterruptArp32_intShmStub(UInt16 idx)
276     UInt16 srcVirtId;
277     InterruptArp32_FxnTable *table;
279     srcVirtId = idx / InterruptArp32_NUM_CORES;
280     table = &(InterruptArp32_module->fxnTable[srcVirtId]);
281     (table->func)(table->arg);