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 * ======== InterruptHost.c ========
34 * Mailbox based interrupt manager
35 */
37 #include <xdc/std.h>
38 #include <xdc/runtime/Assert.h>
40 #include <ti/sysbios/family/arm/a8/intcps/Hwi.h>
42 #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/InterruptHost.xdc.h"
49 /* Register access method. */
50 #define REG32(A) (*(volatile UInt32 *) (A))
52 /* Mailbox management values */
53 #define MAILBOX_BASE 0x48094000
54 #define MAILBOX_MESSAGE_0 MAILBOX_BASE + 0x40
55 #define MAILBOX_MESSAGE_1 MAILBOX_BASE + 0x44
56 #define MAILBOX_MSGSTATUS_0 MAILBOX_BASE + 0xC0
57 #define MAILBOX_MSGSTATUS_1 MAILBOX_BASE + 0xC4
58 #define MAILBOX_IRQSTATUS_GPP MAILBOX_BASE + 0x100
59 #define MAILBOX_IRQSTATUS_DSP MAILBOX_BASE + 0x108
60 #define MAILBOX_IRQENABLE_GPP MAILBOX_BASE + 0x104
61 #define MAILBOX_IRQENABLE_DSP MAILBOX_BASE + 0x10C
63 #define DSPINT 55
64 #define HOSTINT 26
67 /*
68 *************************************************************************
69 * Module functions
70 *************************************************************************
71 */
73 /*!
74 * ======== InterruptHost_intEnable ========
75 */
76 Void InterruptHost_intEnable(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo)
77 {
78 Hwi_enableInterrupt(HOSTINT);
79 }
81 /*!
82 * ======== InterruptHost_intDisable ========
83 */
84 Void InterruptHost_intDisable(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo)
85 {
86 Hwi_disableInterrupt(HOSTINT);
87 }
89 /*!
90 * ======== InterruptHost_intRegister ========
91 */
92 Void InterruptHost_intRegister(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo,
93 Fxn func, UArg arg)
94 {
95 UInt key;
96 Hwi_Params hwiAttrs;
98 /* Make sure that we're trying to talk to the HOST */
99 Assert_isTrue(remoteProcId == MultiProc_getId("DSP"),
100 ti_sdo_ipc_Ipc_A_invArgument);
102 /* Disable global interrupts */
103 key = Hwi_disable();
105 InterruptHost_intClear(remoteProcId, intInfo);
107 /* Register interrupt for communication between ARM and DSP */
108 Hwi_Params_init(&hwiAttrs);
109 hwiAttrs.maskSetting = Hwi_MaskingOption_SELF;
110 hwiAttrs.arg = arg;
111 Hwi_create(HOSTINT,
112 (Hwi_FuncPtr)func,
113 &hwiAttrs,
114 NULL);
116 /* Enable the mailbox interrupt to the DSP */
117 REG32(MAILBOX_IRQENABLE_GPP) = 0x4; /* Mailbox 0 */
119 /* Restore global interrupts */
120 Hwi_restore(key);
122 /* Unmask IVA_2_IRQ[10] to allow interrupt to come into DSP */
123 Hwi_enableInterrupt(HOSTINT);
124 }
126 /*!
127 * ======== InterruptHost_intUnregister ========
128 */
129 Void InterruptHost_intUnregister(UInt16 remoteProcId,
130 IInterrupt_IntInfo *intInfo)
131 {
132 Hwi_Handle hwiHandle;
134 /* Delete the Hwi (and disable the corresponding interrupt) */
135 hwiHandle = Hwi_getHandle(HOSTINT);
136 Hwi_delete(&hwiHandle);
137 }
139 /*!
140 * ======== InterruptHost_intSend ========
141 * Send interrupt to the remote processor
142 */
143 Void InterruptHost_intSend(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo,
144 UArg arg)
145 {
146 /* Put into the DSP's mailbox to generate the interrupt. */
147 REG32(MAILBOX_MESSAGE_0) = arg;
148 }
150 /*!
151 * ======== InterruptHost_intPost ========
152 */
153 Void InterruptHost_intPost(UInt16 srcProcId, IInterrupt_IntInfo *intInfo,
154 UArg arg)
155 {
156 /* Put into the GPP's mailbox to generate the interrupt. */
157 REG32(MAILBOX_MESSAGE_1) = arg;
158 }
160 /*!
161 * ======== Interrupt_intClear ========
162 * Clear interrupt
163 */
164 UInt InterruptHost_intClear(UInt16 remoteProcId, IInterrupt_IntInfo *intInfo)
165 {
166 UInt arg;
168 /* Read into val. */
169 arg = REG32(MAILBOX_MESSAGE_1);
171 /*
172 * Clear the IRQ status.
173 * If there are more in the mailbox FIFO, it will re-assert.
174 */
175 REG32(MAILBOX_IRQSTATUS_GPP) = 0x4; /* Mailbox 0 */
177 return (arg);
178 }