xref: /utopia/UTPA2-700.0.x/modules/irq/hal/M7821/irq/halIRQ.c (revision 53ee8cc121a030b8d368113ac3e966b4705770ef)
1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 //    Software and any modification/derivatives thereof.
18 //    No right, ownership, or interest to MStar Software and any
19 //    modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 //    supplied together with third party`s software and the use of MStar
23 //    Software may require additional licenses from third parties.
24 //    Therefore, you hereby agree it is your sole responsibility to separately
25 //    obtain any and all third party right and license necessary for your use of
26 //    such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 //    MStar`s confidential information and you agree to keep MStar`s
30 //    confidential information in strictest confidence and not disclose to any
31 //    third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 //    kind. Any warranties are hereby expressly disclaimed by MStar, including
35 //    without limitation, any warranties of merchantability, non-infringement of
36 //    intellectual property rights, fitness for a particular purpose, error free
37 //    and in conformity with any international standard.  You agree to waive any
38 //    claim against MStar for any loss, damage, cost or expense that you may
39 //    incur related to your use of MStar Software.
40 //    In no event shall MStar be liable for any direct, indirect, incidental or
41 //    consequential damages, including without limitation, lost of profit or
42 //    revenues, lost or damage of data, and unauthorized system use.
43 //    You agree that this Section 4 shall still apply without being affected
44 //    even if MStar Software has been modified by MStar in accordance with your
45 //    request or instruction for your use, except otherwise agreed by both
46 //    parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 //    services in relation with MStar Software to you for your use of
50 //    MStar Software in conjunction with your or your customer`s product
51 //    ("Services").
52 //    You understand and agree that, except otherwise agreed by both parties in
53 //    writing, Services are provided on an "AS IS" basis and the warranty
54 //    disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 //    or otherwise:
58 //    (a) conferring any license or right to use MStar name, trademark, service
59 //        mark, symbol or any other identification;
60 //    (b) obligating MStar or any of its affiliates to furnish any person,
61 //        including without limitation, you and your customers, any assistance
62 //        of any kind whatsoever, or any information; or
63 //    (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 //    of Taiwan, R.O.C., excluding its conflict of law rules.
67 //    Any and all dispute arising out hereof or related hereto shall be finally
68 //    settled by arbitration referred to the Chinese Arbitration Association,
69 //    Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 //    Rules of the Association by three (3) arbitrators appointed in accordance
71 //    with the said Rules.
72 //    The place of arbitration shall be in Taipei, Taiwan and the language shall
73 //    be English.
74 //    The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 ////////////////////////////////////////////////////////////////////////////////
79 //
80 // Copyright (c) 2008-2009 MStar Semiconductor, Inc.
81 // All rights reserved.
82 //
83 // Unless otherwise stipulated in writing, any and all information contained
84 // herein regardless in any format shall remain the sole proprietary of
85 // MStar Semiconductor Inc. and be kept in strict confidence
86 // ("MStar Confidential Information") by the recipient.
87 // Any unauthorized act including without limitation unauthorized disclosure,
88 // copying, use, reproduction, sale, distribution, modification, disassembling,
89 // reverse engineering and compiling of the contents of MStar Confidential
90 // Information is unlawful and strictly prohibited. MStar hereby reserves the
91 // rights to any and all damages, losses, costs and expenses resulting therefrom.
92 //
93 ////////////////////////////////////////////////////////////////////////////////
94 
95 #if defined(MSOS_TYPE_NOS) || defined(MSOS_TYPE_NUTTX)
96 
97 //-------------------------------------------------------------------------------------------------
98 //  Include Files
99 //-------------------------------------------------------------------------------------------------
100 #include "MsCommon.h"
101 #include "MsOS.h"
102 #include "halIRQTBL.h"
103 #include "regCHIP.h"
104 #include "drvIRQ.h"
105 #include "halIRQ.h"
106 #include "regIRQ.h"
107 #include "ULog.h"
108 
109 #if defined(MSOS_TYPE_NUTTX)
110 #include "debug.h"
111 #endif
112 
113 #define MST_MACRO_START     do {
114 #define MST_MACRO_END       } while (0)
115 
116 #define TAG_IRQ "IRQ"
117 #define IRQ_HAL_ERR(x, args...)        {ULOGE(TAG_IRQ, x, ##args);}
118 
119 #if defined (__mips__)
120 #define mtspr(spr, value)  ULOGI(TAG_IRQ, "[NIY] mtspr in line:%s %d\n",__FILE__, __LINE__);
121 #define mfspr(spr)		   ULOGI(TAG_IRQ, "[NIY] mfspr in line:%s %d\n",__FILE__, __LINE__);
122 
__mhal_lsbit_index(MS_U32 _value_)123 inline MS_U32 __mhal_lsbit_index(MS_U32 _value_)
124 {
125     MS_U32  index = 1;
126 
127     while((_value_&0x01) == 0x00)
128     {
129         _value_ = (_value_ >> 1);
130         index++;
131         if(index == 32)
132         {
133             index = 0;
134             break;
135         }
136     }
137 
138     return index;
139     //printf(const char * fmt, ...)("[NIY] __mhal_lsbit_index in line: %s %d\n",__FILE__, __LINE__);
140 }
141 
142 
143 #define __mhal_interrupt_disable(_old_) (_old_=_old_)
144 
145 #define __mhal_interrupt_restore(_old_) (_old_=_old_)
146 
147 #elif defined (__arm__)
148 #define mtspr(spr, value)  ULOGI(TAG_IRQ, "[NIY] mtspr in line:%s %d\n",__FILE__, __LINE__);
149 #define mfspr(spr)		   ULOGI(TAG_IRQ, "[NIY] mfspr in line:%s %d\n",__FILE__, __LINE__);
150 
__mhal_lsbit_index(MS_U32 _value_)151 inline MS_U32 __mhal_lsbit_index(MS_U32 _value_)
152 {
153     MS_U32  index = 1;
154 
155     while((_value_&0x01) == 0x00)
156     {
157         _value_ = (_value_ >> 1);
158         index++;
159         if(index == 32)
160         {
161             index = 0;
162             break;
163         }
164     }
165 
166     return index;
167     //printf(const char * fmt, ...)("[NIY] __mhal_lsbit_index in line: %s %d\n",__FILE__, __LINE__);
168 }
169 
170 
171 #define __mhal_interrupt_disable(_old_) (_old_=_old_)
172 
173 #define __mhal_interrupt_restore(_old_) (_old_=_old_)
174 #else
175 #define mtspr(spr, value) \
176     __asm__ __volatile__ ("l.mtspr\t\t%0,%1,0" : : "r" (spr), "r" (value))
177 
178 #define mfspr(spr) \
179     ({ \
180         unsigned long value; \
181         __asm__ __volatile__ ("l.mfspr\t\t%0,%1,0" : "=r" (value) : "r" (spr) : "memory"); \
182         value; \
183     })
184 
185 #define __mhal_lsbit_index(_value_)                                         \
186     ({                                                                      \
187     unsigned long _index_;                                                  \
188     __asm__ __volatile__ ("l.ff1\t\t%0,%1" : "=r" (_index_) : "r" (_value_));\
189     _index_;                                                                \
190     })
191 
192 
193 #define GRP_BITS                (11)
194 #define SPR_SR                  ((0 << GRP_BITS) + 17)
195 #define SPR_SR_TEE              0x00000002  // Tick timer Exception Enable
196 #define SPR_SR_IEE              0x00000004  // Interrupt Exception Enable
197 
198 #define __mhal_interrupt_disable(_old_)                                     \
199     MST_MACRO_START                                                         \
200     _old_ = mfspr(SPR_SR);                                                  \
201     mtspr(SPR_SR, (_old_) & ~(SPR_SR_IEE | SPR_SR_TEE));                    \
202     MST_MACRO_END
203 
204 #define __mhal_interrupt_restore(_old_)                                     \
205     mtspr(SPR_SR, (~(SPR_SR_IEE|SPR_SR_TEE) & mfspr(SPR_SR) ) |             \
206                   ( (SPR_SR_IEE|SPR_SR_TEE) & (_old_) ))
207 #endif
208 
209 
210 //-------------------------------------------------------------------------------------------------
211 //  Driver Compiler Options
212 //-------------------------------------------------------------------------------------------------
213 
214 
215 //-------------------------------------------------------------------------------------------------
216 //  Local Defines
217 //-------------------------------------------------------------------------------------------------
218 #define COUNTOF( array )    (sizeof(array) / sizeof((array)[0]))
219 //#define E_INTERRUPT_FIQ     E_INTERRUPT_02
220 //#define E_INTERRUPT_IRQ     E_INTERRUPT_03
221 
222 //-------------------------------------------------------------------------------------------------
223 //  Local Structures
224 //-------------------------------------------------------------------------------------------------
225 typedef void (*IRQCb)(MS_U32 u32Vector);
226 
227 //-------------------------------------------------------------------------------------------------
228 //  Global Variables
229 //-------------------------------------------------------------------------------------------------
230 
231 
232 //-------------------------------------------------------------------------------------------------
233 //  Local Variables
234 //-------------------------------------------------------------------------------------------------
235 static IRQCb irq_table[E_IRQ_FIQ_ALL] = {0};
236 // static MS_U32 _u32FIQ, _u32IRQ, _u32FIQExp, _u32IRQExp, _u32MIO_MapBase = 0;
237 static MS_U32 _u32FIQ_Msk, _u32IRQ_Msk, _u32FIQExp_Msk, _u32IRQExp_Msk;
238 
239 #if defined(MCU_AEON)
240 static MS_U32  _u32MIO_MapBase= 0xFA200000;
241 #elif defined(MCU_ARM_CA12)
242     #ifdef CONFIG_MBOOT
243         static MS_U32 _u32MIO_MapBase= 0x1f200000;
244     #else
245         static MS_U32 _u32MIO_MapBase= 0xfd200000;
246     #endif
247 #elif defined(CONFIG_FPGA)
248 	static MS_U32 _u32MIO_MapBase= 0xfd200000;
249 #else
250 static MS_U32  _u32MIO_MapBase= 0xbf200000;
251 #endif
252 
253 static MS_BOOL _bInIRQ = FALSE, _bInFIQ = FALSE;
254 
255 //-------------------------------------------------------------------------------------------------
256 //  External Functions
257 //-------------------------------------------------------------------------------------------------
258 
259 #define REG16_R(u32RegAddr) ((*((volatile MS_U16*)(_u32MIO_MapBase+ ((u32RegAddr)<< 1)))) & 0xFFFF)
260 #define REG16_W(u32RegAddr, u32Value) (*((volatile MS_U32*)(_u32MIO_MapBase+ ((u32RegAddr)<< 1))))= ((u32Value) & 0xFFFF)
261 
262 /*
263 static MS_U16 REG16_R(MS_U32 u32RegAddr_in)
264 {
265     MS_U32 u32RegAddr1 = (u32RegAddr_in << 1);
266     MS_U32 u32RegAddr = (_u32MIO_MapBase+ (u32RegAddr1));
267     MS_U16 u16RegValue = (*((volatile MS_U16*)(u32RegAddr)) & 0xFFFF);
268 
269     printf("[%s][%d] 0x%08x, 0x%08x\n", __FUNCTION__, __LINE__, u32RegAddr, u16RegValue);
270     return u16RegValue;
271 }
272 
273 static MS_U16 REG16_W(MS_U32 u32RegAddr_in, MS_U32 u32Value)
274 {
275     MS_U32 u32RegAddr1 = (u32RegAddr_in << 1);
276     MS_U32 u32RegAddr = (_u32MIO_MapBase+ (u32RegAddr1));
277     *((volatile MS_U16*)(u32RegAddr)) = ((u32Value) & 0xFFFF);
278 
279     // printf("[%s][%d] 0x%08x, 0x%08x\n", __FUNCTION__, __LINE__, u32RegAddr, u32Value);
280     // REG16_R(u32RegAddr_in);
281 }
282 */
283 
284 //-------------------------------------------------------------------------------------------------
285 //  Local Functions
286 //-------------------------------------------------------------------------------------------------
287 static void _HAL_IRQ_Enable(MS_U32 u32Vector, int enable);
288 
_IRQ_Read2Byte(MS_U32 u32RegAddr)289 static MS_U16 _IRQ_Read2Byte(MS_U32 u32RegAddr)
290 {
291     return REG16_R(u32RegAddr);
292 }
293 
_IRQ_Read4Byte(MS_U32 u32RegAddr)294 static MS_U32 _IRQ_Read4Byte(MS_U32 u32RegAddr)
295 {
296     return (_IRQ_Read2Byte(u32RegAddr) | _IRQ_Read2Byte(u32RegAddr+2) << 16);
297 }
298 
299 #if 0
300 static void _IRQ_WriteByte(MS_U32 u32RegAddr, MS_U8 u8Val)
301 {
302     if (u32RegAddr & 1)
303     {
304         REG16_W(u32RegAddr, (REG16_R(u32RegAddr) & ~(0xFF00))| (u8Val<< 8));
305     }
306     else
307     {
308         REG16_W(u32RegAddr, (REG16_R(u32RegAddr) & ~(0x00FF))| (u8Val));
309     }
310 }
311 #endif
312 
_IRQ_Write2Byte(MS_U32 u32RegAddr,MS_U16 u16Val)313 static void _IRQ_Write2Byte(MS_U32 u32RegAddr, MS_U16 u16Val)
314 {
315     REG16_W(u32RegAddr, u16Val);
316 }
317 
_IRQ_Write4Byte(MS_U32 u32RegAddr,MS_U32 u32Val)318 static void _IRQ_Write4Byte(MS_U32 u32RegAddr, MS_U32 u32Val)
319 {
320     _IRQ_Write2Byte(u32RegAddr, u32Val & 0x0000FFFF);
321     _IRQ_Write2Byte(u32RegAddr+2, u32Val >> 16);
322 }
323 
324 #if defined(MCU_ARM_CA12)
_HAL_IRQ_FIQHnd_ARM(void)325 static void _HAL_IRQ_FIQHnd_ARM(void)
326 {
327     MS_U32 status;
328     MS_U32 index;
329 
330     _bInFIQ = TRUE;
331     status = _IRQ_Read4Byte(REG_FIQ_FINAL_STATUS);
332 
333     index = __mhal_lsbit_index(status);
334     if (index)
335     {
336 
337         _IRQ_Write4Byte(REG_C_FIQ_CLR + 0, status);
338         _IRQ_Write4Byte(REG_C_FIQ_CLR + 0, 0);
339 
340         do
341         {
342             status &= ~(1 << --index);
343             index += (MS_U32)E_FIQL_START;
344             if (irq_table[index])
345             {
346                 _HAL_IRQ_Enable(index, DISABLE);
347                 irq_table[index](HWIdx2IntEnum[index]);
348             }
349             index = __mhal_lsbit_index(status);
350         } while (index);
351     }
352 
353     status = _IRQ_Read4Byte(REG_C_FIQ_EXP_FINAL_STATUS);
354 
355     index = __mhal_lsbit_index(status);
356     if (index)
357     {
358         _IRQ_Write4Byte(REG_C_FIQ_EXP_CLR, status);
359         _IRQ_Write4Byte(REG_C_FIQ_EXP_CLR, 0);
360         do {
361             status &= ~(1 << --index);
362             index += (MS_U32)E_FIQEXPL_START;
363             if (irq_table[index])
364             {
365                 _HAL_IRQ_Enable(index, DISABLE);
366                 irq_table[index](HWIdx2IntEnum[index]);
367             }
368             index = __mhal_lsbit_index(status);
369         } while (index);
370     }
371     _bInFIQ = FALSE;
372 }
373 
_HAL_IRQ_IRQHnd_ARM(void)374 static void _HAL_IRQ_IRQHnd_ARM(void)
375 {
376     MS_U32 status;
377     MS_U32 index;
378 
379     _bInIRQ = TRUE;
380     status = _IRQ_Read4Byte(REG_IRQ_FINAL_STATUS);
381     index = __mhal_lsbit_index(status);
382     if (index)
383     {
384         do {
385             status &= ~(1 << --index);
386             index += (MS_U32)E_IRQL_START;
387             if (irq_table[index])
388             {
389                 _HAL_IRQ_Enable(index, DISABLE);
390                 //fix Uart Rx interrupt can't work
391                 irq_table[index](HWIdx2IntEnum[index]);
392             }
393             index = __mhal_lsbit_index(status);
394         } while (index);
395     }
396 
397     status = _IRQ_Read4Byte(REG_C_IRQ_EXP_FINAL_STATUS);
398     index = __mhal_lsbit_index(status);
399     if (index)
400     {
401         do {
402             status &= ~(1 << --index);
403             index += (MS_U32)E_IRQEXPL_START;
404             if (irq_table[index])
405             {
406                 _HAL_IRQ_Enable(index, DISABLE);
407                 irq_table[index](HWIdx2IntEnum[index]);
408             }
409             index = __mhal_lsbit_index(status);
410         } while (index);
411     }
412     _bInIRQ = FALSE;
413 }
414 
415 #else
_HAL_IRQ_FIQHnd(MHAL_SavedRegisters * pHalReg,MS_U32 u32Vector)416 static void _HAL_IRQ_FIQHnd(MHAL_SavedRegisters *pHalReg, MS_U32 u32Vector)
417 {
418     MS_U32 status;
419     MS_U32 index;
420 
421     _bInFIQ = TRUE;
422 
423 #if defined(CONFIG_FRC)//frcr2_integration###
424     status = _IRQ_Read4Byte(REG_FIQ_FINAL_STATUS);
425     index = __mhal_lsbit_index(status);
426     if (index)
427     {
428 
429         _IRQ_Write4Byte(REG_C_FIQ_CLR + 0, status);
430         _IRQ_Write4Byte(REG_C_FIQ_CLR + 0, 0);
431 
432         do
433         {
434             status &= ~(1 << --index);
435             index += (MS_U32)E_FIQL_START;
436             if (irq_table[index])
437             {
438                 _HAL_IRQ_Enable(index, DISABLE);
439                 irq_table[index](HWIdx2IntEnum[index]);
440             }
441             index = __mhal_lsbit_index(status);
442         } while (index);
443     }
444 #else
445     status = _IRQ_Read4Byte(REG_FIQ_FINAL_STATUS);
446     index = __mhal_lsbit_index(status);
447     if (index)
448     {
449 
450         _IRQ_Write4Byte(REG_C_FIQ_CLR + 0, status);
451         _IRQ_Write4Byte(REG_C_FIQ_CLR + 0, 0);
452 
453         do
454         {
455             status &= ~(1 << --index);
456             index += (MS_U32)E_FIQL_START;
457             if (irq_table[index])
458             {
459                 _HAL_IRQ_Enable(index, DISABLE);
460                 irq_table[index](HWIdx2IntEnum[index]);
461             }
462             index = __mhal_lsbit_index(status);
463         } while (index);
464     }
465 
466     status = _IRQ_Read4Byte(REG_C_FIQ_EXP_FINAL_STATUS);
467 
468     index = __mhal_lsbit_index(status);
469     if (index)
470     {
471         _IRQ_Write4Byte(REG_C_FIQ_EXP_CLR, status);
472         _IRQ_Write4Byte(REG_C_FIQ_EXP_CLR, 0);
473         do {
474             status &= ~(1 << --index);
475             index += (MS_U32)E_FIQEXPL_START;
476             if (irq_table[index])
477             {
478                 _HAL_IRQ_Enable(index, DISABLE);
479                 irq_table[index](HWIdx2IntEnum[index]);
480             }
481             index = __mhal_lsbit_index(status);
482         } while (index);
483     }
484 
485     status = _IRQ_Read4Byte(REG_C_FIQ_HYP_FINAL_STATUS);
486 
487     index = __mhal_lsbit_index(status);
488     if (index)
489     {
490         _IRQ_Write4Byte(REG_C_FIQ_HYP_CLR, status);
491         _IRQ_Write4Byte(REG_C_FIQ_HYP_CLR, 0);
492         do {
493             status &= ~(1 << --index);
494             index += (MS_U32)E_FIQHYPL_START;
495             if (irq_table[index])
496             {
497                 _HAL_IRQ_Enable(index, DISABLE);
498                 irq_table[index](HWIdx2IntEnum[index]);
499             }
500             index = __mhal_lsbit_index(status);
501         } while (index);
502     }
503 #endif
504 
505     _bInFIQ = FALSE;
506 }
507 
_HAL_IRQ_IRQHnd(MHAL_SavedRegisters * pHalReg,MS_U32 u32Vector)508 static void _HAL_IRQ_IRQHnd(MHAL_SavedRegisters *pHalReg, MS_U32 u32Vector)
509 {
510     MS_U32 status;
511     MS_U32 index;
512 
513     _bInIRQ = TRUE;
514 
515 #if defined(CONFIG_FRC)//frcr2_integration###
516     status = _IRQ_Read4Byte(REG_IRQ_FINAL_STATUS);
517     index = __mhal_lsbit_index(status);
518     if (index)
519     {
520         do {
521             status &= ~(1 << --index);
522             index += (MS_U32)E_IRQL_START;
523             if (irq_table[index])
524             {
525                 _HAL_IRQ_Enable(index, DISABLE);
526                 irq_table[index](HWIdx2IntEnum[index]);
527             }
528             index = __mhal_lsbit_index(status);
529         } while (index);
530     }
531 #else
532     status = _IRQ_Read4Byte(REG_IRQ_FINAL_STATUS);
533     index = __mhal_lsbit_index(status);
534     if (index)
535     {
536         do {
537             status &= ~(1 << --index);
538             index += (MS_U32)E_IRQL_START;
539             if (irq_table[index])
540             {
541                 _HAL_IRQ_Enable(index, DISABLE);
542                 // This is for UART debug to get CPU registers temp solution.
543                 // Todo: Should modify the interface to let CPU registers
544                 //       pointer pass to Callback funtion
545                 if (HWIdx2IntEnum[index] == E_INT_IRQ_UART0)
546                 {
547                     irq_table[index]((MS_U32)pHalReg);
548                 }
549                 else
550                 {
551                     irq_table[index](HWIdx2IntEnum[index]);
552                 }
553             }
554             index = __mhal_lsbit_index(status);
555         } while (index);
556     }
557 
558     status = _IRQ_Read4Byte(REG_C_IRQ_EXP_FINAL_STATUS);
559     index = __mhal_lsbit_index(status);
560     if (index)
561     {
562         do {
563             status &= ~(1 << --index);
564             index += (MS_U32)E_IRQEXPL_START;
565             if (irq_table[index])
566             {
567                 _HAL_IRQ_Enable(index, DISABLE);
568                 if (HWIdx2IntEnum[index] == E_INT_IRQ_FRC_INT_FIQ2HST0)//frcr2_integration###
569                 {
570                     MS_U32 reg = E_IRQ_FIQ_INVALID;
571                     MS_U32 status_frc;
572 
573                     irq_table[index](HWIdx2IntEnum[index]);
574                     //clear frc fiq status
575                     reg = REG_FRC_C_FIQ_CLR;
576                     if((reg-RIUBASE_IRQ_FRC) >= (0x20*2))//clear Host0 status for FRC
577                     {
578                         reg -= (0x20*2);
579                         status_frc = _IRQ_Read4Byte(reg);
580                         _IRQ_Write4Byte(reg, status_frc);
581                         _IRQ_Write4Byte(reg, 0);
582                     }
583                 }
584                 else
585                 {
586                     irq_table[index](HWIdx2IntEnum[index]);
587                 }
588             }
589             index = __mhal_lsbit_index(status);
590         } while (index);
591     }
592 
593     status = _IRQ_Read4Byte(REG_C_IRQ_HYP_FINAL_STATUS);
594     index = __mhal_lsbit_index(status);
595     if (index)
596     {
597         do {
598             status &= ~(1 << --index);
599             index += (MS_U32)E_IRQHYPL_START;
600             if (irq_table[index])
601             {
602                 _HAL_IRQ_Enable(index, DISABLE);
603                 irq_table[index](HWIdx2IntEnum[index]);
604             }
605             index = __mhal_lsbit_index(status);
606         } while (index);
607     }
608 #endif
609 
610     _bInIRQ = FALSE;
611 }
612 #endif
613 
_HAL_IRQ_Enable(MS_U32 u32Vector,int enable)614 static void _HAL_IRQ_Enable(MS_U32 u32Vector, int enable)
615 {
616     MS_U32 reg = E_IRQ_FIQ_INVALID;
617     MS_U32 mask;
618     MS_U32 old = 0;
619 
620     if ((MS_U32)u32Vector <= COUNTOF(irq_table))
621     {
622         if ( (u32Vector >= E_IRQL_START) && (u32Vector <= E_IRQH_END) )
623         {
624             u32Vector -= E_IRQL_START;
625             reg = REG_C_IRQ_MASK;
626         }
627         else if ( (u32Vector >= E_FIQL_START) && (u32Vector <= E_FIQH_END) )
628         {
629             u32Vector -= E_FIQL_START;
630             reg = REG_C_FIQ_MASK;
631             #if defined(CONFIG_FRC)//frcr2_integration###
632             if(u32Vector==E_IRQ_03)
633             {
634                 if((reg-RIUBASE_IRQ_FRC) >= (0x20*2))
635                     reg -= (0x20*2);
636             }
637             #endif
638         }
639         else if ( (u32Vector >= E_IRQEXPL_START) && (u32Vector <= E_IRQEXPH_END) )
640         {
641             u32Vector -= E_IRQEXPL_START;
642             reg = REG_C_IRQ_EXP_MASK;
643         }
644         else if ( (u32Vector >= E_FIQEXPL_START) && (u32Vector <= E_FIQEXPH_END) )
645         {
646             u32Vector -= E_FIQEXPL_START;
647             reg = REG_C_FIQ_EXP_MASK;
648         }
649         else if ( (u32Vector >= E_IRQHYPL_START) && (u32Vector <= E_IRQHYPH_END) )
650         {
651             u32Vector -= E_IRQHYPL_START;
652             reg = REG_C_IRQ_HYP_MASK;
653         }
654         else if ( (u32Vector >= E_FIQHYPL_START) && (u32Vector <= E_FIQHYPH_END) )
655         {
656             u32Vector -= E_FIQHYPL_START;
657             reg = REG_C_FIQ_HYP_MASK;
658         }
659 
660         if( E_IRQ_FIQ_INVALID == reg )
661         {
662             //printf("_HAL_IRQ_Enable: unknow vector\n");
663             return;
664         }
665 
666         __mhal_interrupt_disable(old);
667         mask = _IRQ_Read4Byte(reg);
668         u32Vector = (1 << u32Vector);
669 
670         if (enable)
671             mask &= ~u32Vector;
672         else
673             mask |= u32Vector;
674 
675         _IRQ_Write4Byte(reg, mask);
676         __mhal_interrupt_restore(old);
677 
678     }
679 }
680 
681 //-------------------------------------------------------------------------------------------------
682 //  Global Functions
683 //-------------------------------------------------------------------------------------------------
HAL_IRQ_Set_IOMap(MS_U32 u32Base)684 void HAL_IRQ_Set_IOMap(MS_U32 u32Base)
685 {
686      _u32MIO_MapBase = u32Base;
687 }
688 
689 #if defined(MSOS_TYPE_NUTTX)
_HAL_IRQ_FIQHnd_Nuttx(int irq,void * context)690 int _HAL_IRQ_FIQHnd_Nuttx(int irq, void *context)
691 {
692     _HAL_IRQ_FIQHnd((MHAL_SavedRegisters *)context, irq);
693     return 1;
694 }
695 
_HAL_IRQ_IRQHnd_Nuttx(int irq,void * context)696 int _HAL_IRQ_IRQHnd_Nuttx(int irq, void *context)
697 {
698     _HAL_IRQ_IRQHnd((MHAL_SavedRegisters *)context, irq);
699     return 1;
700 }
701 #endif
702 
HAL_IRQ_Init(void)703 void HAL_IRQ_Init(void)
704 {
705     HAL_InitIrqTable();
706     #if defined(MCU_ARM_CA12)
707     MsOS_CPU_AttachInterrupt(E_INTERRUPT_FIQ, _HAL_IRQ_FIQHnd_ARM, E_INTERRUPT_FIQ);
708     MsOS_CPU_AttachInterrupt(E_INTERRUPT_IRQ, _HAL_IRQ_IRQHnd_ARM, E_INTERRUPT_IRQ);
709     #else
710     #if defined(MSOS_TYPE_NUTTX)
711         MsOS_CPU_AttachInterrupt(E_INTERRUPT_FIQ, _HAL_IRQ_FIQHnd_Nuttx, E_INTERRUPT_FIQ);
712         MsOS_CPU_AttachInterrupt(E_INTERRUPT_IRQ, _HAL_IRQ_IRQHnd_Nuttx, E_INTERRUPT_IRQ);
713         MsOS_CPU_UnMaskInterrupt(E_INTERRUPT_FIQ);
714         MsOS_CPU_UnMaskInterrupt(E_INTERRUPT_IRQ);
715     #else
716         MsOS_CPU_AttachInterrupt(E_INTERRUPT_FIQ, (mhal_isr_t) _HAL_IRQ_FIQHnd, E_INTERRUPT_FIQ);
717         MsOS_CPU_AttachInterrupt(E_INTERRUPT_IRQ, (mhal_isr_t) _HAL_IRQ_IRQHnd, E_INTERRUPT_IRQ);
718     #endif
719     #endif
720     HAL_IRQ_DetechAll();
721 }
722 
723 
HAL_IRQ_Attach(MS_U32 u32Vector,void * pIntCb,MS_U32 u32IntType)724 void HAL_IRQ_Attach(MS_U32 u32Vector, void *pIntCb , MS_U32 u32IntType )
725 {
726     MS_U32 u32VectorIndex = 0;
727 
728     u32VectorIndex = (MS_U32)IntEnum2HWIdx[u32Vector];
729 
730     if ((MS_U32)u32VectorIndex <= COUNTOF(irq_table))
731         irq_table[u32VectorIndex] = (IRQCb)pIntCb;
732     else
733         IRQ_HAL_ERR("%s error vector: %x\n", __FUNCTION__, (unsigned int)u32VectorIndex);
734 }
735 
HAL_IRQ_DetechAll()736 void HAL_IRQ_DetechAll()
737 {
738     MS_U16 u16Cnt= 0;
739     for (; u16Cnt <= COUNTOF(irq_table); u16Cnt++)
740         irq_table[u16Cnt] = 0;
741 }
742 
HAL_IRQ_Detech(MS_U32 u32Vector)743 void HAL_IRQ_Detech(MS_U32 u32Vector)
744 {
745     MS_U32 u32VectorIndex = 0;
746 
747     u32VectorIndex = (MS_U32)IntEnum2HWIdx[u32Vector];
748 
749     if ((MS_U32)u32VectorIndex <= COUNTOF(irq_table))
750         irq_table[u32VectorIndex] = 0;
751     else
752         IRQ_HAL_ERR("%s error vector: %x\n", __FUNCTION__, (unsigned int)u32Vector);
753 }
754 
HAL_IRQ_MaskAll(MS_BOOL bMask)755 void HAL_IRQ_MaskAll(MS_BOOL bMask)
756 {
757     if (bMask)
758     {
759         _u32FIQ_Msk = _IRQ_Read4Byte(REG_C_FIQ_MASK);
760         _u32IRQ_Msk = _IRQ_Read4Byte(REG_C_IRQ_MASK);
761         _u32FIQExp_Msk = _IRQ_Read4Byte(REG_C_FIQ_EXP_MASK);
762         _u32IRQExp_Msk = _IRQ_Read4Byte(REG_C_IRQ_EXP_MASK);
763         _IRQ_Write4Byte(REG_C_FIQ_MASK, 0xFFFFFFFF);
764         _IRQ_Write4Byte(REG_C_IRQ_MASK, 0xFFFFFFFF);
765         _IRQ_Write4Byte(REG_C_FIQ_EXP_MASK, 0xFFFFFFFF);
766         _IRQ_Write4Byte(REG_C_IRQ_EXP_MASK, 0xFFFFFFFF);
767     }
768     else
769     {
770         _IRQ_Write4Byte(REG_C_FIQ_MASK, 0);
771         _IRQ_Write4Byte(REG_C_IRQ_MASK, 0);
772         _IRQ_Write4Byte(REG_C_FIQ_EXP_MASK, 0);
773         _IRQ_Write4Byte(REG_C_IRQ_EXP_MASK, 0);
774     }
775 }
776 
HAL_IRQ_Restore()777 void HAL_IRQ_Restore()
778 {
779     _IRQ_Write4Byte(REG_C_FIQ_MASK, _u32FIQ_Msk);
780     _IRQ_Write4Byte(REG_C_IRQ_MASK, _u32IRQ_Msk);
781     _IRQ_Write4Byte(REG_C_FIQ_EXP_MASK, _u32FIQExp_Msk);
782     _IRQ_Write4Byte(REG_C_IRQ_EXP_MASK, _u32IRQExp_Msk);
783 }
784 
HAL_IRQ_Mask(MS_U32 u32Vector)785 void HAL_IRQ_Mask(MS_U32 u32Vector)
786 {
787     MS_U32 u32VectorIndex = 0;
788 
789     u32VectorIndex = (MS_U32)IntEnum2HWIdx[u32Vector];
790     _HAL_IRQ_Enable(u32VectorIndex, DISABLE);
791 }
792 
HAL_IRQ_UnMask(MS_U32 u32Vector)793 void HAL_IRQ_UnMask(MS_U32 u32Vector)
794 {
795     MS_U32 u32VectorIndex = 0;
796 
797     u32VectorIndex = (MS_U32)IntEnum2HWIdx[u32Vector];
798     _HAL_IRQ_Enable(u32VectorIndex, ENABLE);
799 }
800 
HAL_IRQ_NotifyCpu(IRQ_CPU_TYPE type)801 void HAL_IRQ_NotifyCpu(IRQ_CPU_TYPE type)
802 {
803     type = type;
804     IRQ_HAL_ERR("[%s][%d] has not implemented yet\n", __FUNCTION__, __LINE__);
805 #if 0
806     switch (type)
807     {
808         case E_IRQ_CPU0_2_CPU1:
809             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU0, BIT(0));
810             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU0, 0);
811             break;
812         case E_IRQ_CPU0_2_CPU2:
813             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU0, BIT(1));
814             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU0, 0);
815             break;
816         case E_IRQ_CPU1_2_CPU0:
817             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU1, BIT(0));
818             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU1, 0);
819             break;
820         case E_IRQ_CPU1_2_CPU2:
821             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU1, BIT(1));
822             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU1, 0);
823             break;
824         case E_IRQ_CPU2_2_CPU0:
825             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU2, BIT(0));
826             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU2, 0);
827             break;
828         case E_IRQ_CPU2_2_CPU1:
829             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU2, BIT(1));
830             _IRQ_WriteByte(REG_SEND_IRQ_FROM_CPU2, 0);
831             break;
832         default:
833             break;
834     }
835 #endif
836 }
837 
HAL_IRQ_InISR()838 MS_BOOL HAL_IRQ_InISR()
839 {
840     return (_bInIRQ || _bInFIQ);
841 }
842 
843 #endif // #if defined (MSOS_TYPE_NOS)
844 
845 #if defined(MSOS_TYPE_LINUX_KERNEL)
846 #include "linux/interrupt.h"
847 #include "MsCommon.h"
848 #include "halIRQTBL.h"
849 
850 typedef struct
851 {
852     MS_BOOL         bUsed;
853     //MS_BOOL         bRunning;
854     InterruptCb     pInterruptCb;
855 } CHIP_ISR_Info;
856 
857 static CHIP_ISR_Info        _MsOS_ISR_Info[MS_IRQ_MAX];
858 
859 static irqreturn_t _HAL_IRQHandler_Wrapper(int irq, void *desc);
860 
861 //
862 //  Interrupt Service Routine
863 //
864 static                          DEFINE_SPINLOCK(_HAL_IRQ_Mutex);
865 #define IRQ_MUTEX_LOCK()        spin_lock(&_HAL_IRQ_Mutex)
866 #define IRQ_MUTEX_UNLOCK()      spin_unlock(&_HAL_IRQ_Mutex)
867 static MS_BOOL g_bISRInit = FALSE;
868 
869 //Bottom half interrupt handler define
870 #define BH_SOFTIRQ      1
871 #define BH_TASKLET      2
872 #define BH_WORKQUEUE    3
873 #define BH_THREADED     4
874 
875 #define BOTTOM_HALF     BH_THREADED
876 
CHIP_InitISR(void)877 void CHIP_InitISR(void)
878 {
879     IRQ_MUTEX_LOCK();
880     if (g_bISRInit)
881     {
882         IRQ_MUTEX_UNLOCK();
883         return;
884     }
885     g_bISRInit = TRUE;
886     HAL_InitIrqTable();
887     //_HAL_IRQ_Tlb_Init();
888     memset(_MsOS_ISR_Info, 0, MS_IRQ_MAX*sizeof(CHIP_ISR_Info));
889     IRQ_MUTEX_UNLOCK();
890 }
891 
CHIP_EnableIRQ(InterruptNum eIntNum)892 MS_BOOL CHIP_EnableIRQ(InterruptNum eIntNum)
893 {
894     MS_U16 u16VectorIndex = 0;
895     int irq;
896 
897     IRQ_MUTEX_LOCK();
898 
899     u16VectorIndex = (MS_U16)IntEnum2HWIdx[eIntNum];
900     irq = (int)u16VectorIndex + MSTAR_INT_BASE;
901 
902     if (!g_bISRInit || !_MsOS_ISR_Info[u16VectorIndex].bUsed)
903     {
904         IRQ_MUTEX_UNLOCK();
905         return FALSE;   //IRQ number was not register(Attach).
906     }
907     IRQ_MUTEX_UNLOCK();
908 
909     /* do not enable irq if already enableld */
910     if ((irq_to_desc(irq)->irq_data.state_use_accessors & IRQD_IRQ_DISABLED))
911         enable_irq(irq);
912 
913     return TRUE;
914 }
915 
CHIP_DisableIRQ(InterruptNum eIntNum)916 MS_BOOL CHIP_DisableIRQ(InterruptNum eIntNum)
917 {
918     MS_U16 u16VectorIndex = 0;
919     int irq;
920 
921     IRQ_MUTEX_LOCK();
922 
923     u16VectorIndex = (MS_U16)IntEnum2HWIdx[eIntNum];
924     irq = (int)u16VectorIndex + MSTAR_INT_BASE;
925 
926     if (!g_bISRInit || !_MsOS_ISR_Info[u16VectorIndex].bUsed)
927     {
928         IRQ_MUTEX_UNLOCK();
929         return FALSE;   //IRQ number was not register(Attach).
930     }
931     IRQ_MUTEX_UNLOCK();
932 
933     disable_irq_nosync(irq);
934     return TRUE;
935 }
936 
937 typedef struct
938 {
939     int     id;
940     bool        id_auto;
941 }platform_utopia_device;
942 
943 
944 static platform_utopia_device _devUTOPIA =
945 {
946     .id = 6,
947     .id_auto = 0,
948 };
_irq_top(int eIntNum,void * dev_id)949 static irqreturn_t _irq_top(int eIntNum, void* dev_id)
950 {
951     return IRQ_WAKE_THREAD;
952 }
953 
HAL_IRQ_Attach(MS_U32 u32Vector,void * pIntCb,MS_U32 u32IntType)954 void HAL_IRQ_Attach(MS_U32 u32Vector, void *pIntCb, MS_U32 u32IntType )
955 {
956     MS_U16 u16VectorIndex = 0;
957     int irq_flags = SA_INTERRUPT;
958     int err = 0, irq;
959 
960     IRQ_MUTEX_LOCK();
961 
962     u16VectorIndex = (MS_U16)IntEnum2HWIdx[u32Vector];
963     irq = (int)u16VectorIndex + MSTAR_INT_BASE;
964 
965     if (!g_bISRInit || _MsOS_ISR_Info[u16VectorIndex].bUsed)
966     {
967         if (!g_bISRInit)
968             printk("[Utopia2K] IRQ structure did not be initialized\n");
969         else
970             printk("[Utopia2K] IRQ %d has been registered.\n", (unsigned int)u32Vector);
971         IRQ_MUTEX_UNLOCK();
972         return;
973     }
974 
975     _MsOS_ISR_Info[u16VectorIndex].bUsed = TRUE;
976     _MsOS_ISR_Info[u16VectorIndex].pInterruptCb = (InterruptCb)pIntCb;
977 
978     IRQ_MUTEX_UNLOCK();
979 
980 #if   (BOTTOM_HALF == BH_SOFTIRQ)
981 #elif (BOTTOM_HALF == BH_TASKLET)
982 #elif (BOTTOM_HALF == BH_WORKQUEUE)
983 #elif (BOTTOM_HALF == BH_THREADED)
984 
985     if(u32IntType !=  IRQF_SHARED )
986     {
987         irq_flags |= IRQF_ONESHOT;
988 
989         err = request_threaded_irq( irq,
990                                 NULL,
991                                 _HAL_IRQHandler_Wrapper,
992                                 irq_flags,
993                                 HWIdx2IRQname[u16VectorIndex],
994                                 NULL);
995     }else
996     {
997         irq_flags = IRQF_SHARED | IRQF_ONESHOT;
998 
999         err = request_threaded_irq( irq,
1000                                 _irq_top,
1001                                 _HAL_IRQHandler_Wrapper,
1002                                 irq_flags,
1003                                 HWIdx2IRQname[u16VectorIndex],
1004                                 &_devUTOPIA);
1005 
1006     }
1007     if (0 != err)
1008     {
1009         printk("[Utopia2K] request_threaded_irq Fail\n");
1010         return;
1011     }
1012 
1013     if(!(irq_to_desc(irq)->irq_data.state_use_accessors & IRQD_IRQ_DISABLED))
1014         disable_irq_nosync(irq);
1015 #endif
1016 
1017     return;
1018 }
1019 
HAL_IRQ_Detech(MS_U32 u32Vector)1020 void HAL_IRQ_Detech(MS_U32 u32Vector)
1021 {
1022     MS_U16 u16VectorIndex = 0;
1023     int irq;
1024 
1025     IRQ_MUTEX_LOCK();
1026     u16VectorIndex = (MS_U16)IntEnum2HWIdx[u32Vector];
1027     irq = (int)u16VectorIndex + MSTAR_INT_BASE;
1028 
1029     if (!g_bISRInit || !_MsOS_ISR_Info[u16VectorIndex].bUsed)
1030     {
1031         IRQ_MUTEX_UNLOCK();
1032         return;
1033     }
1034     IRQ_MUTEX_UNLOCK();
1035 
1036     free_irq(irq, NULL);
1037 
1038     IRQ_MUTEX_LOCK();
1039     _MsOS_ISR_Info[u16VectorIndex].bUsed = FALSE;
1040     _MsOS_ISR_Info[u16VectorIndex].pInterruptCb = NULL;
1041     IRQ_MUTEX_UNLOCK();
1042 
1043     return;
1044 }
1045 
_HAL_IRQHandler_Wrapper(int irq,void * desc)1046 static irqreturn_t _HAL_IRQHandler_Wrapper(int irq, void *desc)
1047 {
1048     InterruptCb pfnIntCb;
1049 
1050 	disable_irq_nosync(irq);
1051 
1052     IRQ_MUTEX_LOCK();
1053     if (!_MsOS_ISR_Info[(irq-MSTAR_INT_BASE)].bUsed || !_MsOS_ISR_Info[(irq-MSTAR_INT_BASE)].pInterruptCb)
1054     {
1055         IRQ_MUTEX_UNLOCK();
1056         return IRQ_HANDLED;
1057     }
1058     pfnIntCb = _MsOS_ISR_Info[(irq-MSTAR_INT_BASE)].pInterruptCb;
1059     IRQ_MUTEX_UNLOCK();
1060 
1061     pfnIntCb(irq);
1062 
1063     return IRQ_HANDLED;
1064 }
1065 
1066 #endif
1067 
1068