73c1e9aa1904b2104f0a3503fad593b0290e643a
[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, 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 9
113 /*!
114 * @def VAYU_VAYU_INDEX_DSP
115 * @brief Dsp index.
116 */
117 #define VAYU_INDEX_DSP1 6
118 /*!
119 * @def VAYU_INDEX_VIDEOM4
120 * @brief M4Video index.
121 */
122 #define VAYU_INDEX_VIDEOM4 1
123 /*!
124 * @def VAYU_INDEX_IPU2
125 * @brief M4Dss index.
126 */
127 #define VAYU_INDEX_IPU2 1
128 /*!
129 * @def VAYU_INDEX_HOST
130 * @brief HOST index.
131 */
132 #define VAYU_INDEX_HOST 0
134 /*!
135 * @def VAYU_HOST_IPU2_MBOX
136 * @brief Mailbox used for HOST<->IPU2 communication.
137 */
138 #define VAYU_HOST_IPU2_MBOX 6
140 /*!
141 * @def IPU2_HOST_SUB_MBOX
142 * @brief Sub-Mailbox used for HOST->IPU2 communication.
143 */
144 #define IPU2_HOST_SUB_MBOX 4
146 /*!
147 * @def HOST_IPU2_SUB_MBOX
148 * @brief Sub-Mailbox used for IPU2->HOST communication.
149 */
150 #define HOST_IPU2_SUB_MBOX 6
152 /*!
153 * @def VAYU_HOST_DSP1_2_MBOX
154 * @brief Mailbox used for HOST<->DSP1 communication.
155 */
156 #define VAYU_HOST_DSP1_MBOX 5
158 /*!
159 * @def DSP1_HOST_SUB_MBOX
160 * @brief Mailbox used for DSP1->HOST communication.
161 */
162 #define DSP1_HOST_SUB_MBOX 1
164 /*!
165 * @def HOST_DSP1_SUB_MBOX
166 * @brief Mailbox used for HOST->DSP1 communication.
167 */
168 #define HOST_DSP1_SUB_MBOX 5
170 /*!
171 * @def VAYU_HOST_USER_ID
172 * @brief User ID of HOST.
173 */
174 #define VAYU_HOST_USER_ID 2
176 /*!
177 * @def VAYU_IPU2_USER_ID
178 * @brief User ID of IPU2.
179 */
180 #define VAYU_IPU2_USER_ID 1
182 /*!
183 * @def VAYU_DSP1_USER_ID
184 * @brief User ID of DSP1.
185 */
186 #define VAYU_DSP1_USER_ID 0
188 /* Macro to make a correct module magic number with refCount */
189 #define VAYUIPCINT_MAKE_MAGICSTAMP(x) \
190 ((VAYUIPCINT_MODULEID << 12u) | (x))
192 /*!
193 * @def REG
194 * @brief Regsiter access method.
195 */
196 #define REG(x) *((volatile UInt32 *) (x))
197 #define REG32(x) (*(volatile UInt32 *) (x))
199 /* Register access method. */
200 #define REG16(A) (*(volatile UInt16 *) (A))
202 /*!
203 * @def AINTC_BASE_ADDR
204 * @brief configuraion address.
205 */
206 #define AINTC_BASE_ADDR 0x48200000
208 /*!
209 * @def AINTC_BASE_SIZE
210 * @brief size to be ioremapped.
211 */
212 #define AINTC_BASE_SIZE 0x1000
214 /*!
215 * @def CTRL_MODULE_BASE
216 * @brief configuration address.
217 */
218 #define CTRL_MODULE_BASE 0x4A002000
220 /*!
221 * @def CTRL_MODULE_SIZE
222 * @brief size to be ioremapped.
223 */
224 #define CTRL_MODULE_SIZE 0x1000
226 /*!
227 * @def CTRL_MODULE_MMR_OFFSET
228 * @brief offset in ctrl module to MMR LOCK reg.
229 */
230 #define CTRL_MODULE_MMR_OFFSET 0x544
232 /*!
233 * @def CTRL_MODULE_MPU_OFFSET
234 * @brief offset in ctrl module to MPU INTs.
235 */
236 #define CTRL_MODULE_MPU_OFFSET 0xA4C
238 /*!
239 * @def CTRL_MODULE_INT_BASE
240 * @brief interrupt num at offset.
241 */
242 #define CTRL_MODULE_INT_BASE 0x8
244 /*!
245 * @def CTRL_MODULE_INT_m_OFFSET
246 * @brief interrupt num at offset.
247 */
248 #define CTRL_MODULE_INT_m_OFFSET(m) CTRL_MODULE_MPU_OFFSET + \
249 ((((m) - CTRL_MODULE_INT_BASE) / 2) * 4)
251 /*!
252 * @def IRQ_XBAR_MBOX_6_USR_2
253 * @brief irq xbar num for mailbox 6 user 2.
254 */
255 #define IRQ_XBAR_MBOX_6_USR_2 255
257 /*!
258 * @def IRQ_XBAR_MBOX_5_USR_2
259 * @brief irq xbar num for mailbox 5 user 2.
260 */
261 #define IRQ_XBAR_MBOX_5_USR_2 251
263 /*!
264 * @def IRQ_XBAR_DSP1
265 * @brief irq xbar num for dsp1.
266 */
267 #define IRQ_XBAR_DSP1 IRQ_XBAR_MBOX_6_USR_2
269 /*!
270 * @def IRQ_XBAR_IPU2
271 * @brief irq xbar num for ipu2.
272 */
273 #define IRQ_XBAR_IPU2 IRQ_XBAR_MBOX_5_USR_2
275 /* Mailbox management values */
276 /*!
277 * @def VAYU_MAILBOX_5_BASE
278 * @brief configuraion address.
279 */
280 #define MAILBOX_5_BASE 0x48840000
282 /*!
283 * @def VAYU_MAILBOX_6_BASE
284 * @brief configuraion address.
285 */
286 #define MAILBOX_6_BASE 0x48842000
288 /*!
289 * @def MAILBOX_SIZE
290 * @brief size to be ioremapped.
291 */
292 #define MAILBOX_SIZE 0x1000
294 /*!
295 * @def MAILBOX_SYSCONFIG_OFFSET
296 * @brief Offset from the Mailbox base address.
297 */
298 #define MAILBOX_SYSCONFIG_OFFSET 0x10
300 /*!
301 * @def MAILBOX_MAXNUM
302 * @brief maximum number of mailbox.
303 */
304 #define MAILBOX_MAXNUM 0xC
306 /*!
307 * @def MAILBOX_MESSAGE_m_OFFSET
308 * @brief mailbox message address Offset from the Mailbox base
309 * address. m = 0 to 7 => offset = 0x40 + 0x4*m
310 */
311 #define MAILBOX_MESSAGE_m_OFFSET(m) (0x40 + (m<<2))
313 /*!
314 * @def MAILBOX_MSGSTATUS_m_OFFSET
315 * @brief mailbox message status address Offset from the Mailbox base
316 * address. m = 0 to 7 => offset = 0x40 + 0x4*m
317 */
318 #define MAILBOX_MSGSTATUS_m_OFFSET(m) (0xC0 + (m<<2))
320 /*!
321 * @def MAILBOX_IRQSTATUS_CLEAR_OFFSET
322 * @brief mailbox IRQSTATUS clear address Offset from the Mailbox base
323 * address.
324 */
325 #define MAILBOX_IRQSTATUS_CLEAR_OFFSET 0x104
327 /*!
328 * @def MAILBOX_IRQENABLE_SET_OFFSET
329 * @brief mailbox IRQ enable set address Offset from the Mailbox base
330 * address.
331 */
332 #define MAILBOX_IRQENABLE_SET_OFFSET 0x108
333 /*!
334 * @def MAILBOX_IRQENABLE_CLR_OFFSET
335 * @brief mailbox IRQ enable clear address Offset from the Mailbox base
336 * address.
337 */
338 #define MAILBOX_IRQENABLE_CLR_OFFSET 0x10C
341 /* Macro used when saving the mailbox context */
342 #define VAYU_MAILBOX_IRQENABLE(u) (0x108 + 0x10 * (u))
344 /* Msg elem used to store messages from the remote proc */
345 typedef struct VAYUIpcInt_MsgListElem_tag {
346 List_Elem elem;
347 UInt32 msg;
348 struct VAYUIpcInt_MsgListElem * next;
349 struct VAYUIpcInt_MsgListElem * prev;
350 } VAYUIpcInt_MsgListElem;
352 /* Msg elem used to store isrHandles */
353 typedef struct VAYUIpcInt_isrHandleElem_tag {
354 List_Elem elem;
355 OsalIsr_Handle isrHandle;
356 UInt32 intId;
357 Atomic refCount;
358 } VAYUIpcInt_isrHandleElem;
360 /*!
361 * @brief Device specific object
362 * It can be populated as per device need and it is used internally in
363 * the device specific implementation only.
364 */
365 typedef struct VAYUIpcInt_Object_tag {
366 Atomic isrRefCount;
367 /*!< ISR Reference count */
368 Atomic asserted;
369 /*!< Indicates receipt of interrupt from particular processor */
370 UInt32 recvIntId;
371 /*!<recevive interrupt id */
372 ArchIpcInt_CallbackFxn fxn;
373 /*!< Callbck function to be registered for particular instance of driver*/
374 Ptr fxnArgs;
375 /*!< Argument to the call back function */
376 List_Elem * isrHandle;
377 /*!< isrHandle */
378 } VAYUIpcInt_Object;
381 /*!
382 * @brief Device specific object
383 * It can be populated as per device need and it is used internally in
384 * the device specific implementation only.
385 */
386 typedef struct VAYUIpcInt_ModuleObject_tag {
387 Atomic isrRefCount;
388 /*!< ISR Reference count */
389 //OsalIsr_Handle isrHandle;
390 List_Handle isrHandles;
391 /*!< Handle to the OsalIsr object */
392 UInt16 procIds [VAYU_NUMPROCS];
393 /*!< Processors supported */
394 UInt16 maxProcessors;
395 /*!< Maximum number of processors supported by this platform*/
396 VAYUIpcInt_Object isrObjects [MultiProc_MAXPROCESSORS];
397 /*!< Array of Isr objects */
398 List_Handle isrLists [MultiProc_MAXPROCESSORS];
399 /*!< Array of Isr lists */
400 UInt32 archCoreCmBase;
401 /*!< configuration mgmt base */
402 UInt32 mailbox5Base;
403 /*!< mail box configuration mgmt base */
404 UInt32 mailbox6Base;
405 /*!< mail box configuration mgmt base */
406 UInt32 controlModuleBase;
407 /*!< control module base */
408 UInt32 intId;
409 /*!< interrupt id for this proc */
410 } VAYUIpcInt_ModuleObject;
414 /* =============================================================================
415 * Forward declarations of internal functions.
416 * =============================================================================
417 */
418 /* This function implements the interrupt service routine for the interrupt
419 * received from the remote processor.
420 */
421 static Bool _VAYUIpcInt_isr (Ptr ref);
423 /*!
424 * @brief Forward declaration of check and clear function
425 */
426 static Bool _VAYUIpcInt_checkAndClearFunc (Ptr arg);
429 /* =============================================================================
430 * Globals
431 * =============================================================================
432 */
433 /*!
434 * @brief State object for VAYUIpcInt
435 */
436 VAYUIpcInt_ModuleObject VAYUIpcInt_state;
438 /*!
439 * @brief Function table for OMAP3530
440 */
441 ArchIpcInt_FxnTable VAYUIpcInt_fxnTable = {
442 VAYUIpcInt_interruptRegister,
443 VAYUIpcInt_interruptUnregister,
444 VAYUIpcInt_interruptEnable,
445 VAYUIpcInt_interruptDisable,
446 VAYUIpcInt_waitClearInterrupt,
447 VAYUIpcInt_sendInterrupt,
448 VAYUIpcInt_clearInterrupt,
449 };
451 int mailbox_5_context[MAILBOX_SIZE];
452 int mailbox_6_context[MAILBOX_SIZE];
454 /* =============================================================================
455 * APIs
456 * =============================================================================
457 */
459 /*!
460 * @brief Function to initialize the VAYUIpcInt module.
461 *
462 * @param cfg Configuration for setup
463 *
464 * @sa VAYUIpcInt_destroy
465 */
466 Void
467 VAYUIpcInt_setup (VAYUIpcInt_Config * cfg)
468 {
469 #if !defined(SYSLINK_BUILD_OPTIMIZE)
470 Int status = VAYUIPCINT_SUCCESS;
471 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
472 Int i = 0;
473 Memory_MapInfo mapInfo;
474 List_Params listParams;
476 GT_1trace (curTrace, GT_ENTER, "VAYUIpcInt_setup", cfg);
478 GT_assert (curTrace, (cfg != NULL));
480 /* The setup will be called only once, either from SysMgr or from
481 * archipcvayu module. Hence it does not need to be atomic.
482 */
483 #if !defined(SYSLINK_BUILD_OPTIMIZE)
484 if (cfg == NULL) {
485 GT_setFailureReason (curTrace,
486 GT_4CLASS,
487 "VAYUIpcInt_setup",
488 VAYUIPCINT_E_FAIL,
489 "config for driver specific setup can not be NULL");
490 }
491 else {
492 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
494 /* Map general control base */
495 mapInfo.src = AINTC_BASE_ADDR;
496 mapInfo.size = AINTC_BASE_SIZE;
497 mapInfo.isCached = FALSE;
498 #if !defined(SYSLINK_BUILD_OPTIMIZE)
499 status =
500 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
501 Memory_map (&mapInfo);
502 #if !defined(SYSLINK_BUILD_OPTIMIZE)
503 if (status < 0) {
504 GT_setFailureReason (curTrace,
505 GT_4CLASS,
506 "VAYUIpcInt_setup",
507 status,
508 "Failure in Memory_map for general ctrl base");
509 VAYUIpcInt_state.archCoreCmBase = 0;
510 }
511 else {
512 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
513 VAYUIpcInt_state.archCoreCmBase = mapInfo.dst;
514 /* Map mailbox5Base */
515 mapInfo.src = MAILBOX_5_BASE;
516 mapInfo.size = MAILBOX_SIZE;
517 mapInfo.isCached = FALSE;
518 #if !defined(SYSLINK_BUILD_OPTIMIZE)
519 status =
520 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
521 Memory_map (&mapInfo);
522 #if !defined(SYSLINK_BUILD_OPTIMIZE)
523 if (status < 0) {
524 GT_setFailureReason (curTrace,
525 GT_4CLASS,
526 "VAYUIpcInt_setup",
527 status,
528 "Failure in Memory_map for mailbox5Base");
529 VAYUIpcInt_state.mailbox5Base = 0;
530 }
531 else {
532 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
533 VAYUIpcInt_state.mailbox5Base = mapInfo.dst;
534 /* Map mailbox5Base */
535 mapInfo.src = MAILBOX_6_BASE;
536 mapInfo.size = MAILBOX_SIZE;
537 mapInfo.isCached = FALSE;
538 #if !defined(SYSLINK_BUILD_OPTIMIZE)
539 status =
540 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
541 Memory_map (&mapInfo);
542 #if !defined(SYSLINK_BUILD_OPTIMIZE)
543 if (status < 0) {
544 GT_setFailureReason (curTrace,
545 GT_4CLASS,
546 "VAYUIpcInt_setup",
547 status,
548 "Failure in Memory_map for mailbox6Base");
549 VAYUIpcInt_state.mailbox6Base = 0;
550 }
551 else {
552 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
553 VAYUIpcInt_state.mailbox6Base = mapInfo.dst;
554 /* Map mailbox5Base */
555 mapInfo.src = CTRL_MODULE_BASE;
556 mapInfo.size = CTRL_MODULE_SIZE;
557 mapInfo.isCached = FALSE;
558 #if !defined(SYSLINK_BUILD_OPTIMIZE)
559 status =
560 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
561 Memory_map (&mapInfo);
562 #if !defined(SYSLINK_BUILD_OPTIMIZE)
563 if (status < 0) {
564 GT_setFailureReason (curTrace,
565 GT_4CLASS,
566 "VAYUIpcInt_setup",
567 status,
568 "Failure in Memory_map for mailbox6Base");
569 VAYUIpcInt_state.controlModuleBase = 0;
570 }
571 else {
572 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
573 VAYUIpcInt_state.controlModuleBase = mapInfo.dst;
575 /* Program the MMR lock registers to access the SCM
576 * IRQ crossbar register address range */
577 REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_MMR_OFFSET) = 0xF757FDC0;
579 /* Reset Mailbox 5 */
580 REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) =
581 REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) | 0x1;
582 while (REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) == 0x1);
583 /*Set Mailbox to Smart Idle */
584 REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
585 /* Reset Mailbox 6 */
586 REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) =
587 REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) | 0x1;
588 while (REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) == 0x1);
589 /*Set Mailbox to Smart Idle */
590 REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
591 #if !defined(SYSLINK_BUILD_OPTIMIZE)
592 }
593 }
594 }
595 }
596 if (status >= 0) {
597 /*Registering vayu platform with ArchIpcInt*/
598 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
599 ArchIpcInt_object.fxnTable = &VAYUIpcInt_fxnTable;
600 ArchIpcInt_object.obj = &VAYUIpcInt_state;
602 for (i = 0; i < MultiProc_getNumProcessors(); i++ ) {
603 Atomic_set (&(VAYUIpcInt_state.isrObjects [i].asserted), 1);
604 List_Params_init(&listParams);
605 VAYUIpcInt_state.isrLists [i] = List_create(&listParams);
606 if (VAYUIpcInt_state.isrLists [i] == NULL) {
607 status = VAYUIPCINT_E_MEMORY;
608 GT_setFailureReason (curTrace,
609 GT_4CLASS,
610 "VAYUIpcInt_setup",
611 status,
612 "Failure in List_create");
613 for (i = i - 1; i >= 0; i--) {
614 List_delete(&VAYUIpcInt_state.isrLists [i]);
615 }
616 break;
617 }
618 }
620 List_Params_init(&listParams);
621 VAYUIpcInt_state.isrHandles = List_create(&listParams);
623 /* Calling MultiProc APIs here in setup save time in ISR and makes
624 * it small and fast with less overhead. This can be done
625 * regardless of status.
626 */
627 VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1] =
628 MultiProc_getId ("DSP1");
629 VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2] =
630 MultiProc_getId ("IPU2");
631 VAYUIpcInt_state.maxProcessors = MultiProc_getNumProcessors();
633 if (status >= 0) {
634 ArchIpcInt_object.isSetup = TRUE;
635 }
636 #if !defined(SYSLINK_BUILD_OPTIMIZE)
637 }
638 }
639 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
641 GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_setup");
642 }
645 /*!
646 * @brief Function to finalize the VAYUIpcInt module
647 *
648 * @sa VAYUIpcInt_setup
649 */
650 Void
651 VAYUIpcInt_destroy (Void)
652 {
653 Memory_UnmapInfo unmapInfo;
654 UInt32 i = 0;
655 List_Elem * elem = NULL, * temp = NULL;
657 GT_0trace (curTrace, GT_ENTER, "VAYUIpcInt_destroy");
659 GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
661 ArchIpcInt_object.isSetup = FALSE;
662 ArchIpcInt_object.obj = NULL;
663 ArchIpcInt_object.fxnTable = NULL;
665 for (i = 0; i < MultiProc_getNumProcessors(); i++ ) {
666 if (VAYUIpcInt_state.isrLists [i]) {
667 List_delete(&VAYUIpcInt_state.isrLists [i]);
668 }
669 }
671 List_traverse_safe(elem, temp, VAYUIpcInt_state.isrHandles) {
672 Memory_free(NULL, elem, sizeof(VAYUIpcInt_isrHandleElem));
673 }
674 List_delete(&VAYUIpcInt_state.isrHandles);
676 if (VAYUIpcInt_state.archCoreCmBase != (UInt32) NULL) {
677 unmapInfo.addr = VAYUIpcInt_state.archCoreCmBase;
678 unmapInfo.size = AINTC_BASE_SIZE;
679 unmapInfo.isCached = FALSE;
680 Memory_unmap (&unmapInfo);
681 VAYUIpcInt_state.archCoreCmBase = (UInt32) NULL;
682 }
684 if (VAYUIpcInt_state.mailbox5Base != (UInt32) NULL) {
685 unmapInfo.addr = VAYUIpcInt_state.mailbox5Base;
686 unmapInfo.size = MAILBOX_SIZE;
687 unmapInfo.isCached = FALSE;
688 Memory_unmap (&unmapInfo);
689 VAYUIpcInt_state.mailbox5Base = (UInt32) NULL;
690 }
692 if (VAYUIpcInt_state.mailbox6Base != (UInt32) NULL) {
693 unmapInfo.addr = VAYUIpcInt_state.mailbox6Base;
694 unmapInfo.size = MAILBOX_SIZE;
695 unmapInfo.isCached = FALSE;
696 Memory_unmap (&unmapInfo);
697 VAYUIpcInt_state.mailbox6Base = (UInt32) NULL;
698 }
700 if (VAYUIpcInt_state.controlModuleBase != (UInt32) NULL) {
701 unmapInfo.addr = VAYUIpcInt_state.controlModuleBase;
702 unmapInfo.size = CTRL_MODULE_SIZE;
703 unmapInfo.isCached = FALSE;
704 Memory_unmap (&unmapInfo);
705 VAYUIpcInt_state.archCoreCmBase = (UInt32) NULL;
706 }
708 GT_0trace (curTrace, GT_ENTER, "VAYUIpcInt_destroy");
709 }
712 /*!
713 * @brief Function to register the interrupt.
714 *
715 * @param procId destination procId.
716 * @param intId interrupt id.
717 * @param fxn callback function to be called on receiving interrupt.
718 * @param fxnArgs arguments to the callback function.
719 *
720 * @sa VAYUIpcInt_interruptEnable
721 */
723 Int32
724 VAYUIpcInt_interruptRegister (UInt16 procId,
725 UInt32 intId,
726 ArchIpcInt_CallbackFxn fxn,
727 Ptr fxnArgs)
728 {
729 Int32 status = VAYUIPCINT_SUCCESS;
730 OsalIsr_Params isrParams;
731 OsalIsr_Handle isrHandle;
732 List_Elem * elem = NULL;
733 UInt32 reg = 0;
734 UInt32 mboxId = 0;
736 GT_4trace (curTrace,
737 GT_ENTER,
738 "VAYUIpcInt_interruptRegister",
739 procId,
740 intId,
741 fxn,
742 fxnArgs);
744 GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
745 GT_assert(curTrace, (procId < MultiProc_MAXPROCESSORS));
746 GT_assert(curTrace, (fxn != NULL));
749 /* This sets the refCount variable if not initialized, upper 16 bits is
750 * written with module Id to ensure correctness of refCount variable.
751 */
752 Atomic_cmpmask_and_set (
753 &VAYUIpcInt_state.isrObjects [procId].isrRefCount,
754 VAYUIPCINT_MAKE_MAGICSTAMP(0),
755 VAYUIPCINT_MAKE_MAGICSTAMP(0));
757 /* This is a normal use-case, so should not be inside
758 * SYSLINK_BUILD_OPTIMIZE.
759 */
760 if (Atomic_inc_return (&VAYUIpcInt_state.isrObjects [procId].isrRefCount)
761 != VAYUIPCINT_MAKE_MAGICSTAMP(1u)) {
762 /*! @retval VAYUIPCINT_S_ALREADYREGISTERED ISR already registered!
763 */
764 status = VAYUIPCINT_S_ALREADYREGISTERED;
765 GT_0trace (curTrace,
766 GT_2CLASS,
767 "ISR already registered!");
768 }
769 else {
770 VAYUIpcInt_state.isrObjects [procId].fxn = fxn;
771 VAYUIpcInt_state.isrObjects [procId].fxnArgs = fxnArgs;
772 VAYUIpcInt_state.isrObjects [procId].recvIntId = intId;
773 /* Enable hardware interrupt. */
774 VAYUIpcInt_interruptEnable (procId, intId);
775 }
777 isrParams.sharedInt = FALSE;
778 isrParams.checkAndClearFxn = &_VAYUIpcInt_checkAndClearFunc;
779 isrParams.fxnArgs = NULL;
780 isrParams.intId = intId;
782 /* Check if handle is already created/installed */
783 List_traverse(elem, VAYUIpcInt_state.isrHandles) {
784 if (((VAYUIpcInt_isrHandleElem *)elem)->intId == intId) {
785 Atomic_inc_return (&((VAYUIpcInt_isrHandleElem *)elem)->refCount);
786 status = VAYUIPCINT_S_ALREADYREGISTERED;
787 GT_0trace (curTrace,
788 GT_2CLASS,
789 "ISR already set !");
790 break;
791 }
792 }
793 if (elem == &((List_Object *)VAYUIpcInt_state.isrHandles)->elem) {
794 if (procId == MultiProc_getId("DSP1")) {
795 mboxId = IRQ_XBAR_DSP1;
796 }
797 else if (procId == MultiProc_getId("IPU2")){
798 mboxId = IRQ_XBAR_IPU2;
799 }
800 /* Program the IntXbar */
801 reg = REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_INT_m_OFFSET((intId - 32)));
802 if (((intId - 32) - CTRL_MODULE_INT_BASE) % 2) {
803 REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_INT_m_OFFSET((intId - 32))) =
804 (reg & 0x0000FFFF) | (mboxId << 16);
805 }
806 else {
807 REG32(VAYUIpcInt_state.controlModuleBase + CTRL_MODULE_INT_m_OFFSET((intId - 32))) =
808 (reg & 0xFFFF0000) | (mboxId);
809 }
810 isrHandle = OsalIsr_create (&_VAYUIpcInt_isr, NULL, &isrParams);
811 #if !defined(SYSLINK_BUILD_OPTIMIZE)
812 if (isrHandle == NULL) {
813 /*! @retval VAYUIPCINT_E_FAIL OsalIsr_create failed */
814 status = VAYUIPCINT_E_FAIL;
815 GT_setFailureReason (curTrace,
816 GT_4CLASS,
817 "VAYUIpcInt_interruptRegister",
818 status,
819 "OsalIsr_create failed");
820 }
821 else {
822 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
823 status = OsalIsr_install (isrHandle);
824 #if !defined(SYSLINK_BUILD_OPTIMIZE)
825 if (status < 0) {
826 GT_setFailureReason (curTrace,
827 GT_4CLASS,
828 "VAYUIpcInt_interruptRegister",
829 status,
830 "OsalIsr_install failed");
831 }
832 else {
833 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
834 elem = Memory_alloc(NULL, sizeof(VAYUIpcInt_isrHandleElem),
835 0, NULL);
836 #if !defined(SYSLINK_BUILD_OPTIMIZE)
837 if (elem == NULL) {
838 status = VAYUIPCINT_E_MEMORY;
839 GT_setFailureReason (curTrace,
840 GT_4CLASS,
841 "VAYUIpcInt_interruptRegister",
842 status,
843 "Memory_alloc failed");
844 }
845 else {
846 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
847 ((VAYUIpcInt_isrHandleElem *)elem)->isrHandle = isrHandle;
848 Atomic_cmpmask_and_set (
849 &((VAYUIpcInt_isrHandleElem *)elem)->refCount,
850 VAYUIPCINT_MAKE_MAGICSTAMP(0),
851 VAYUIPCINT_MAKE_MAGICSTAMP(1));
852 ((VAYUIpcInt_isrHandleElem *)elem)->intId = intId;
853 List_put(VAYUIpcInt_state.isrHandles, elem);
854 #if !defined(SYSLINK_BUILD_OPTIMIZE)
855 }
856 }
857 }
858 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
859 }
861 #if !defined(SYSLINK_BUILD_OPTIMIZE)
862 if (status >= 0) {
863 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
864 VAYUIpcInt_state.isrObjects [procId].isrHandle = elem;
866 /* Clear the messages in the IPU2->HOST mailbox */
867 while (REG32(VAYUIpcInt_state.mailbox6Base + \
868 MAILBOX_MSGSTATUS_m_OFFSET(IPU2_HOST_SUB_MBOX))) {
869 VAYUIpcInt_clearInterrupt(
870 VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2],
871 IPU2_HOST_SUB_MBOX);
872 }
873 /* Clear the messages in the HOST->IPU2 mailbox */
874 while (REG32(VAYUIpcInt_state.mailbox6Base + \
875 MAILBOX_MSGSTATUS_m_OFFSET(HOST_IPU2_SUB_MBOX))) {
876 VAYUIpcInt_clearInterrupt(
877 VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2],
878 HOST_IPU2_SUB_MBOX);
879 }
880 /* Clear the messages in the DSP1->HOST mailbox */
881 while (REG32(VAYUIpcInt_state.mailbox5Base + \
882 MAILBOX_MSGSTATUS_m_OFFSET(DSP1_HOST_SUB_MBOX))) {
883 VAYUIpcInt_clearInterrupt(
884 VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1],
885 DSP1_HOST_SUB_MBOX);
886 }
887 /* Clear the messages in the HOST->DSP1 mailbox */
888 while (REG32(VAYUIpcInt_state.mailbox5Base + \
889 MAILBOX_MSGSTATUS_m_OFFSET(HOST_DSP1_SUB_MBOX))) {
890 VAYUIpcInt_clearInterrupt(
891 VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1],
892 HOST_DSP1_SUB_MBOX);
893 }
894 /* The below seems to be needed for OMAP5 Virtio for
895 * slaying/restarting syslink properly
896 */
897 /* Disables interrupts from HOST->IPU2 */
898 SET_BIT(REG(VAYUIpcInt_state.mailbox6Base + \
899 MAILBOX_IRQENABLE_CLR_OFFSET + \
900 (0x10 * VAYU_IPU2_USER_ID)),
901 ((HOST_IPU2_SUB_MBOX) << 1));
902 /* Disables interrupts from HOST->DSP1 */
903 SET_BIT(REG(VAYUIpcInt_state.mailbox5Base + \
904 MAILBOX_IRQENABLE_CLR_OFFSET + \
905 (0x10 * VAYU_DSP1_USER_ID)),
906 ((HOST_DSP1_SUB_MBOX) << 1));
908 /* Set mailbox to smart-idle */
909 REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
910 REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
911 #if !defined(SYSLINK_BUILD_OPTIMIZE)
912 }
913 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
915 GT_1trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptRegister", status);
917 /*! @retval VAYUIPCINT_SUCCESS Interrupt successfully registered */
918 return status;
919 }
921 /*!
922 * @brief Function to Save context.
923 *
924 * @param procId The procId associated with the mailbox context being
925 * saved.
926 *
927 * @sa VAYUIpcInt_mbxRestoreCtxt
928 */
930 Int32
931 VAYUIpcInt_mboxSaveCtxt (UInt16 procId)
932 {
933 Int32 status = VAYUIPCINT_SUCCESS;
934 UInt32 i = 0;
936 if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2] &&
937 VAYUIpcInt_state.mailbox5Base == NULL) {
938 status = VAYUIPCINT_E_MEMORY;
939 GT_setFailureReason (curTrace,
940 GT_4CLASS,
941 "VAYUIpcInt_mboxSaveCtxt",
942 status,
943 "Unable to map the Mailbox memory in SaveCtxt");
944 }
945 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1] &&
946 VAYUIpcInt_state.mailbox6Base == NULL) {
947 status = VAYUIPCINT_E_MEMORY;
948 GT_setFailureReason (curTrace,
949 GT_4CLASS,
950 "VAYUIpcInt_mboxSaveCtxt",
951 status,
952 "Unable to map the Mailbox memory in SaveCtxt");
953 }
954 else {
955 if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
956 for (i = 0; i < 4; i++) {
957 mailbox_5_context[i] = REG32(VAYUIpcInt_state.mailbox5Base + \
958 VAYU_MAILBOX_IRQENABLE(i));
959 }
960 }
961 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
962 for (i = 0; i < 4; i++) {
963 mailbox_6_context[i] = REG32(VAYUIpcInt_state.mailbox6Base + \
964 VAYU_MAILBOX_IRQENABLE(i));
965 }
966 }
967 VAYUIpcInt_interruptDisable(procId, VAYUIpcInt_state.intId);
968 }
969 return status;
970 }
972 /*!
973 * @brief Function to Restore context.
974 *
975 * @param procId The procId associated with the mailbox context being
976 * restored.
977 *
978 * @sa VAYUIpcInt_mbxSaveCtxt
979 */
981 Int32
982 VAYUIpcInt_mboxRestoreCtxt (UInt16 procId)
983 {
984 Int32 status = VAYUIPCINT_SUCCESS;
985 UInt32 i = 0;
987 if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2] &&
988 VAYUIpcInt_state.mailbox5Base == NULL) {
989 status = VAYUIPCINT_E_MEMORY;
990 GT_setFailureReason (curTrace,
991 GT_4CLASS,
992 "VAYUIpcInt_mboxRestoreCtxt",
993 status,
994 "Unable to map the Mailbox memory in RestoreCtxt");
995 }
996 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1] &&
997 VAYUIpcInt_state.mailbox6Base == NULL) {
998 status = VAYUIPCINT_E_MEMORY;
999 GT_setFailureReason (curTrace,
1000 GT_4CLASS,
1001 "VAYUIpcInt_mboxRestoreCtxt",
1002 status,
1003 "Unable to map the Mailbox memory in RestoreCtxt");
1004 }
1005 else {
1006 if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1007 /* Set to Smart Idle mode*/
1008 REG(VAYUIpcInt_state.mailbox5Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
1010 for (i = 0; i < 4; i++) {
1011 REG32(VAYUIpcInt_state.mailbox5Base + \
1012 VAYU_MAILBOX_IRQENABLE(i)) = mailbox_5_context[i];
1013 }
1014 }
1015 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1016 /* Set to Smart Idle mode*/
1017 REG(VAYUIpcInt_state.mailbox6Base + MAILBOX_SYSCONFIG_OFFSET) = 0x8;
1019 for (i = 0; i < 4; i++) {
1020 REG32(VAYUIpcInt_state.mailbox6Base + \
1021 VAYU_MAILBOX_IRQENABLE(i)) = mailbox_6_context[i];
1022 }
1023 }
1025 VAYUIpcInt_interruptEnable(procId, VAYUIpcInt_state.intId);
1026 }
1028 return status;
1029 }
1032 /*!
1033 * @brief Function to unregister interrupt.
1034 *
1035 * @param procId destination procId
1036 *
1037 * @sa VAYUIpcInt_interruptRegister
1038 */
1039 Int32
1040 VAYUIpcInt_interruptUnregister (UInt16 procId)
1041 {
1042 Int32 status = VAYUIPCINT_SUCCESS;
1043 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1044 Int32 tmpStatus = VAYUIPCINT_SUCCESS;
1045 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1046 VAYUIpcInt_isrHandleElem * isrHandleElem;
1048 GT_1trace (curTrace,GT_ENTER,"VAYUIpcInt_interruptUnregister", procId);
1050 GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1051 GT_assert(curTrace, (procId < MultiProc_MAXPROCESSORS));
1053 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1054 if ( Atomic_cmpmask_and_lt (
1055 &VAYUIpcInt_state.isrObjects [procId].isrRefCount,
1056 VAYUIPCINT_MAKE_MAGICSTAMP(0),
1057 VAYUIPCINT_MAKE_MAGICSTAMP(1))
1058 == TRUE) {
1059 /*! @retval VAYUIPCINT_E_INVALIDSTATE ISR was not registered */
1060 status = VAYUIPCINT_E_INVALIDSTATE;
1061 GT_setFailureReason (curTrace,
1062 GT_4CLASS,
1063 "VAYUIpcInt_interruptUnregister",
1064 status,
1065 "ISR was not registered!");
1066 }
1067 else {
1068 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1069 /* This is a normal use-case, so should not be inside
1070 * SYSLINK_BUILD_OPTIMIZE.
1071 */
1072 if (Atomic_dec_return(&VAYUIpcInt_state.isrObjects[procId].isrRefCount)
1073 == VAYUIPCINT_MAKE_MAGICSTAMP(0)) {
1074 /* Disable hardware interrupt. */
1075 VAYUIpcInt_interruptDisable (procId,
1076 VAYUIpcInt_state.isrObjects [procId].recvIntId);
1078 VAYUIpcInt_state.isrObjects [procId].fxn = NULL;
1079 VAYUIpcInt_state.isrObjects [procId].fxnArgs = NULL;
1080 VAYUIpcInt_state.isrObjects [procId].recvIntId = -1u;
1081 }
1083 isrHandleElem = (VAYUIpcInt_isrHandleElem *)VAYUIpcInt_state.isrObjects [procId].isrHandle;
1085 if ( Atomic_dec_return (&isrHandleElem->refCount)
1086 == VAYUIPCINT_MAKE_MAGICSTAMP(0)) {
1087 List_remove(VAYUIpcInt_state.isrHandles, (List_Elem *)isrHandleElem);
1088 status = OsalIsr_uninstall (isrHandleElem->isrHandle);
1089 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1090 if (status < 0) {
1091 GT_setFailureReason (curTrace,
1092 GT_4CLASS,
1093 "VAYUIpcInt_interruptUnregister",
1094 status,
1095 "OsalIsr_uninstall failed");
1096 }
1097 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1098 /* Clear the messages in the IPU2->HOST mailbox */
1099 while (REG32(VAYUIpcInt_state.mailbox6Base + \
1100 MAILBOX_MSGSTATUS_m_OFFSET(IPU2_HOST_SUB_MBOX))) {
1101 VAYUIpcInt_clearInterrupt(
1102 VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2],
1103 IPU2_HOST_SUB_MBOX);
1104 }
1105 /* Clear the messages in the HOST->IPU2 mailbox */
1106 while (REG32(VAYUIpcInt_state.mailbox6Base + \
1107 MAILBOX_MSGSTATUS_m_OFFSET(HOST_IPU2_SUB_MBOX))) {
1108 VAYUIpcInt_clearInterrupt(
1109 VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2],
1110 HOST_IPU2_SUB_MBOX);
1111 }
1112 /* Clear the messages in the DSP1->HOST mailbox */
1113 while (REG32(VAYUIpcInt_state.mailbox5Base + \
1114 MAILBOX_MSGSTATUS_m_OFFSET(DSP1_HOST_SUB_MBOX))) {
1115 VAYUIpcInt_clearInterrupt(
1116 VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1],
1117 DSP1_HOST_SUB_MBOX);
1118 }
1119 /* Clear the messages in the HOST->DSP1 mailbox */
1120 while (REG32(VAYUIpcInt_state.mailbox5Base + \
1121 MAILBOX_MSGSTATUS_m_OFFSET(HOST_DSP1_SUB_MBOX))) {
1122 VAYUIpcInt_clearInterrupt(
1123 VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1],
1124 HOST_DSP1_SUB_MBOX);
1125 }
1126 /* The below seems to be needed for OMAP5 Virtio for
1127 * slaying/restarting syslink properly
1128 */
1129 /* Disables interrupts from HOST->IPU2 */
1130 SET_BIT(REG(VAYUIpcInt_state.mailbox6Base + \
1131 MAILBOX_IRQENABLE_CLR_OFFSET + \
1132 (0x10 * VAYU_IPU2_USER_ID)),
1133 ((HOST_IPU2_SUB_MBOX) << 1));
1134 /* Disables interrupts from HOST->DSP1 */
1135 SET_BIT(REG(VAYUIpcInt_state.mailbox5Base + \
1136 MAILBOX_IRQENABLE_CLR_OFFSET + \
1137 (0x10 * VAYU_DSP1_USER_ID)),
1138 ((HOST_DSP1_SUB_MBOX) << 1));
1139 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1140 tmpStatus =
1141 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1142 OsalIsr_delete (&(isrHandleElem->isrHandle));
1143 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1144 if ((status >= 0) && (tmpStatus < 0)) {
1145 status = tmpStatus;
1146 GT_setFailureReason (curTrace,
1147 GT_4CLASS,
1148 "VAYUIpcInt_interruptUnregister",
1149 status,
1150 "OsalIsr_delete failed");
1151 }
1152 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1153 Memory_free(NULL, isrHandleElem, sizeof(VAYUIpcInt_isrHandleElem));
1154 }
1155 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1156 }
1157 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1159 GT_1trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptUnregister",
1160 status);
1162 /*! @retval VAYUIPCINT_SUCCESS Interrupt successfully unregistered */
1163 return status;
1164 }
1167 /*!
1168 * @brief Function to enable the specified interrupt
1169 *
1170 * @param procId Remote processor ID
1171 * @param intId interrupt id
1172 *
1173 * @sa VAYUIpcInt_interruptDisable
1174 */
1175 Void
1176 VAYUIpcInt_interruptEnable (UInt16 procId, UInt32 intId)
1177 {
1178 GT_2trace (curTrace, GT_ENTER, "VAYUIpcInt_interruptEnable",
1179 procId, intId);
1181 GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1182 GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1184 if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1185 /*
1186 * Mailbox 5 is used for HOST<->DSP1 communication
1187 */
1188 SET_BIT(REG(VAYUIpcInt_state.mailbox5Base + \
1189 VAYU_MAILBOX_IRQENABLE(VAYU_HOST_USER_ID)),
1190 ( (DSP1_HOST_SUB_MBOX) << 1));
1191 }
1192 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1193 /*
1194 * Mailbox 6 is used for HOST<->IPU2 communication
1195 */
1196 SET_BIT(REG(VAYUIpcInt_state.mailbox6Base + \
1197 VAYU_MAILBOX_IRQENABLE(VAYU_HOST_USER_ID)),
1198 ( (IPU2_HOST_SUB_MBOX) << 1));
1199 }
1200 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1201 else {
1202 GT_setFailureReason (curTrace,
1203 GT_4CLASS,
1204 "VAYUIpcInt_interruptEnable",
1205 VAYUIPCINT_E_FAIL,
1206 "Invalid procId specified");
1207 }
1208 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1210 GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptEnable");
1211 }
1214 /*!
1215 * @brief Function to disable the specified interrupt
1216 *
1217 * @param procId Remote processor ID
1218 * @param intId interrupt id
1219 *
1220 * @sa VAYUIpcInt_interruptEnable
1221 */
1222 Void
1223 VAYUIpcInt_interruptDisable (UInt16 procId, UInt32 intId)
1224 {
1225 GT_2trace (curTrace, GT_ENTER, "VAYUIpcInt_interruptDisable",
1226 procId, intId);
1228 GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1229 GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1231 if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1232 /*
1233 * Mailbox 5 is used for HOST<->DSP1 communication
1234 */
1235 SET_BIT(REG(VAYUIpcInt_state.mailbox5Base + \
1236 MAILBOX_IRQENABLE_CLR_OFFSET + (0x10 * VAYU_HOST_USER_ID)),
1237 ( (DSP1_HOST_SUB_MBOX) << 1));
1238 }
1239 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1240 /*
1241 * Mailbox 6 is used for HOST<->IPU2 communication
1242 */
1243 SET_BIT(REG(VAYUIpcInt_state.mailbox6Base + \
1244 MAILBOX_IRQENABLE_CLR_OFFSET + (0x10 * VAYU_HOST_USER_ID)),
1245 ( (IPU2_HOST_SUB_MBOX) << 1));
1246 }
1247 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1248 else {
1249 GT_setFailureReason (curTrace,
1250 GT_4CLASS,
1251 "VAYUIpcInt_interruptDisable",
1252 VAYUIPCINT_E_FAIL,
1253 "Invalid procId specified");
1254 }
1255 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1257 GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_interruptDisable");
1258 }
1261 /*!
1262 * @brief Function to wait for interrupt to be cleared.
1263 *
1264 * @param procId Remote processor ID
1265 * @param intId interrupt id
1266 *
1267 * @sa VAYUIpcInt_sendInterrupt
1268 */
1269 Int32
1270 VAYUIpcInt_waitClearInterrupt (UInt16 procId, UInt32 intId)
1271 {
1272 Int32 status = VAYUIPCINT_SUCCESS;
1274 GT_2trace (curTrace,GT_ENTER,"VAYUIpcInt_waitClearInterrupt",
1275 procId, intId);
1277 GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1278 GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1280 if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1281 /* Wait for DSP to clear the previous interrupt */
1282 while( ( REG32(( VAYUIpcInt_state.mailbox5Base
1283 + MAILBOX_MSGSTATUS_m_OFFSET(HOST_DSP1_SUB_MBOX)))
1284 & 0x3F ));
1285 }
1286 else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1287 /* Wait for VIDEOM4 to clear the previous interrupt */
1288 while( ( REG32((VAYUIpcInt_state.mailbox6Base
1289 + MAILBOX_MSGSTATUS_m_OFFSET(HOST_IPU2_SUB_MBOX)))
1290 & 0x3F ));
1291 }
1292 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1293 else {
1294 /*! @retval VAYUIPCINT_E_FAIL Invalid procId specified */
1295 status = VAYUIPCINT_E_FAIL;
1296 GT_setFailureReason (curTrace,
1297 GT_4CLASS,
1298 "VAYUIpcInt_waitClearInterrupt",
1299 status,
1300 "Invalid procId specified");
1301 }
1302 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1304 GT_1trace (curTrace,GT_LEAVE,"VAYUIpcInt_waitClearInterrupt", status);
1306 /*! @retval VAYUIPCINT_SUCCESS Wait for interrupt clearing successfully
1307 completed. */
1308 return status ;
1309 }
1312 /*!
1313 * @brief Function to send a specified interrupt to the DSP.
1314 *
1315 * @param procId Remote processor ID
1316 * @param intId interrupt id
1317 * @param value Value to be sent with the interrupt
1318 *
1319 * @sa VAYUIpcInt_waitClearInterrupt
1320 */
1321 Int32
1322 VAYUIpcInt_sendInterrupt (UInt16 procId, UInt32 intId, UInt32 value)
1323 {
1324 Int32 status = VAYUIPCINT_SUCCESS;
1326 GT_3trace (curTrace, GT_ENTER, "VAYUIpcInt_sendInterrupt",
1327 procId, intId, value);
1329 GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1330 GT_assert (curTrace, (procId < MultiProc_MAXPROCESSORS));
1332 if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1]) {
1333 /*
1334 * Mailbox 5 is used for HOST<->DSP1 communication
1335 */
1336 if (REG32(VAYUIpcInt_state.mailbox5Base + \
1337 MAILBOX_MSGSTATUS_m_OFFSET(HOST_DSP1_SUB_MBOX)) == 0)
1338 REG32(VAYUIpcInt_state.mailbox5Base + \
1339 MAILBOX_MESSAGE_m_OFFSET(HOST_DSP1_SUB_MBOX)) = value;
1340 else
1341 GT_0trace (curTrace, GT_4CLASS, "Dropping HOST->DSP1 Mbox Msg");
1342 } else if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2]) {
1343 /*
1344 * Mailbox 6 is used for HOST<->DSP1 communication
1345 */
1346 REG32(VAYUIpcInt_state.mailbox6Base + \
1347 MAILBOX_MESSAGE_m_OFFSET(HOST_IPU2_SUB_MBOX)) = value;
1348 }
1349 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1350 else {
1351 /*! @retval VAYUIPCINT_E_FAIL Invalid procId specified */
1352 status = VAYUIPCINT_E_FAIL;
1353 GT_setFailureReason (curTrace,
1354 GT_4CLASS,
1355 "VAYUIpcInt_sendInterrupt",
1356 status,
1357 "Invalid procId specified");
1358 }
1359 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1361 GT_1trace (curTrace, GT_LEAVE, "VAYUIpcInt_sendInterrupt",status);
1363 /*! @retval VAYUIPCINT_SUCCESS Interrupt successfully sent */
1364 return status;
1365 }
1368 /*!
1369 * @brief Function to clear the specified interrupt received from the
1370 * remote core.
1371 *
1372 * @param procId Remote processor ID
1373 * @param intId interrupt id
1374 *
1375 * @sa VAYUIpcInt_sendInterrupt
1376 */
1377 UInt32
1378 VAYUIpcInt_clearInterrupt (UInt16 procId, UInt16 mboxNum)
1379 {
1380 UInt32 retVal = 0;
1381 UInt32 mailboxBase = 0;
1383 GT_1trace (curTrace,GT_ENTER,"VAYUIpcInt_clearInterrupt", mboxNum);
1385 GT_assert (curTrace,(ArchIpcInt_object.isSetup == TRUE));
1387 if (procId == VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2])
1388 mailboxBase = VAYUIpcInt_state.mailbox6Base;
1389 else
1390 mailboxBase = VAYUIpcInt_state.mailbox5Base;
1392 if (mboxNum < MAILBOX_MAXNUM) {
1393 /* Read the register to get the entry from the mailbox FIFO */
1394 retVal = REG32(mailboxBase + MAILBOX_MESSAGE_m_OFFSET(mboxNum));
1396 /* Clear the IRQ status.
1397 * If there are more in the mailbox FIFO, it will re-assert.
1398 */
1399 SET_BIT(REG(mailboxBase + MAILBOX_IRQSTATUS_CLEAR_OFFSET + \
1400 (0x10 * VAYU_HOST_USER_ID)),
1401 (mboxNum<<1));
1402 }
1403 #if !defined(SYSLINK_BUILD_OPTIMIZE)
1404 else {
1405 GT_setFailureReason (curTrace,
1406 GT_4CLASS,
1407 "VAYUIpcInt_clearInterrupt",
1408 VAYUIPCINT_E_FAIL,
1409 "Invalid mailbox number specified");
1410 }
1411 #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
1413 GT_0trace (curTrace, GT_LEAVE, "VAYUIpcInt_clearInterrupt");
1415 /*! @retval Value Value received with the interrupt. */
1416 return retVal;
1417 }
1420 /*
1421 * Instead of constantly allocating and freeing the msg structures
1422 * we just cache a few of them, and recycle them instead.
1423 */
1424 #define CACHE_NUM 20
1425 static VAYUIpcInt_MsgListElem *msg_cache;
1426 static int num_msg = 0;
1428 static VAYUIpcInt_MsgListElem *get_msg()
1429 {
1430 VAYUIpcInt_MsgListElem *msg;
1431 IArg key = NULL;
1433 key = Gate_enterSystem();
1434 msg = msg_cache;
1435 if (msg != NULL) {
1436 msg_cache = (VAYUIpcInt_MsgListElem *)msg_cache->next;
1437 num_msg--;
1438 Gate_leaveSystem(key);
1439 } else {
1440 Gate_leaveSystem(key);
1441 msg = Memory_alloc(NULL, sizeof(VAYUIpcInt_MsgListElem), 0, NULL);
1442 }
1443 return(msg);
1444 }
1446 static void put_msg(VAYUIpcInt_MsgListElem * msg)
1447 {
1448 IArg key = NULL;
1449 key = Gate_enterSystem();
1450 if (num_msg >= CACHE_NUM) {
1451 Gate_leaveSystem(key);
1452 Memory_free(NULL, msg, sizeof(*msg));
1453 } else {
1454 msg->next = (struct VAYUIpcInt_MsgListElem *)msg_cache;
1455 msg_cache = msg;
1456 num_msg++;
1457 Gate_leaveSystem(key);
1458 }
1459 return;
1460 }
1463 /*!
1464 * @brief Function to check and clear the remote proc interrupt
1465 *
1466 * @param arg Optional argument to the function.
1467 *
1468 * @sa _VAYUIpcInt_isr
1469 */
1470 static
1471 Bool
1472 _VAYUIpcInt_checkAndClearFunc (Ptr arg)
1473 {
1474 UInt16 procId;
1475 UInt32 msg;
1476 VAYUIpcInt_MsgListElem * elem = NULL;
1478 GT_1trace (curTrace, GT_ENTER, "_VAYUIpcInt_checkAndClearFunc", arg);
1480 if( REG32( VAYUIpcInt_state.mailbox6Base
1481 + MAILBOX_MSGSTATUS_m_OFFSET(IPU2_HOST_SUB_MBOX)) != 0 ){
1482 procId = VAYUIpcInt_state.procIds [VAYU_INDEX_IPU2];
1483 msg = VAYUIpcInt_clearInterrupt (procId, IPU2_HOST_SUB_MBOX);
1485 GT_1trace (curTrace, GT_1CLASS, "Got msg [0x%08x] from IPU2", msg);
1487 /* This is a message from IPU2, put the message in IPU2's list */
1488 elem = get_msg();
1489 if (elem) {
1490 elem->msg = msg;
1491 List_put(VAYUIpcInt_state.isrLists[procId], (List_Elem *)elem);
1492 }
1493 }
1494 if( REG32( VAYUIpcInt_state.mailbox5Base
1495 + MAILBOX_MSGSTATUS_m_OFFSET(DSP1_HOST_SUB_MBOX)) != 0 ){
1496 procId = VAYUIpcInt_state.procIds [VAYU_INDEX_DSP1];
1497 msg = VAYUIpcInt_clearInterrupt (procId, DSP1_HOST_SUB_MBOX);
1499 GT_1trace (curTrace, GT_1CLASS, "Got msg [0x%08x] from DSP1", msg);
1501 /* This is a message from DSP, put the message in DSP's list */
1502 elem = get_msg();
1503 if (elem) {
1504 elem->msg = msg;
1505 List_put(VAYUIpcInt_state.isrLists[procId], (List_Elem *)elem);
1506 }
1507 }
1509 GT_1trace (curTrace, GT_LEAVE, "_VAYUIpcInt_checkAndClearFunc", TRUE);
1511 /* This is not a shared interrupt, so interrupt has always occurred */
1512 /*! @retval TRUE Interrupt has occurred. */
1513 return (TRUE);
1514 }
1517 /*!
1518 * @brief Interrupt Service Routine for VAYUIpcInt module
1519 *
1520 * @param arg Optional argument to the function.
1521 *
1522 * @sa _VAYUIpcInt_checkAndClearFunc
1523 */
1524 static
1525 Bool
1526 _VAYUIpcInt_isr (Ptr ref)
1527 {
1528 UInt16 i = 0;
1529 VAYUIpcInt_MsgListElem * elem = NULL;
1530 GT_1trace (curTrace, GT_ENTER, "_VAYUIpcInt_isr", ref);
1532 for (i = 0 ; i < VAYUIpcInt_state.maxProcessors ; i++) {
1533 if ((elem = List_get(VAYUIpcInt_state.isrLists [i])) != NULL) {
1534 /*Calling the particular ISR */
1535 GT_assert(curTrace,(VAYUIpcInt_state.isrObjects [i].fxn != NULL));
1536 if (VAYUIpcInt_state.isrObjects [i].fxn != NULL) {
1537 VAYUIpcInt_state.isrObjects [i].fxn (elem->msg,
1538 VAYUIpcInt_state.isrObjects [i].fxnArgs);
1539 }
1540 put_msg(elem);
1541 }
1542 }
1544 GT_1trace (curTrace, GT_LEAVE, "_VAYUIpcInt_isr", TRUE);
1546 /*! @retval TRUE Interrupt has been handled. */
1547 return (TRUE);
1548 }
1550 #if defined (__cplusplus)
1551 }
1552 #endif