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