[ipc/ipcdev.git] / qnx / src / ipc3x_dev / ti / syslink / ipc / hlos / knl / arch / vayu / VAYUIpcInt.c
1 /*
2 * @file VAYUIpcInt.c
3 *
4 * @brief VAYU interrupt handling code.
5 * Defines necessary functions for Interrupt Handling.
6 *
7 *
8 * ============================================================================
9 *
10 * Copyright (c) 2013-2015, Texas Instruments Incorporated
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * * Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 *
19 * * Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 *
23 * * Neither the name of Texas Instruments Incorporated nor the names of
24 * its contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
29 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
31 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
34 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
35 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
36 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
37 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 * Contact information for paper mail:
39 * Texas Instruments
40 * Post Office Box 655303
41 * Dallas, Texas 75265
42 * Contact information:
43 * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
44 * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
45 * ============================================================================
46 *
47 */
51 /* Standard headers */
52 #include <ti/syslink/Std.h>
54 /* OSAL headers */
55 #include <ti/syslink/utils/Trace.h>
56 #include <ti/syslink/utils/List.h>
57 #include <Bitops.h>
59 /* OSAL and utils headers */
60 #include <OsalIsr.h>
61 #include <_MultiProc.h>
62 #include <ti/ipc/MultiProc.h>
63 #include <ti/syslink/utils/Memory.h>
64 #include <ti/syslink/utils/Gate.h>
65 #include <ti/syslink/utils/GateMutex.h>
67 /* Hardware Abstraction Layer */
68 #include <_ArchIpcInt.h>
69 #include <_VAYUIpcInt.h>
70 #include <VAYUIpcInt.h>
71 #include <errno.h>
74 #if defined (__cplusplus)
75 extern "C" {
76 #endif
78 /* From TableInit.xs in packages/ti/sdo/ipc/family/vayu: */
79 /*
80 * src dst mbox userid subidx
81 * IPU1_0 DSP1 5 0 3
82 * HOST DSP1 5 0 5
83 * IPU1_1 DSP1 5 0 8
84 * DSP1 IPU1_0 5 1 0
85 * HOST IPU1_0 5 1 6
86 * DSP1 HOST 5 2 1
87 * IPU1_0 HOST 5 2 4
88 * IPU1_1 HOST 5 2 9
89 * DSP1 IPU1_1 5 3 2
90 * HOST IPU1_1 5 3 7
91 * IPU2_0 DSP2 6 0 3
92 * HOST DSP2 6 0 5
93 * IPU2_1 DSP2 6 0 8
94 * DSP2 IPU2_0 6 1 0
95 * HOST IPU2_0 6 1 6
96 * DSP2 HOST 6 2 1
97 * IPU2_0 HOST 6 2 4
98 * IPU2_1 HOST 6 2 9
99 * DSP2 IPU2_1 6 3 2
100 * HOST IPU2_1 6 3 7
101 */
103 /* =============================================================================
104 * Macros and types
105 * =============================================================================
106 */
108 /*!
109 * @def VAYU_VAYU_NUMPROCS
110 * @brief Number of processors supported on this platform
111 */
112 #define VAYU_NUMPROCS 5
113 /*!
114 * @def VAYU_INDEX_DSP1
115 * @brief Dsp1 index.
116 */
117 #define VAYU_INDEX_DSP1 4
118 /*!
119 * @def VAYU_INDEX_DSP2
120 * @brief Dsp2 index.
121 */
122 #define VAYU_INDEX_DSP2 3
123 /*!
124 * @def VAYU_INDEX_IPU1
125 * @brief IPU1 index.
126 */
127 #define VAYU_INDEX_IPU1 2
128 /*!
129 * @def VAYU_INDEX_IPU2
130 * @brief IPU2 index.
131 */
132 #define VAYU_INDEX_IPU2 1
133 /*!
134 * @def VAYU_INDEX_HOST
135 * @brief HOST index.
136 */
137 #define VAYU_INDEX_HOST 0
139 /*!
140 * @def VAYU_HOST_IPU1_MBOX
141 * @brief Mailbox used for HOST<->IPU1 communication.
142 */
143 #define VAYU_HOST_IPU1_MBOX 5
145 /*!
146 * @def VAYU_HOST_IPU2_MBOX
147 * @brief Mailbox used for HOST<->IPU2 communication.
148 */
149 #define VAYU_HOST_IPU2_MBOX 6
151 /*!
152 * @def IPU1_HOST_SUB_MBOX
153 * @brief Sub-Mailbox used for IPU1->HOST communication.
154 */
155 #define IPU1_HOST_SUB_MBOX 4
157 /*!
158 * @def HOST_IPU1_SUB_MBOX
159 * @brief Sub-Mailbox used for HOST->IPU1 communication.
160 */
161 #define HOST_IPU1_SUB_MBOX 6
163 /*!
164 * @def IPU2_HOST_SUB_MBOX
165 * @brief Sub-Mailbox used for IPU2->HOST communication.
166 */
167 #define IPU2_HOST_SUB_MBOX 4
169 /*!
170 * @def HOST_IPU2_SUB_MBOX
171 * @brief Sub-Mailbox used for HOST->IPU2 communication.
172 */
173 #define HOST_IPU2_SUB_MBOX 6
175 /*!
176 * @def VAYU_HOST_DSP1_MBOX
177 * @brief Mailbox used for HOST<->DSP1 communication.
178 */
179 #define VAYU_HOST_DSP1_MBOX 5
181 /*!
182 * @def DSP1_HOST_SUB_MBOX
183 * @brief Mailbox used for DSP1->HOST communication.
184 */
185 #define DSP1_HOST_SUB_MBOX 1
187 /*!
188 * @def HOST_DSP1_SUB_MBOX
189 * @brief Mailbox used for HOST->DSP1 communication.
190 */
191 #define HOST_DSP1_SUB_MBOX 5
193 /*!
194 * @def VAYU_HOST_DSP2_MBOX
195 * @brief Mailbox used for HOST<->DSP2 communication.
196 */
197 #define VAYU_HOST_DSP2_MBOX 6
199 /*!
200 * @def DSP2_HOST_SUB_MBOX
201 * @brief Mailbox used for DSP2->HOST communication.
202 */
203 #define DSP2_HOST_SUB_MBOX 1
205 /*!
206 * @def HOST_DSP2_SUB_MBOX
207 * @brief Mailbox used for HOST->DSP2 communication.
208 */
209 #define HOST_DSP2_SUB_MBOX 5
211 /*!
212 * @def VAYU_HOST_USER_ID
213 * @brief User ID of HOST.
214 */
215 #define VAYU_HOST_USER_ID 2
217 /*!
218 * @def VAYU_IPU1_USER_ID
219 * @brief User ID of IPU2.
220 */
221 #define VAYU_IPU1_USER_ID 1
223 /*!
224 * @def VAYU_IPU2_USER_ID
225 * @brief User ID of IPU2.
226 */
227 #define VAYU_IPU2_USER_ID 1
229 /*!
230 * @def VAYU_DSP1_USER_ID
231 * @brief User ID of DSP1.
232 */
233 #define VAYU_DSP1_USER_ID 0
235 /*!
236 * @def VAYU_DSP2_USER_ID
237 * @brief User ID of DSP2.
238 */
239 #define VAYU_DSP2_USER_ID 0
241 /* Macro to make a correct module magic number with refCount */
242 #define VAYUIPCINT_MAKE_MAGICSTAMP(x) \
243 ((VAYUIPCINT_MODULEID << 12u) | (x))
245 /*!
246 * @def REG
247 * @brief Regsiter access method.
248 */
249 #define REG(x) *((volatile UInt32 *) (x))
250 #define REG32(x) (*(volatile UInt32 *) (x))
252 /* Register access method. */
253 #define REG16(A) (*(volatile UInt16 *) (A))
255 /*!
256 * @def AINTC_BASE_ADDR
257 * @brief configuraion address.
258 */
259 #define AINTC_BASE_ADDR 0x48200000
261 /*!
262 * @def AINTC_BASE_SIZE
263 * @brief size to be ioremapped.
264 */
265 #define AINTC_BASE_SIZE 0x1000
267 /*!
268 * @def CTRL_MODULE_BASE
269 * @brief configuration address.
270 */
271 #define CTRL_MODULE_BASE 0x4A002000
273 /*!
274 * @def CTRL_MODULE_SIZE
275 * @brief size to be ioremapped.
276 */
277 #define CTRL_MODULE_SIZE 0x1000
279 /*!
280 * @def CTRL_MODULE_MMR_OFFSET
281 * @brief offset in ctrl module to MMR LOCK reg.
282 */
283 #define CTRL_MODULE_MMR_OFFSET 0x544
285 /*!
286 * @def CTRL_MODULE_MPU_OFFSET
287 * @brief offset in ctrl module to MPU INTs.
288 */
289 #define CTRL_MODULE_MPU_OFFSET 0xA4C
291 /*!
292 * @def CTRL_MODULE_INT_BASE
293 * @brief interrupt num at offset.
294 */
295 #define CTRL_MODULE_INT_BASE 0x8
297 /*!
298 * @def CTRL_MODULE_INT_m_OFFSET
299 * @brief interrupt num at offset.
300 */
301 #define CTRL_MODULE_INT_m_OFFSET(m) CTRL_MODULE_MPU_OFFSET + \
302 ((((m) - CTRL_MODULE_INT_BASE) / 2) * 4) - \
303 (((m) > 131) ? 4 : 0)
305 /*!
306 * @def IRQ_XBAR_MBOX_6_USR_2
307 * @brief irq xbar num for mailbox 6 user 2.
308 */
309 #define IRQ_XBAR_MBOX_6_USR_2 255
311 /*!
312 * @def IRQ_XBAR_MBOX_5_USR_2
313 * @brief irq xbar num for mailbox 5 user 2.
314 */
315 #define IRQ_XBAR_MBOX_5_USR_2 251
317 /*!
318 * @def IRQ_XBAR_DSP1
319 * @brief irq xbar num for dsp1.
320 */
321 #define IRQ_XBAR_DSP1 IRQ_XBAR_MBOX_5_USR_2
323 /*!
324 * @def IRQ_XBAR_DSP2
325 * @brief irq xbar num for dsp2.
326 */
327 #define IRQ_XBAR_DSP2 IRQ_XBAR_MBOX_6_USR_2
329 /*!
330 * @def IRQ_XBAR_IPU1
331 * @brief irq xbar num for ipu1.
332 */
333 #define IRQ_XBAR_IPU1 IRQ_XBAR_MBOX_5_USR_2
335 /*!
336 * @def IRQ_XBAR_IPU2
337 * @brief irq xbar num for ipu2.
338 */
339 #define IRQ_XBAR_IPU2 IRQ_XBAR_MBOX_6_USR_2
341 /* Mailbox management values */
342 /*!
343 * @def VAYU_MAILBOX_5_BASE
344 * @brief configuraion address.
345 */
346 #define MAILBOX_5_BASE 0x48840000
348 /*!
349 * @def VAYU_MAILBOX_6_BASE
350 * @brief configuraion address.
351 */
352 #define MAILBOX_6_BASE 0x48842000
354 /*!
355 * @def MAILBOX_SIZE
356 * @brief size to be ioremapped.
357 */
358 #define MAILBOX_SIZE 0x1000
360 /*!
361 * @def MAILBOX_SYSCONFIG_OFFSET
362 * @brief Offset from the Mailbox base address.
363 */
364 #define MAILBOX_SYSCONFIG_OFFSET 0x10
366 /*!
367 * @def MAILBOX_MAXNUM
368 * @brief maximum number of mailbox.
369 */
370 #define MAILBOX_MAXNUM 0xC
372 /*!
373 * @def MAILBOX_MESSAGE_m_OFFSET
374 * @brief mailbox message address Offset from the Mailbox base
375 * address. m = 0 to 7 => offset = 0x40 + 0x4*m
376 */
377 #define MAILBOX_MESSAGE_m_OFFSET(m) (0x40 + (m<<2))
379 /*!
380 * @def MAILBOX_MSGSTATUS_m_OFFSET
381 * @brief mailbox message status address Offset from the Mailbox base
382 * address. m = 0 to 7 => offset = 0x40 + 0x4*m
383 */
384 #define MAILBOX_MSGSTATUS_m_OFFSET(m) (0xC0 + (m<<2))
386 /*!
387 * @def MAILBOX_IRQSTATUS_CLEAR_OFFSET
388 * @brief mailbox IRQSTATUS clear address Offset from the Mailbox base
389 * address.
390 */
391 #define MAILBOX_IRQSTATUS_CLEAR_OFFSET 0x104
393 /*!
394 * @def MAILBOX_IRQENABLE_SET_OFFSET
395 * @brief mailbox IRQ enable set address Offset from the Mailbox base
396 * address.
397 */
398 #define MAILBOX_IRQENABLE_SET_OFFSET 0x108
399 /*!
400 * @def MAILBOX_IRQENABLE_CLR_OFFSET
401 * @brief mailbox IRQ enable clear address Offset from the Mailbox base
402 * address.
403 */
404 #define MAILBOX_IRQENABLE_CLR_OFFSET 0x10C
407 /* Macro used when saving the mailbox context */
408 #define VAYU_MAILBOX_IRQENABLE(u) (0x108 + 0x10 * (u))
410 /* Msg elem used to store messages from the remote proc */
411 typedef struct VAYUIpcInt_MsgListElem_tag {
412 List_Elem elem;
413 UInt32 msg;
414 struct VAYUIpcInt_MsgListElem * next;
415 struct VAYUIpcInt_MsgListElem * prev;
416 } VAYUIpcInt_MsgListElem;
418 /* Msg elem used to store isrHandles */
419 typedef struct VAYUIpcInt_isrHandleElem_tag {
420 List_Elem elem;
421 OsalIsr_Handle isrHandle;
422 UInt32 intId;
423 Atomic refCount;
424 } VAYUIpcInt_isrHandleElem;
426 /*!
427 * @brief Device specific object
428 * It can be populated as per device need and it is used internally in
429 * the device specific implementation only.
430 */
431 typedef struct VAYUIpcInt_Object_tag {
432 Atomic isrRefCount;
433 /*!< ISR Reference count */
434 Atomic asserted;
435 /*!< Indicates receipt of interrupt from particular processor */
436 UInt32 recvIntId;
437 /*!<recevive interrupt id */
438 ArchIpcInt_CallbackFxn fxn;
439 /*!< Callbck function to be registered for particular instance of driver*/
440 Ptr fxnArgs;
441 /*!< Argument to the call back function */
442 List_Elem * isrHandle;
443 /*!< isrHandle */
444 } VAYUIpcInt_Object;
447 /*!
448 * @brief Device specific object
449 * It can be populated as per device need and it is used internally in
450 * the device specific implementation only.
451 */
452 typedef struct VAYUIpcInt_ModuleObject_tag {
453 Atomic isrRefCount;
454 /*!< ISR Reference count */
455 //OsalIsr_Handle isrHandle;
456 List_Handle isrHandles;
457 /*!< Handle to the OsalIsr object */
458 UInt16 procIds [VAYU_NUMPROCS];
459 /*!< Processors supported */
460 UInt16 maxProcessors;
461 /*!< Maximum number of processors supported by this platform*/
462 VAYUIpcInt_Object isrObjects [MultiProc_MAXPROCESSORS];
463 /*!< Array of Isr objects */
464 List_Handle isrLists [MultiProc_MAXPROCESSORS];
465 /*!< Array of Isr lists */
466 UInt32 archCoreCmBase;
467 /*!< configuration mgmt base */
468 UInt32 mailbox5Base;
469 /*!< mail box configuration mgmt base */
470 UInt32 mailbox6Base;
471 /*!< mail box configuration mgmt base */
472 UInt32 controlModuleBase;
473 /*!< control module base */
474 UInt32 intId;
475 /*!< interrupt id for this proc */
476 } VAYUIpcInt_ModuleObject;
480 /* =============================================================================
481 * Forward declarations of internal functions.
482 * =============================================================================
483 */
484 /* This function implements the interrupt service routine for the interrupt
485 * received from the remote processor.
486 */
487 static Bool _VAYUIpcInt_isr (Ptr ref);
489 /*!
490 * @brief Forward declaration of check and clear function
491 */
492 static Bool _VAYUIpcInt_checkAndClearFunc (Ptr arg);
495 /* =============================================================================
496 * Globals
497 * =============================================================================
498 */
499 /*!
500 * @brief State object for VAYUIpcInt
501 */
502 VAYUIpcInt_ModuleObject VAYUIpcInt_state;
504 /*!
505 * @brief Function table for OMAP3530
506 */
507 ArchIpcInt_FxnTable VAYUIpcInt_fxnTable = {
508 VAYUIpcInt_interruptRegister,
509 VAYUIpcInt_interruptUnregister,
510 VAYUIpcInt_interruptEnable,
511 VAYUIpcInt_interruptDisable,
512 VAYUIpcInt_waitClearInterrupt,
513 VAYUIpcInt_sendInterrupt,
514 VAYUIpcInt_clearInterrupt,
515 };
517 int mailbox_5_context_ipu1[MAILBOX_SIZE];
518 int mailbox_5_context_ipu2[MAILBOX_SIZE];
519 int mailbox_6_context[MAILBOX_SIZE];
521 /* =============================================================================
522 * APIs
523 * =============================================================================
524 */
526 /*!
527 * @brief Function to initialize the VAYUIpcInt module.
528 *
529 * @param cfg Configuration for setup
530 *
531 * @sa VAYUIpcInt_destroy
532 */
533 Void
534 VAYUIpcInt_setup (VAYUIpcInt_Config * cfg)
535 {
536 #if !defined(IPC_BUILD_OPTIMIZE)
537 Int status = VAYUIPCINT_SUCCESS;
538 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
539 Int i = 0;
540 Memory_MapInfo mapInfo;
541 List_Params listParams;
543 GT_1trace (curTrace, GT_ENTER, "VAYUIpcInt_setup", cfg);
545 GT_assert (curTrace, (cfg != NULL));
547 /* The setup will be called only once, either from SysMgr or from
548 * archipcvayu module. Hence it does not need to be atomic.
549 */
550 #if !defined(IPC_BUILD_OPTIMIZE)
551 if (cfg == NULL) {
552 GT_setFailureReason (curTrace,
553 GT_4CLASS,
554 "VAYUIpcInt_setup",
555 VAYUIPCINT_E_FAIL,
556 "config for driver specific setup can not be NULL");
557 }
558 else {
559 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
561 /* Map general control base */
562 mapInfo.src = AINTC_BASE_ADDR;
563 mapInfo.size = AINTC_BASE_SIZE;
564 mapInfo.isCached = FALSE;
565 #if !defined(IPC_BUILD_OPTIMIZE)
566 status =
567 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
568 Memory_map (&mapInfo);
569 #if !defined(IPC_BUILD_OPTIMIZE)
570 if (status < 0) {
571 GT_setFailureReason (curTrace,
572 GT_4CLASS,
573 "VAYUIpcInt_setup",
574 status,
575 "Failure in Memory_map for general ctrl base");
576 VAYUIpcInt_state.archCoreCmBase = 0;
577 }
578 else {
579 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
580 VAYUIpcInt_state.archCoreCmBase = mapInfo.dst;
581 /* Map mailbox5Base */
582 mapInfo.src = MAILBOX_5_BASE;
583 mapInfo.size = MAILBOX_SIZE;
584 mapInfo.isCached = FALSE;
585 #if !defined(IPC_BUILD_OPTIMIZE)
586 status =
587 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
588 Memory_map (&mapInfo);
589 #if !defined(IPC_BUILD_OPTIMIZE)
590 if (status < 0) {
591 GT_setFailureReason (curTrace,
592 GT_4CLASS,
593 "VAYUIpcInt_setup",
594 status,
595 "Failure in Memory_map for mailbox5Base");
596 VAYUIpcInt_state.mailbox5Base = 0;
597 }
598 else {
599 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
600 VAYUIpcInt_state.mailbox5Base = mapInfo.dst;
601 /* Map mailbox5Base */
602 mapInfo.src = MAILBOX_6_BASE;
603 mapInfo.size = MAILBOX_SIZE;
604 mapInfo.isCached = FALSE;
605 #if !defined(IPC_BUILD_OPTIMIZE)
606 status =
607 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
608 Memory_map (&mapInfo);
609 #if !defined(IPC_BUILD_OPTIMIZE)
610 if (status < 0) {
611 GT_setFailureReason (curTrace,
612 GT_4CLASS,
613 "VAYUIpcInt_setup",
614 status,
615 "Failure in Memory_map for mailbox6Base");
616 VAYUIpcInt_state.mailbox6Base = 0;
617 }
618 else {
619 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
620 VAYUIpcInt_state.mailbox6Base = mapInfo.dst;
621 /* Map mailbox5Base */
622 mapInfo.src = CTRL_MODULE_BASE;
623 mapInfo.size = CTRL_MODULE_SIZE;
624 mapInfo.isCached = FALSE;
625 #if !defined(IPC_BUILD_OPTIMIZE)
626 status =
627 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
628 Memory_map (&mapInfo);
629 #if !defined(IPC_BUILD_OPTIMIZE)
630 if (status < 0) {
631 GT_setFailureReason (curTrace,
632 GT_4CLASS,
633 "VAYUIpcInt_setup",
634 status,
635 "Failure in Memory_map for mailbox6Base");
636 VAYUIpcInt_state.controlModuleBase = 0;
637 }
638 else {
639 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
640 VAYUIpcInt_state.controlModuleBase = mapInfo.dst;
642 /* Program the MMR lock registers to access the SCM
643 * IRQ crossbar register address range */
644 REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_MMR_OFFSET) = 0xF757FDC0;
646 /* Reset Mailbox 5 */
647 REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) =
648 REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) | 0x1;
649 while (REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) == 0x1);
650 /*Set Mailbox to Smart Idle */
651 REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
652 /* Reset Mailbox 6 */
653 REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) =
654 REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) | 0x1;
655 while (REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) == 0x1);
656 /*Set Mailbox to Smart Idle */
657 REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
658 #if !defined(IPC_BUILD_OPTIMIZE)
659 }
660 }
661 }
662 }
663 if (status >= 0) {
664 /*Registering vayu platform with ArchIpcInt*/
665 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
666 ArchIpcInt_object.fxnTable = &VAYUIpcInt_fxnTable;
667 ArchIpcInt_object.obj = &VAYUIpcInt_state;
669 for (i = 0; i < MultiProc_getNumProcessors(); i++ ) {
670 Atomic_set (&(VAYUIpcInt_state.isrObjects [i].asserted), 1);
671 List_Params_init(&listParams);
672 VAYUIpcInt_state.isrLists [i] = List_create(&listParams);
673 if (VAYUIpcInt_state.isrLists [i] == NULL) {
674 status = VAYUIPCINT_E_MEMORY;
675 GT_setFailureReason (curTrace,
676 GT_4CLASS,
677 "VAYUIpcInt_setup",
678 status,
679 "Failure in List_create");
680 for (i = i - 1; i >= 0; i--) {
681 List_delete(&VAYUIpcInt_state.isrLists [i]);
682 }
683 break;
684 }
685 }
687 List_Params_init(&listParams);
688 VAYUIpcInt_state.isrHandles = List_create(&listParams);
690 /* Calling MultiProc APIs here in setup save time in ISR and makes
691 * it small and fast with less overhead. This can be done
692 * regardless of status.
693 */
694 VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1] =
695 MultiProc_getId ("DSP1");
696 VAYUIpcInt_state.procIds [VAYU_INDEX_DSP2] =
697 MultiProc_getId ("DSP2");
698 VAYUIpcInt_state.procIds [VAYU_INDEX_IPU1] =
699 MultiProc_getId ("IPU1");
700 VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2] =
701 MultiProc_getId ("IPU2");
702 VAYUIpcInt_state.maxProcessors = MultiProc_getNumProcessors();
704 if (status >= 0) {
705 ArchIpcInt_object.isSetup = TRUE;
706 }
707 #if !defined(IPC_BUILD_OPTIMIZE)
708 }
709 }
710 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
712 GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_setup");
713 }
716 /*!
717 * @brief Function to finalize the VAYUIpcInt module
718 *
719 * @sa VAYUIpcInt_setup
720 */
721 Void
722 VAYUIpcInt_destroy (Void)
723 {
724 Memory_UnmapInfo unmapInfo;
725 UInt32 i = 0;
726 List_Elem * elem = NULL, * temp = NULL;
728 GT_0trace (curTrace, GT_ENTER, "VAYUIpcInt_destroy");
730 GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
732 ArchIpcInt_object.isSetup = FALSE;
733 ArchIpcInt_object.obj = NULL;
734 ArchIpcInt_object.fxnTable = NULL;
736 for (i = 0; i < MultiProc_getNumProcessors(); i++ ) {
737 if (VAYUIpcInt_state.isrLists [i]) {
738 List_delete(&VAYUIpcInt_state.isrLists [i]);
739 }
740 }
742 List_traverse_safe(elem, temp, VAYUIpcInt_state.isrHandles) {
743 Memory_free(NULL, elem, sizeof(VAYUIpcInt_isrHandleElem));
744 }
745 List_delete(&VAYUIpcInt_state.isrHandles);
747 if (VAYUIpcInt_state.archCoreCmBase != (UInt32) NULL) {
748 unmapInfo.addr = VAYUIpcInt_state.archCoreCmBase;
749 unmapInfo.size = AINTC_BASE_SIZE;
750 unmapInfo.isCached = FALSE;
751 Memory_unmap (&unmapInfo);
752 VAYUIpcInt_state.archCoreCmBase = (UInt32) NULL;
753 }
755 if (VAYUIpcInt_state.mailbox5Base != (UInt32) NULL) {
756 unmapInfo.addr = VAYUIpcInt_state.mailbox5Base;
757 unmapInfo.size = MAILBOX_SIZE;
758 unmapInfo.isCached = FALSE;
759 Memory_unmap (&unmapInfo);
760 VAYUIpcInt_state.mailbox5Base = (UInt32) NULL;
761 }
763 if (VAYUIpcInt_state.mailbox6Base != (UInt32) NULL) {
764 unmapInfo.addr = VAYUIpcInt_state.mailbox6Base;
765 unmapInfo.size = MAILBOX_SIZE;
766 unmapInfo.isCached = FALSE;
767 Memory_unmap (&unmapInfo);
768 VAYUIpcInt_state.mailbox6Base = (UInt32) NULL;
769 }
771 if (VAYUIpcInt_state.controlModuleBase != (UInt32) NULL) {
772 unmapInfo.addr = VAYUIpcInt_state.controlModuleBase;
773 unmapInfo.size = CTRL_MODULE_SIZE;
774 unmapInfo.isCached = FALSE;
775 Memory_unmap (&unmapInfo);
776 VAYUIpcInt_state.controlModuleBase = (UInt32) NULL;
777 }
779 GT_0trace (curTrace, GT_ENTER, "VAYUIpcInt_destroy");
780 }
783 /*!
784 * @brief Function to register the interrupt.
785 *
786 * @param procId destination procId.
787 * @param intId interrupt id.
788 * @param fxn callback function to be called on receiving interrupt.
789 * @param fxnArgs arguments to the callback function.
790 *
791 * @sa VAYUIpcInt_interruptEnable
792 */
794 Int32
795 VAYUIpcInt_interruptRegister (UInt16 procId,
796 UInt32 intId,
797 ArchIpcInt_CallbackFxn fxn,
798 Ptr fxnArgs)
799 {
800 Int32 status = VAYUIPCINT_SUCCESS;
801 OsalIsr_Params isrParams;
802 OsalIsr_Handle isrHandle;
803 List_Elem * elem = NULL;
804 UInt32 reg = 0;
805 UInt32 mboxId = 0;
807 GT_4trace (curTrace,
808 GT_ENTER,
809 "VAYUIpcInt_interruptRegister",
810 procId,
811 intId,
812 fxn,
813 fxnArgs);
815 GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
816 GT_assert(curTrace, (procId < MultiProc_MAXPROCESSORS));
817 GT_assert(curTrace, (fxn != NULL));
820 /* This sets the refCount variable if not initialized, upper 16 bits is
821 * written with module Id to ensure correctness of refCount variable.
822 */
823 Atomic_cmpmask_and_set (
824 &VAYUIpcInt_state.isrObjects [procId].isrRefCount,
825 VAYUIPCINT_MAKE_MAGICSTAMP(0),
826 VAYUIPCINT_MAKE_MAGICSTAMP(0));
828 /* This is a normal use-case, so should not be inside
829 * IPC_BUILD_OPTIMIZE.
830 */
831 if (Atomic_inc_return (&VAYUIpcInt_state.isrObjects [procId].isrRefCount)
832 != VAYUIPCINT_MAKE_MAGICSTAMP(1u)) {
833 /*! @retval VAYUIPCINT_S_ALREADYREGISTERED ISR already registered!
834 */
835 status = VAYUIPCINT_S_ALREADYREGISTERED;
836 GT_0trace (curTrace,
837 GT_2CLASS,
838 "ISR already registered!");
839 }
840 else {
841 VAYUIpcInt_state.isrObjects [procId].fxn = fxn;
842 VAYUIpcInt_state.isrObjects [procId].fxnArgs = fxnArgs;
843 VAYUIpcInt_state.isrObjects [procId].recvIntId = intId;
844 /* Enable hardware interrupt. */
845 VAYUIpcInt_interruptEnable (procId, intId);
846 }
848 isrParams.sharedInt = FALSE;
849 isrParams.checkAndClearFxn = &_VAYUIpcInt_checkAndClearFunc;
850 isrParams.fxnArgs = NULL;
851 isrParams.intId = intId;
853 /* Check if handle is already created/installed */
854 List_traverse(elem, VAYUIpcInt_state.isrHandles) {
855 if (((VAYUIpcInt_isrHandleElem *)elem)->intId == intId) {
856 Atomic_inc_return (&((VAYUIpcInt_isrHandleElem *)elem)->refCount);
857 status = VAYUIPCINT_S_ALREADYREGISTERED;
858 GT_0trace (curTrace,
859 GT_2CLASS,
860 "ISR already set !");
861 break;
862 }
863 }
864 if (elem == &((List_Object *)VAYUIpcInt_state.isrHandles)->elem) {
865 if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
866 mboxId = IRQ_XBAR_DSP1;
867 }
868 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP2]) {
869 mboxId = IRQ_XBAR_DSP2;
870 }
871 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU1]){
872 mboxId = IRQ_XBAR_IPU1;
873 }
874 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]){
875 mboxId = IRQ_XBAR_IPU2;
876 }
878 /* Program the IntXbar */
879 reg = REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_INT_m_OFFSET((intId - 32)));
880 if (((intId - 32) - CTRL_MODULE_INT_BASE) % 2) {
881 REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_INT_m_OFFSET((intId - 32))) =
882 (reg & 0x0000FFFF) | (mboxId << 16);
883 }
884 else {
885 REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_INT_m_OFFSET((intId - 32))) =
886 (reg & 0xFFFF0000) | (mboxId);
887 }
888 isrHandle = OsalIsr_create (&_VAYUIpcInt_isr, NULL, &isrParams);
889 #if !defined(IPC_BUILD_OPTIMIZE)
890 if (isrHandle == NULL) {
891 /*! @retval VAYUIPCINT_E_FAIL OsalIsr_create failed */
892 status = VAYUIPCINT_E_FAIL;
893 GT_setFailureReason (curTrace,
894 GT_4CLASS,
895 "VAYUIpcInt_interruptRegister",
896 status,
897 "OsalIsr_create failed");
898 }
899 else {
900 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
901 status = OsalIsr_install (isrHandle);
902 #if !defined(IPC_BUILD_OPTIMIZE)
903 if (status < 0) {
904 GT_setFailureReason (curTrace,
905 GT_4CLASS,
906 "VAYUIpcInt_interruptRegister",
907 status,
908 "OsalIsr_install failed");
909 }
910 else {
911 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
912 elem = Memory_alloc(NULL, sizeof(VAYUIpcInt_isrHandleElem),
913 0, NULL);
914 #if !defined(IPC_BUILD_OPTIMIZE)
915 if (elem == NULL) {
916 status = VAYUIPCINT_E_MEMORY;
917 GT_setFailureReason (curTrace,
918 GT_4CLASS,
919 "VAYUIpcInt_interruptRegister",
920 status,
921 "Memory_alloc failed");
922 }
923 else {
924 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
925 ((VAYUIpcInt_isrHandleElem *)elem)->isrHandle = isrHandle;
926 Atomic_cmpmask_and_set (
927 &((VAYUIpcInt_isrHandleElem *)elem)->refCount,
928 VAYUIPCINT_MAKE_MAGICSTAMP(0),
929 VAYUIPCINT_MAKE_MAGICSTAMP(1));
930 ((VAYUIpcInt_isrHandleElem *)elem)->intId = intId;
931 List_put(VAYUIpcInt_state.isrHandles, elem);
932 #if !defined(IPC_BUILD_OPTIMIZE)
933 }
934 }
935 }
936 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
937 }
939 #if !defined(IPC_BUILD_OPTIMIZE)
940 if (status >= 0) {
941 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
942 VAYUIpcInt_state.isrObjects [procId].isrHandle = elem;
943 #if !defined(IPC_BUILD_OPTIMIZE)
944 }
945 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
947 GT_1trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptRegister", status);
949 /*! @retval VAYUIPCINT_SUCCESS Interrupt successfully registered */
950 return status;
951 }
955 /*!
956 * @brief Function to unregister interrupt.
957 *
958 * @param procId destination procId
959 *
960 * @sa VAYUIpcInt_interruptRegister
961 */
962 Int32
963 VAYUIpcInt_interruptUnregister (UInt16 procId)
964 {
965 Int32 status = VAYUIPCINT_SUCCESS;
966 #if !defined(IPC_BUILD_OPTIMIZE)
967 Int32 tmpStatus = VAYUIPCINT_SUCCESS;
968 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
969 VAYUIpcInt_isrHandleElem * isrHandleElem;
971 GT_1trace (curTrace,GT_ENTER,"VAYUIpcInt_interruptUnregister", procId);
973 GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
974 GT_assert(curTrace, (procId < MultiProc_MAXPROCESSORS));
976 #if !defined(IPC_BUILD_OPTIMIZE)
977 if ( Atomic_cmpmask_and_lt (
978 &VAYUIpcInt_state.isrObjects [procId].isrRefCount,
979 VAYUIPCINT_MAKE_MAGICSTAMP(0),
980 VAYUIPCINT_MAKE_MAGICSTAMP(1))
981 == TRUE) {
982 /*! @retval VAYUIPCINT_E_INVALIDSTATE ISR was not registered */
983 status = VAYUIPCINT_E_INVALIDSTATE;
984 GT_setFailureReason (curTrace,
985 GT_4CLASS,
986 "VAYUIpcInt_interruptUnregister",
987 status,
988 "ISR was not registered!");
989 }
990 else {
991 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
992 /* This is a normal use-case, so should not be inside
993 * IPC_BUILD_OPTIMIZE.
994 */
995 if (Atomic_dec_return(&VAYUIpcInt_state.isrObjects[procId].isrRefCount)
996 == VAYUIPCINT_MAKE_MAGICSTAMP(0)) {
997 /* Disable hardware interrupt. */
998 VAYUIpcInt_interruptDisable (procId,
999 VAYUIpcInt_state.isrObjects [procId].recvIntId);
1001 VAYUIpcInt_state.isrObjects [procId].fxn = NULL;
1002 VAYUIpcInt_state.isrObjects [procId].fxnArgs = NULL;
1003 VAYUIpcInt_state.isrObjects [procId].recvIntId = -1u;
1004 }
1006 isrHandleElem = (VAYUIpcInt_isrHandleElem *)VAYUIpcInt_state.isrObjects [procId].isrHandle;
1008 if ( Atomic_dec_return (&isrHandleElem->refCount)
1009 == VAYUIPCINT_MAKE_MAGICSTAMP(0)) {
1010 List_remove(VAYUIpcInt_state.isrHandles, (List_Elem *)isrHandleElem);
1011 status = OsalIsr_uninstall (isrHandleElem->isrHandle);
1012 #if !defined(IPC_BUILD_OPTIMIZE)
1013 if (status < 0) {
1014 GT_setFailureReason (curTrace,
1015 GT_4CLASS,
1016 "VAYUIpcInt_interruptUnregister",
1017 status,
1018 "OsalIsr_uninstall failed");
1019 }
1020 tmpStatus =
1021 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
1022 OsalIsr_delete (&(isrHandleElem->isrHandle));
1023 #if !defined(IPC_BUILD_OPTIMIZE)
1024 if ((status >= 0) && (tmpStatus < 0)) {
1025 status = tmpStatus;
1026 GT_setFailureReason (curTrace,
1027 GT_4CLASS,
1028 "VAYUIpcInt_interruptUnregister",
1029 status,
1030 "OsalIsr_delete failed");
1031 }
1032 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
1033 Memory_free(NULL, isrHandleElem, sizeof(VAYUIpcInt_isrHandleElem));
1034 }
1035 #if !defined(IPC_BUILD_OPTIMIZE)
1036 }
1037 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
1039 GT_1trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptUnregister",
1040 status);
1042 /*! @retval VAYUIPCINT_SUCCESS Interrupt successfully unregistered */
1043 return status;
1044 }
1047 /*!
1048 * @brief Function to enable the specified interrupt
1049 *
1050 * @param procId Remote processor ID
1051 * @param intId interrupt id
1052 *
1053 * @sa VAYUIpcInt_interruptDisable
1054 */
1055 Void
1056 VAYUIpcInt_interruptEnable (UInt16 procId, UInt32 intId)
1057 {
1058 GT_2trace (curTrace, GT_ENTER, "VAYUIpcInt_interruptEnable",
1059 procId, intId);
1061 GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1062 GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1064 if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1065 /*
1066 * Mailbox 5 is used for HOST<->DSP1 communication
1067 */
1068 SET_BIT(REG(VAYUIpcInt_state.mailbox5Base + \
1069 VAYU_MAILBOX_IRQENABLE(VAYU_HOST_USER_ID)),
1070 ( (DSP1_HOST_SUB_MBOX) << 1));
1071 }
1072 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP2]) {
1073 /*
1074 * Mailbox 6 is used for HOST<->DSP2 communication
1075 */
1076 SET_BIT(REG(VAYUIpcInt_state.mailbox6Base + \
1077 VAYU_MAILBOX_IRQENABLE(VAYU_HOST_USER_ID)),
1078 ( (DSP2_HOST_SUB_MBOX) << 1));
1079 }
1080 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU1]) {
1081 /*
1082 * Mailbox 5 is used for HOST<->IPU1 communication
1083 */
1084 SET_BIT(REG(VAYUIpcInt_state.mailbox5Base + \
1085 VAYU_MAILBOX_IRQENABLE(VAYU_HOST_USER_ID)),
1086 ( (IPU1_HOST_SUB_MBOX) << 1));
1087 }
1088 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1089 /*
1090 * Mailbox 6 is used for HOST<->IPU2 communication
1091 */
1092 SET_BIT(REG(VAYUIpcInt_state.mailbox6Base + \
1093 VAYU_MAILBOX_IRQENABLE(VAYU_HOST_USER_ID)),
1094 ( (IPU2_HOST_SUB_MBOX) << 1));
1095 }
1096 #if !defined(IPC_BUILD_OPTIMIZE)
1097 else {
1098 GT_setFailureReason (curTrace,
1099 GT_4CLASS,
1100 "VAYUIpcInt_interruptEnable",
1101 VAYUIPCINT_E_FAIL,
1102 "Invalid procId specified");
1103 }
1104 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
1106 GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptEnable");
1107 }
1110 /*!
1111 * @brief Function to disable the specified interrupt
1112 *
1113 * @param procId Remote processor ID
1114 * @param intId interrupt id
1115 *
1116 * @sa VAYUIpcInt_interruptEnable
1117 */
1118 Void
1119 VAYUIpcInt_interruptDisable (UInt16 procId, UInt32 intId)
1120 {
1121 GT_2trace (curTrace, GT_ENTER, "VAYUIpcInt_interruptDisable",
1122 procId, intId);
1124 GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1125 GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1127 if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1128 /*
1129 * Mailbox 5 is used for HOST<->DSP1 communication
1130 */
1131 REG(VAYUIpcInt_state.mailbox5Base + \
1132 MAILBOX_IRQENABLE_CLR_OFFSET + (0x10 * VAYU_HOST_USER_ID)) =
1133 1 << ((DSP1_HOST_SUB_MBOX) << 1);
1134 }
1135 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP2]) {
1136 /*
1137 * Mailbox 6 is used for HOST<->DSP2 communication
1138 */
1139 REG(VAYUIpcInt_state.mailbox6Base + \
1140 MAILBOX_IRQENABLE_CLR_OFFSET + (0x10 * VAYU_HOST_USER_ID)) =
1141 1 << ((DSP2_HOST_SUB_MBOX) << 1);
1142 }
1143 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU1]) {
1144 /*
1145 * Mailbox 5 is used for HOST<->IPU1 communication
1146 */
1147 REG(VAYUIpcInt_state.mailbox5Base + \
1148 MAILBOX_IRQENABLE_CLR_OFFSET + (0x10 * VAYU_HOST_USER_ID)) =
1149 1 << ((IPU1_HOST_SUB_MBOX) << 1);
1150 }
1151 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1152 /*
1153 * Mailbox 6 is used for HOST<->IPU2 communication
1154 */
1155 REG(VAYUIpcInt_state.mailbox6Base + \
1156 MAILBOX_IRQENABLE_CLR_OFFSET + (0x10 * VAYU_HOST_USER_ID)) =
1157 1 << ((IPU2_HOST_SUB_MBOX) << 1);
1158 }
1159 #if !defined(IPC_BUILD_OPTIMIZE)
1160 else {
1161 GT_setFailureReason (curTrace,
1162 GT_4CLASS,
1163 "VAYUIpcInt_interruptDisable",
1164 VAYUIPCINT_E_FAIL,
1165 "Invalid procId specified");
1166 }
1167 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
1169 GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptDisable");
1170 }
1173 /*!
1174 * @brief Function to wait for interrupt to be cleared.
1175 *
1176 * @param procId Remote processor ID
1177 * @param intId interrupt id
1178 *
1179 * @sa VAYUIpcInt_sendInterrupt
1180 */
1181 Int32
1182 VAYUIpcInt_waitClearInterrupt (UInt16 procId, UInt32 intId)
1183 {
1184 Int32 status = VAYUIPCINT_SUCCESS;
1186 GT_2trace (curTrace,GT_ENTER,"VAYUIpcInt_waitClearInterrupt",
1187 procId, intId);
1189 GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1190 GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1192 if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1193 /* Wait for DSP to clear the previous interrupt */
1194 while( ( REG32(( VAYUIpcInt_state.mailbox5Base
1195 + MAILBOX_MSGSTATUS_m_OFFSET(HOST_DSP1_SUB_MBOX)))
1196 & 0x3F ));
1197 }
1198 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP2]) {
1199 /* Wait for DSP to clear the previous interrupt */
1200 while( ( REG32(( VAYUIpcInt_state.mailbox6Base
1201 + MAILBOX_MSGSTATUS_m_OFFSET(HOST_DSP2_SUB_MBOX)))
1202 & 0x3F ));
1203 }
1204 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU1]) {
1205 /* Wait for M4 to clear the previous interrupt */
1206 while( ( REG32((VAYUIpcInt_state.mailbox5Base
1207 + MAILBOX_MSGSTATUS_m_OFFSET(HOST_IPU1_SUB_MBOX)))
1208 & 0x3F ));
1209 }
1210 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1211 /* Wait for M4 to clear the previous interrupt */
1212 while( ( REG32((VAYUIpcInt_state.mailbox6Base
1213 + MAILBOX_MSGSTATUS_m_OFFSET(HOST_IPU2_SUB_MBOX)))
1214 & 0x3F ));
1215 }
1216 #if !defined(IPC_BUILD_OPTIMIZE)
1217 else {
1218 /*! @retval VAYUIPCINT_E_FAIL Invalid procId specified */
1219 status = VAYUIPCINT_E_FAIL;
1220 GT_setFailureReason (curTrace,
1221 GT_4CLASS,
1222 "VAYUIpcInt_waitClearInterrupt",
1223 status,
1224 "Invalid procId specified");
1225 }
1226 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
1228 GT_1trace (curTrace,GT_LEAVE,"VAYUIpcInt_waitClearInterrupt", status);
1230 /*! @retval VAYUIPCINT_SUCCESS Wait for interrupt clearing successfully
1231 completed. */
1232 return status ;
1233 }
1236 /*!
1237 * @brief Function to send a specified interrupt to the DSP.
1238 *
1239 * @param procId Remote processor ID
1240 * @param intId interrupt id
1241 * @param value Value to be sent with the interrupt
1242 *
1243 * @sa VAYUIpcInt_waitClearInterrupt
1244 */
1245 Int32
1246 VAYUIpcInt_sendInterrupt (UInt16 procId, UInt32 intId, UInt32 value)
1247 {
1248 Int32 status = VAYUIPCINT_SUCCESS;
1250 GT_3trace (curTrace, GT_ENTER, "VAYUIpcInt_sendInterrupt",
1251 procId, intId, value);
1253 GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1254 GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1256 if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1257 /*
1258 * Mailbox 5 is used for HOST<->DSP1 communication
1259 */
1260 REG32(VAYUIpcInt_state.mailbox5Base + \
1261 MAILBOX_MESSAGE_m_OFFSET(HOST_DSP1_SUB_MBOX)) = value;
1262 }
1263 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP2]) {
1264 /*
1265 * Mailbox 6 is used for HOST<->DSP2 communication
1266 */
1267 REG32(VAYUIpcInt_state.mailbox6Base + \
1268 MAILBOX_MESSAGE_m_OFFSET(HOST_DSP2_SUB_MBOX)) = value;
1269 }
1270 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU1]) {
1271 /*
1272 * Mailbox 5 is used for HOST<->IPU1 communication
1273 */
1274 REG32(VAYUIpcInt_state.mailbox5Base + \
1275 MAILBOX_MESSAGE_m_OFFSET(HOST_IPU1_SUB_MBOX)) = value;
1276 }
1277 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1278 /*
1279 * Mailbox 6 is used for HOST<->IPU2 communication
1280 */
1281 REG32(VAYUIpcInt_state.mailbox6Base + \
1282 MAILBOX_MESSAGE_m_OFFSET(HOST_IPU2_SUB_MBOX)) = value;
1283 }
1284 #if !defined(IPC_BUILD_OPTIMIZE)
1285 else {
1286 /*! @retval VAYUIPCINT_E_FAIL Invalid procId specified */
1287 status = VAYUIPCINT_E_FAIL;
1288 GT_setFailureReason (curTrace,
1289 GT_4CLASS,
1290 "VAYUIpcInt_sendInterrupt",
1291 status,
1292 "Invalid procId specified");
1293 }
1294 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
1296 GT_1trace (curTrace, GT_LEAVE, "VAYUIpcInt_sendInterrupt",status);
1298 /*! @retval VAYUIPCINT_SUCCESS Interrupt successfully sent */
1299 return status;
1300 }
1303 /*!
1304 * @brief Function to clear the specified interrupt received from the
1305 * remote core.
1306 *
1307 * @param procId Remote processor ID
1308 * @param intId interrupt id
1309 *
1310 * @sa VAYUIpcInt_sendInterrupt
1311 */
1312 UInt32
1313 VAYUIpcInt_clearInterrupt (UInt16 procId, UInt16 mboxNum)
1314 {
1315 UInt32 retVal = 0;
1316 UInt32 mailboxBase = 0;
1318 GT_1trace (curTrace,GT_ENTER,"VAYUIpcInt_clearInterrupt", mboxNum);
1320 GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1321 if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2] ||
1322 procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP2])
1323 mailboxBase = VAYUIpcInt_state.mailbox6Base;
1324 else
1325 mailboxBase = VAYUIpcInt_state.mailbox5Base;
1327 if (mboxNum < MAILBOX_MAXNUM) {
1328 /* Read the register to get the entry from the mailbox FIFO */
1329 retVal = REG32(mailboxBase + MAILBOX_MESSAGE_m_OFFSET(mboxNum));
1331 /* Clear the IRQ status.
1332 * If there are more in the mailbox FIFO, it will re-assert.
1333 */
1334 REG32(mailboxBase + MAILBOX_IRQSTATUS_CLEAR_OFFSET + \
1335 (0x10 * VAYU_HOST_USER_ID)) = 0x1 << (mboxNum << 1);
1336 }
1337 #if !defined(IPC_BUILD_OPTIMIZE)
1338 else {
1339 GT_setFailureReason (curTrace,
1340 GT_4CLASS,
1341 "VAYUIpcInt_clearInterrupt",
1342 VAYUIPCINT_E_FAIL,
1343 "Invalid mailbox number specified");
1344 }
1345 #endif /* if !defined(IPC_BUILD_OPTIMIZE) */
1347 GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_clearInterrupt");
1349 /*! @retval Value Value received with the interrupt. */
1350 return retVal;
1351 }
1354 /*
1355 * Instead of constantly allocating and freeing the msg structures
1356 * we just cache a few of them, and recycle them instead.
1357 */
1358 #define CACHE_NUM 20
1359 static VAYUIpcInt_MsgListElem *msg_cache;
1360 static int num_msg = 0;
1362 static VAYUIpcInt_MsgListElem *get_msg()
1363 {
1364 VAYUIpcInt_MsgListElem *msg;
1365 IArg key = NULL;
1367 key = Gate_enterSystem();
1368 msg = msg_cache;
1369 if (msg != NULL) {
1370 msg_cache = (VAYUIpcInt_MsgListElem *)msg_cache->next;
1371 num_msg--;
1372 Gate_leaveSystem(key);
1373 } else {
1374 Gate_leaveSystem(key);
1375 msg = Memory_alloc(NULL, sizeof(VAYUIpcInt_MsgListElem), 0, NULL);
1376 }
1377 return(msg);
1378 }
1380 static void put_msg(VAYUIpcInt_MsgListElem * msg)
1381 {
1382 IArg key = NULL;
1383 key = Gate_enterSystem();
1384 if (num_msg >= CACHE_NUM) {
1385 Gate_leaveSystem(key);
1386 Memory_free(NULL, msg, sizeof(*msg));
1387 } else {
1388 msg->next = (struct VAYUIpcInt_MsgListElem *)msg_cache;
1389 msg_cache = msg;
1390 num_msg++;
1391 Gate_leaveSystem(key);
1392 }
1393 return;
1394 }
1397 /*!
1398 * @brief Function to check and clear the remote proc interrupt
1399 *
1400 * @param arg Optional argument to the function.
1401 *
1402 * @sa _VAYUIpcInt_isr
1403 */
1404 static
1405 Bool
1406 _VAYUIpcInt_checkAndClearFunc (Ptr arg)
1407 {
1408 UInt16 procId;
1409 UInt32 msg;
1410 VAYUIpcInt_MsgListElem * elem = NULL;
1412 GT_1trace (curTrace, GT_ENTER, "_VAYUIpcInt_checkAndClearFunc", arg);
1414 if (REG32(VAYUIpcInt_state.mailbox6Base
1415 + MAILBOX_MSGSTATUS_m_OFFSET(IPU2_HOST_SUB_MBOX)) != 0 ){
1416 procId = VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2];
1417 msg = VAYUIpcInt_clearInterrupt (procId, IPU2_HOST_SUB_MBOX);
1419 GT_1trace (curTrace, GT_1CLASS, "Got msg [0x%08x] from IPU2", msg);
1421 /* This is a message from IPU2, put the message in IPU2's list */
1422 elem = get_msg();
1423 if (elem) {
1424 elem->msg = msg;
1425 List_put(VAYUIpcInt_state.isrLists[procId], (List_Elem *)elem);
1426 }
1427 }
1428 if (REG32(VAYUIpcInt_state.mailbox5Base
1429 + MAILBOX_MSGSTATUS_m_OFFSET(IPU1_HOST_SUB_MBOX)) != 0 ){
1430 procId = VAYUIpcInt_state.procIds [VAYU_INDEX_IPU1];
1431 msg = VAYUIpcInt_clearInterrupt (procId, IPU1_HOST_SUB_MBOX);
1433 GT_1trace (curTrace, GT_1CLASS, "Got msg [0x%08x] from IPU1", msg);
1435 /* This is a message from IPU1, put the message in IPU1's list */
1436 elem = get_msg();
1437 if (elem) {
1438 elem->msg = msg;
1439 List_put(VAYUIpcInt_state.isrLists[procId], (List_Elem *)elem);
1440 }
1441 }
1442 if (REG32(VAYUIpcInt_state.mailbox6Base
1443 + MAILBOX_MSGSTATUS_m_OFFSET(DSP2_HOST_SUB_MBOX)) != 0 ){
1444 procId = VAYUIpcInt_state.procIds [VAYU_INDEX_DSP2];
1445 msg = VAYUIpcInt_clearInterrupt (procId, DSP2_HOST_SUB_MBOX);
1447 GT_1trace (curTrace, GT_1CLASS, "Got msg [0x%08x] from DSP2", msg);
1449 /* This is a message from DSP2, put the message in DSP2's list */
1450 elem = get_msg();
1451 if (elem) {
1452 elem->msg = msg;
1453 List_put(VAYUIpcInt_state.isrLists[procId], (List_Elem *)elem);
1454 }
1455 }
1456 if (REG32(VAYUIpcInt_state.mailbox5Base
1457 + MAILBOX_MSGSTATUS_m_OFFSET(DSP1_HOST_SUB_MBOX)) != 0 ){
1458 procId = VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1];
1459 msg = VAYUIpcInt_clearInterrupt (procId, DSP1_HOST_SUB_MBOX);
1461 GT_1trace (curTrace, GT_1CLASS, "Got msg [0x%08x] from DSP1", msg);
1463 /* This is a message from DSP1, put the message in DSP1's list */
1464 elem = get_msg();
1465 if (elem) {
1466 elem->msg = msg;
1467 List_put(VAYUIpcInt_state.isrLists[procId], (List_Elem *)elem);
1468 }
1469 }
1471 GT_1trace (curTrace, GT_LEAVE, "_VAYUIpcInt_checkAndClearFunc", TRUE);
1473 /* This is not a shared interrupt, so interrupt has always occurred */
1474 /*! @retval TRUE Interrupt has occurred. */
1475 return (TRUE);
1476 }
1479 /*!
1480 * @brief Interrupt Service Routine for VAYUIpcInt module
1481 *
1482 * @param arg Optional argument to the function.
1483 *
1484 * @sa _VAYUIpcInt_checkAndClearFunc
1485 */
1486 static
1487 Bool
1488 _VAYUIpcInt_isr (Ptr ref)
1489 {
1490 UInt16 i = 0;
1491 VAYUIpcInt_MsgListElem * elem = NULL;
1492 GT_1trace (curTrace, GT_ENTER, "_VAYUIpcInt_isr", ref);
1494 for (i = 0 ; i < VAYUIpcInt_state.maxProcessors ; i++) {
1495 if ((elem = List_get(VAYUIpcInt_state.isrLists [i])) != NULL) {
1496 /*Calling the particular ISR */
1497 GT_assert(curTrace,(VAYUIpcInt_state.isrObjects [i].fxn != NULL));
1498 if (VAYUIpcInt_state.isrObjects [i].fxn != NULL) {
1499 VAYUIpcInt_state.isrObjects [i].fxn (elem->msg,
1500 VAYUIpcInt_state.isrObjects [i].fxnArgs);
1501 }
1502 put_msg(elem);
1503 }
1504 }
1506 GT_1trace (curTrace, GT_LEAVE, "_VAYUIpcInt_isr", TRUE);
1508 /*! @retval TRUE Interrupt has been handled. */
1509 return (TRUE);
1510 }
1512 #if defined (__cplusplus)
1513 }
1514 #endif