xref: /utopia/UTPA2-700.0.x/modules/xc/drv/xc/mdrv_sc_isr.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 ///////////////////////////////////////////////////////////////////////////////////////////////////
96 /// file    Mdrv_sc_isr.c
97 /// @brief  Driver Interface
98 /// @author MStar Semiconductor Inc.
99 ///////////////////////////////////////////////////////////////////////////////////////////////////
100 #define _MDRV_XC_ISR_C_
101 
102 //-------------------------------------------------------------------------------------------------
103 //  Include Files
104 //-------------------------------------------------------------------------------------------------
105 // Common Definition
106 #ifdef MSOS_TYPE_LINUX_KERNEL
107 #include <linux/sched.h>  // for task_normal
108 #endif
109 #include "MsCommon.h"
110 #include "MsOS.h"
111 #include "mhal_xc_chip_config.h"
112 
113 // Internal Definition
114 #include "utopia.h"
115 #include "utopia_dapi.h"
116 #include "drvXC_IOPort.h"
117 #include "xc_hwreg_utility2.h"
118 #include "hwreg_sc.h"
119 #include "apiXC.h"
120 #include "apiXC_Adc.h"
121 #include "apiXC_Auto.h"
122 #include "apiXC_ModeParse.h"
123 #include "drvXC_HDMI_if.h"
124 #include "drv_sc_display.h"
125 #include "drv_sc_isr.h"
126 #include "apiXC_PCMonitor.h"
127 #include "mvideo_context.h"
128 #include "drv_sc_ip.h"
129 #if (LD_ENABLE==1)
130 #include "mdrv_ld.h"
131 #include "mdrv_ldalgo.h"
132 #endif
133 #include "mdrv_sc_3d.h"
134 #include "xc_Analog_Reg.h"
135 #include "mhal_sc.h"
136 #include "drv_sc_menuload.h"
137 #include "drvXC_ADC_Internal.h"
138 #if FRC_INSIDE
139 #include "mdrv_frc.h"
140 #include "mhal_frc.h"
141 #endif
142 #include "XC_private.h"
143 //-------------------------------------------------------------------------------------------------
144 //  Driver Compiler Options
145 //-------------------------------------------------------------------------------------------------
146 
147 
148 //-------------------------------------------------------------------------------------------------
149 //  Local Defines
150 //-------------------------------------------------------------------------------------------------
151 #define SC_ISR_DBG(x)       //x
152 
153 //-------------------------------------------------------------------------------------------------
154 //  Local Structurs
155 //-------------------------------------------------------------------------------------------------
156 
157 
158 //-------------------------------------------------------------------------------------------------
159 //  Global Variables
160 //-------------------------------------------------------------------------------------------------
161 
162 
163 //-------------------------------------------------------------------------------------------------
164 //  Local Variables
165 //-------------------------------------------------------------------------------------------------
166 
167 
168 //-------------------------------------------------------------------------------------------------
169 //  Debug Functions
170 //-------------------------------------------------------------------------------------------------
171 
172 
173 //-------------------------------------------------------------------------------------------------
174 //  Local Functions
175 //-------------------------------------------------------------------------------------------------
176 
177 
178 //-------------------------------------------------------------------------------------------------
179 //  Global Functions
180 //-------------------------------------------------------------------------------------------------
181 
182 
183 /******************************************************************************/
184 /*                           Local Variables                                    */
185 /******************************************************************************/
186 
187 /******************************************************************************/
188 /*               P r i v a t e    F u n c t i o n s                             */
189 /******************************************************************************/
190 //-------------------------------------------------------------------------------------------------
191 /// Convert SC_INT_SRC bit shift case
192 /// @param eIntNum      \b IN: the interrupt number of API layer
193 /// @return @ref SC_INT_SRC the interrupt number of driver layer
194 //-------------------------------------------------------------------------------------------------
_MApi_XC_GetIntSrc(SC_INT_SRC eIntNum)195 static MS_U8 _MApi_XC_GetIntSrc(SC_INT_SRC eIntNum)
196 {
197     MS_U8 u8Int_bit;
198 
199     switch(eIntNum)
200     {
201         // 0x04
202         default    				  :
203         case SC_INT_DIPW          : u8Int_bit = IRQ_INT_DIPW          ;    break;
204 #ifdef IRQ_INT_MEMSYNC_MAIN
205         case SC_INT_MEMSYNC_MAIN  : u8Int_bit = IRQ_INT_MEMSYNC_MAIN  ;    break;
206 #endif
207         case SC_INT_RESERVED1     : u8Int_bit = IRQ_INT_RESERVED1     ;    break;
208 
209         case SC_INT_VSINT         : u8Int_bit = IRQ_INT_VSINT         ;    break;
210         case SC_INT_F2_VTT_CHG    : u8Int_bit = IRQ_INT_F2_VTT_CHG    ;    break;
211         case SC_INT_F1_VTT_CHG    : u8Int_bit = IRQ_INT_F1_VTT_CHG    ;    break;
212         case SC_INT_F2_VS_LOSE    : u8Int_bit = IRQ_INT_F2_VS_LOSE    ;    break;
213         case SC_INT_F1_VS_LOSE    : u8Int_bit = IRQ_INT_F1_VS_LOSE    ;    break;
214         case SC_INT_F2_JITTER     : u8Int_bit = IRQ_INT_F2_JITTER     ;    break;
215         case SC_INT_F1_JITTER     : u8Int_bit = IRQ_INT_F1_JITTER     ;    break;
216         case SC_INT_F2_IPVS_SB    : u8Int_bit = IRQ_INT_F2_IPVS_SB    ;    break;
217         case SC_INT_F1_IPVS_SB    : u8Int_bit = IRQ_INT_F1_IPVS_SB    ;    break;
218         case SC_INT_F2_IPHCS_DET  : u8Int_bit = IRQ_INT_F2_IPHCS_DET  ;    break;
219         case SC_INT_F1_IPHCS_DET  : u8Int_bit = IRQ_INT_F1_IPHCS_DET  ;    break;
220 
221         // 0x10
222         case SC_INT_PWM_RP_L_INT  : u8Int_bit = IRQ_INT_PWM_RP_L_INT  ;    break;
223         case SC_INT_PWM_FP_L_INT  : u8Int_bit = IRQ_INT_PWM_FP_L_INT  ;    break;
224         case SC_INT_F2_HTT_CHG    : u8Int_bit = IRQ_INT_F2_HTT_CHG    ;    break;
225         case SC_INT_F1_HTT_CHG    : u8Int_bit = IRQ_INT_F1_HTT_CHG    ;    break;
226         case SC_INT_F2_HS_LOSE    : u8Int_bit = IRQ_INT_F2_HS_LOSE    ;    break;
227         case SC_INT_F1_HS_LOSE    : u8Int_bit = IRQ_INT_F1_HS_LOSE    ;    break;
228         case SC_INT_PWM_RP_R_INT  : u8Int_bit = IRQ_INT_PWM_RP_R_INT  ;    break;
229         case SC_INT_PWM_FP_R_INT  : u8Int_bit = IRQ_INT_PWM_FP_R_INT  ;    break;
230 
231         case SC_INT_F2_CSOG       : u8Int_bit = IRQ_INT_F2_CSOG       ;    break;
232         case SC_INT_F1_CSOG       : u8Int_bit = IRQ_INT_F1_CSOG       ;    break;
233         case SC_INT_F2_RESERVED2  : u8Int_bit = IRQ_INT_F2_RESERVED2  ;    break;
234         case SC_INT_F1_RESERVED2  : u8Int_bit = IRQ_INT_F1_RESERVED2  ;    break;
235         case SC_INT_F2_ATP_READY  : u8Int_bit = IRQ_INT_F2_ATP_READY  ;    break;
236         case SC_INT_F1_ATP_READY  : u8Int_bit = IRQ_INT_F1_ATP_READY  ;    break;
237         case SC_INT_F2_RESERVED3  : u8Int_bit = IRQ_INT_F2_RESERVED3  ;    break;
238         case SC_INT_F1_RESERVED3  : u8Int_bit = IRQ_INT_F1_RESERVED3  ;    break;
239     }
240 
241     return u8Int_bit;
242 }
243 
_MDrv_SC_get_interrupt(void * pInstance)244 MS_U32 _MDrv_SC_get_interrupt(void *pInstance)
245 {
246     XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
247     UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
248     MS_U32 u32Reg = SC_R4BYTE(psXCInstPri->u32DeviceID, REG_SC_BK00_10_L);
249 #if IRQ_CLEAN_INKERNEL
250     MS_U32 u32DummyReg = SC_R4BYTE(psXCInstPri->u32DeviceID, INTERRUPT_DUMMY_REGISTER);
251 
252     return u32Reg|(u32DummyReg&(SUPPORTED_KERNEL_INT>> (SC_INT_START - IRQ_INT_START)));
253 #endif
254     return u32Reg;
255 }
256 
_MDrv_SC_clear_interrupt(void * pInstance,SC_INT_SRC u8IntSrc)257 static void _MDrv_SC_clear_interrupt(void *pInstance, SC_INT_SRC u8IntSrc)
258 {
259     XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
260     UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
261 
262     MS_U8 u8IntRemap = _MApi_XC_GetIntSrc(u8IntSrc);
263 
264     if(u8IntRemap < 16)
265     {
266 #if IRQ_CLEAN_INKERNEL
267         MS_U32 u32DummyReg = SC_R4BYTE(psXCInstPri->u32DeviceID, INTERRUPT_DUMMY_REGISTER);
268         MS_U32 u32DummyRegSrc = u32DummyReg << (SC_INT_START - IRQ_INT_START);
269 
270         if(SUPPORTED_KERNEL_INT&(1 << u8IntSrc))
271         {
272             if( u32DummyRegSrc&(1 << u8IntSrc))
273             {
274                 SC_W2BYTEMSK(psXCInstPri->u32DeviceID,INTERRUPT_DUMMY_REGISTER,0, (1 << (u8IntSrc-(SC_INT_START - IRQ_INT_START))));
275             }
276             else
277             {
278                 SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK00_12_L , BIT(u8IntRemap),BIT(u8IntRemap));
279                 SC_W2BYTEMSK(psXCInstPri->u32DeviceID,INTERRUPT_DUMMY_REGISTER, (1 << (u8IntSrc-(SC_INT_START - IRQ_INT_START))), (1 << (u8IntSrc-(SC_INT_START - IRQ_INT_START))));
280             }
281         }
282         else
283 #endif
284         {
285 #if defined(UFO_XC_HDR) && defined(UFO_XC_HDR_VERSION) && (UFO_XC_HDR_VERSION >= 2)
286             if((u8IntRemap != IRQ_INT_F2_IPVS_SB))
287             {
288                 SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK00_12_L , BIT(u8IntRemap),BIT(u8IntRemap));
289             }
290 #else
291             SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK00_12_L , BIT(u8IntRemap),BIT(u8IntRemap));
292 #endif
293         }
294     }
295     else
296     {
297 #if defined(UFO_XC_HDR) && defined(UFO_XC_HDR_VERSION) && (UFO_XC_HDR_VERSION >= 2)
298         //IRQ_INT_PWM_RP_R_INT and IRQ_INT_PWM_FP_R_INT is dummy will be cleaned in kernel
299 #if IRQ_CLEAN_INKERNEL
300         MS_U32 u32DummyReg = SC_R4BYTE(psXCInstPri->u32DeviceID, INTERRUPT_DUMMY_REGISTER);
301         MS_U32 u32DummyRegSrc = u32DummyReg << (SC_INT_START - IRQ_INT_START);
302 
303         if(SUPPORTED_KERNEL_INT&(1 << u8IntSrc))
304         {
305             if( u32DummyRegSrc&(1 << u8IntSrc))
306             {
307                 SC_W2BYTEMSK(psXCInstPri->u32DeviceID,INTERRUPT_DUMMY_REGISTER_H,0, (1 << ((u8IntSrc-(SC_INT_START - IRQ_INT_START))-16)));
308             }
309             else
310             {
311                 SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK00_13_L , BIT(u8IntRemap-16) ,BIT(u8IntRemap-16));
312                 SC_W2BYTEMSK(psXCInstPri->u32DeviceID,INTERRUPT_DUMMY_REGISTER_H, (1 << ((u8IntSrc-(SC_INT_START - IRQ_INT_START))-16)), (1 << ((u8IntSrc-(SC_INT_START - IRQ_INT_START))-16)));
313             }
314         }
315         else
316 #endif
317         {
318             SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK00_13_L , BIT(u8IntRemap-16) ,BIT(u8IntRemap-16));
319         }
320 #else
321         SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK00_13_L , BIT(u8IntRemap-16) ,BIT(u8IntRemap-16));
322 #endif
323     }
324     //MDrv_WriteByte(BK_SELECT_00, u8Bank);
325 }
326 
MDrv_SC_set_interrupt(void * pInstance,SC_INT_SRC u8IntSrc,MS_BOOL bEnable)327 void MDrv_SC_set_interrupt(void *pInstance, SC_INT_SRC u8IntSrc, MS_BOOL bEnable)
328 {
329 #if (!ENABLE_REGISTER_SPREAD)
330     MS_U8 u8Bank;
331 #endif
332     MS_U8 u8IntRemap = _MApi_XC_GetIntSrc(u8IntSrc);
333 
334 #if (!ENABLE_REGISTER_SPREAD)
335     u8Bank = MDrv_ReadByte(BK_SELECT_00);
336 #endif
337 
338     XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
339     UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
340 
341     if(bEnable)
342     {
343         if(u8IntRemap < 16)
344         {
345             SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK00_12_L ,BIT(u8IntRemap),BIT(u8IntRemap));
346             SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK00_14_L , 0 ,BIT(u8IntRemap));
347         }
348         else
349         {
350             SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK00_13_L ,BIT(u8IntRemap-16),BIT(u8IntRemap-16));
351             SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK00_15_L , 0 ,BIT(u8IntRemap-16));
352         }
353     }
354     else
355     {
356         if(u8IntRemap < 16)
357         {
358             SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK00_14_L , BIT(u8IntRemap),BIT(u8IntRemap));
359             SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK00_12_L , 0,BIT(u8IntRemap));
360         }
361         else
362         {
363             SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK00_15_L ,BIT(u8IntRemap-16),BIT(u8IntRemap-16));
364             SC_W2BYTEMSK(psXCInstPri->u32DeviceID, REG_SC_BK00_13_L , 0 ,BIT(u8IntRemap-16));
365         }
366 
367     }
368 #if (!ENABLE_REGISTER_SPREAD)
369     MDrv_WriteByte(BK_SELECT_00, u8Bank);
370 #endif
371 }
372 
373 #ifdef MSOS_TYPE_LINUX_KERNEL
MDrv_SC_vsync_isr(void)374 void MDrv_SC_vsync_isr(void)
375 {
376     void *pInstance = pu32XCInst_private;
377     XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
378 
379     UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
380     XC_RESOURCE_PRIVATE* pXCResourcePrivate = NULL;
381     UtopiaResourceGetPrivate(g_pXCResource[_XC_SELECT_INTERNAL_VARIABLE(psXCInstPri->u32DeviceID)],(void**)(&pXCResourcePrivate));
382     if (pXCResourcePrivate->stXC_Utility._XC_VSyncRun)
383     {
384         pXCResourcePrivate->stXC_Utility._XC_VSyncCount++;
385         if (pXCResourcePrivate->stXC_Utility._XC_VSyncCount >= pXCResourcePrivate->stXC_Utility._XC_VSyncMax)
386         {
387             pXCResourcePrivate->stXC_Utility._XC_EventFlag = 1;
388             wake_up(&pXCResourcePrivate->stXC_Utility._XC_EventQueue);
389         }
390     }
391 }
392 #endif // #ifdef MSOS_TYPE_LINUX_KERNEL
393 
394 
395 #ifdef MSOS_TYPE_LINUX_KERNEL
MDrv_SC_isr(InterruptNum eIntNum,void * dev_id)396 irqreturn_t MDrv_SC_isr(InterruptNum eIntNum, void* dev_id)
397 #else
398 void MDrv_SC_isr( InterruptNum eIntNum )
399 #endif
400 {
401     void *pInstance = pu32XCInst_private;
402     MS_U32 u32IntSource;
403     SC_INT_SRC eSCIntNum;
404     MS_U8 i;
405     XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
406     UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
407 
408     #if (!ENABLE_REGISTER_SPREAD)
409     MS_U8 u8OldISRBank;
410     #endif
411     XC_RESOURCE_PRIVATE* pXCResourcePrivate = NULL;
412     UtopiaResourceGetPrivate(g_pXCResource[_XC_SELECT_INTERNAL_VARIABLE(psXCInstPri->u32DeviceID)],(void**)(&pXCResourcePrivate));
413     UNUSED(eIntNum);
414 
415     // we can't quarantee ISR thread not being context switched out, so if we change bank here, it's very dangerous
416     // need to obtain mutex here
417 #ifdef MSOS_TYPE_LINUX_KERNEL
418     #define _XC_MUTEX_WAIT_TIMEOUT  10
419     _XC_SEMAPHORE_ENTRY(pInstance,E_XC_ID_VAR);
420     if(!MsOS_ObtainMutex(_XC_Mutex, _XC_MUTEX_WAIT_TIMEOUT))
421     {
422         SC_ISR_DBG(printf("ISR return\n"));
423 
424         // re-enable IRQ_DISP
425         MsOS_EnableInterrupt(E_INT_IRQ_DISP);
426         _XC_SEMAPHORE_RETURN(pInstance,E_XC_ID_VAR);
427         return IRQ_HANDLED;
428      }
429 #else
430 #ifndef MSOS_TYPE_ECOS
431     if(!MsOS_ObtainMutex(_XC_Mutex, MSOS_WAIT_FOREVER))
432     {
433         SC_ISR_DBG(printf("ISR return\n"));
434 
435         // re-enable IRQ_DISP
436         MsOS_EnableInterrupt(E_INT_IRQ_DISP);
437         return;
438     }
439 #endif
440 #endif
441     // read XC ISR status
442 
443     #if (!ENABLE_REGISTER_SPREAD)
444     u8OldISRBank = MDrv_ReadByte(BK_SELECT_00);
445     #endif
446 
447     u32IntSource = _MDrv_SC_get_interrupt(pInstance);
448 
449     u32IntSource = u32IntSource << (SC_INT_START - IRQ_INT_START);
450     SC_ISR_DBG(printf("ISR %8lx\n", u32IntSource));
451 
452 #ifdef MSOS_TYPE_LINUX_KERNEL
453     if(u32IntSource & (1 << SC_INT_VSINT))
454     {
455         MDrv_SC_vsync_isr();
456     }
457 #endif
458     for(eSCIntNum=SC_INT_DIPW; eSCIntNum<MAX_SC_INT; eSCIntNum++)
459     {
460         if(u32IntSource & (1 << eSCIntNum))
461         {
462             // this Interrupt happened, clear it
463             _MDrv_SC_clear_interrupt(pInstance, eSCIntNum);
464 
465             // call ISR
466             for(i=0; i<MAX_ISR_NUM_OF_EACH_INT; i++)
467             {
468                 if(pXCResourcePrivate->stdrvXC_ISR.stXCIsrInfo[eSCIntNum][i].aryXC_ISR != NULL)
469                 {
470                     // execute ISR
471                     (void)(pXCResourcePrivate->stdrvXC_ISR.stXCIsrInfo[eSCIntNum][i].aryXC_ISR) ((SC_INT_SRC)eSCIntNum, pXCResourcePrivate->stdrvXC_ISR.stXCIsrInfo[eSCIntNum][i].aryXC_ISR_Param);
472                 }
473             }
474         }
475     }
476 
477 #if (!ENABLE_REGISTER_SPREAD)
478     MDrv_WriteByte(BK_SELECT_00, u8OldISRBank);
479 #endif
480 
481 #ifndef MSOS_TYPE_ECOS
482     MsOS_ReleaseMutex(_XC_Mutex);
483 #endif
484 
485 #ifdef MSOS_TYPE_LINUX_KERNEL
486     _XC_SEMAPHORE_RETURN(pInstance,E_XC_ID_VAR);
487     MsOS_EnableInterrupt(E_INT_IRQ_DISP);
488     return IRQ_HANDLED;
489 #else
490     // re-enable IRQ_DISP
491     MsOS_EnableInterrupt(E_INT_IRQ_DISP);
492 #endif
493 }
494 
495 #ifdef MSOS_TYPE_LINUX_KERNEL
MDrv_SC1_isr(InterruptNum eIntNum,void * dev_id)496 irqreturn_t MDrv_SC1_isr(InterruptNum eIntNum, void* dev_id)
497 #else
498 void MDrv_SC1_isr( InterruptNum eIntNum )
499 #endif
500 {
501     void *pInstance = pu32XCInst_1_private;
502     MS_U32 u32IntSource;
503     SC_INT_SRC eSCIntNum;
504     MS_U8 i;
505 
506 #if (!ENABLE_REGISTER_SPREAD)
507     MS_U8 u8OldISRBank;
508 #endif
509     XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
510     UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
511     UNUSED(eIntNum);
512 
513     // we can't quarantee ISR thread not being context switched out, so if we change bank here, it's very dangerous
514     // need to obtain mutex here
515 #ifdef MSOS_TYPE_LINUX_KERNEL
516 #define _XC_MUTEX_WAIT_TIMEOUT  10
517     _XC_SEMAPHORE_ENTRY(pInstance,E_XC_ID_VAR);
518     if(!MsOS_ObtainMutex(_XC_Mutex, _XC_MUTEX_WAIT_TIMEOUT))
519     {
520         SC_ISR_DBG(printf("ISR return\n"));
521 
522         // re-enable IRQ_DISP
523         MsOS_EnableInterrupt(E_INT_IRQ_DISP1);
524         _XC_SEMAPHORE_RETURN(pInstance,E_XC_ID_VAR);
525         return IRQ_HANDLED;
526      }
527 #else
528 #ifndef MSOS_TYPE_ECOS
529     if(!MsOS_ObtainMutex(_XC_Mutex, MSOS_WAIT_FOREVER))
530     {
531         SC_ISR_DBG(printf("ISR return\n"));
532 
533         // re-enable IRQ_DISP
534         MsOS_EnableInterrupt(E_INT_IRQ_DISP1);
535         return;
536     }
537 #endif
538 #endif
539     // read XC ISR status
540 
541 #if (!ENABLE_REGISTER_SPREAD)
542     u8OldISRBank = MDrv_ReadByte(BK_SELECT_00);
543 #endif
544 
545     u32IntSource = _MDrv_SC_get_interrupt(pInstance);
546 
547     u32IntSource = u32IntSource << (SC_INT_START - IRQ_INT_START);
548     SC_ISR_DBG(printf("ISR %8lx\n", u32IntSource));
549 
550 #ifdef MSOS_TYPE_LINUX_KERNEL
551     if(u32IntSource & (1 << SC_INT_VSINT))
552     {
553         MDrv_SC_vsync_isr();
554     }
555 #endif
556 
557 #ifdef MSOS_TYPE_LINUX_KERNEL
558     _XC_SEMAPHORE_RETURN(pInstance,E_XC_ID_VAR);
559 #endif
560     _XC_SEMAPHORE_ENTRY(pInstance,E_XC_ID_VAR);
561     XC_RESOURCE_PRIVATE* pXCResourcePrivate = NULL;
562     UtopiaResourceGetPrivate(g_pXCResource[_XC_SELECT_INTERNAL_VARIABLE(psXCInstPri->u32DeviceID)],(void**)(&pXCResourcePrivate));
563     for(eSCIntNum=SC_INT_DIPW; eSCIntNum<MAX_SC_INT; eSCIntNum++)
564     {
565         if(u32IntSource & (1 << eSCIntNum))
566         {
567             // this Interrupt happened, clear it
568             _MDrv_SC_clear_interrupt(pInstance, eSCIntNum);
569 
570             // call ISR
571             for(i=0; i<MAX_ISR_NUM_OF_EACH_INT; i++)
572             {
573                 if(pXCResourcePrivate->stdrvXC_ISR.stXCIsrInfo[eSCIntNum][i].aryXC_ISR != NULL)
574                 {
575                     // execute ISR
576                     (void)(pXCResourcePrivate->stdrvXC_ISR.stXCIsrInfo[eSCIntNum][i].aryXC_ISR) ((SC_INT_SRC)eSCIntNum, pXCResourcePrivate->stdrvXC_ISR.stXCIsrInfo[eSCIntNum][i].aryXC_ISR_Param);
577                 }
578             }
579         }
580     }
581     _XC_SEMAPHORE_RETURN(pInstance,E_XC_ID_VAR);
582 #ifdef MSOS_TYPE_LINUX_KERNEL
583     _XC_SEMAPHORE_ENTRY(pInstance,E_XC_ID_VAR);
584 #endif
585 
586 #if (!ENABLE_REGISTER_SPREAD)
587     MDrv_WriteByte(BK_SELECT_00, u8OldISRBank);
588 #endif
589 
590 #ifndef MSOS_TYPE_ECOS
591     MsOS_ReleaseMutex(_XC_Mutex);
592 #endif
593 
594 #ifdef MSOS_TYPE_LINUX_KERNEL
595     _XC_SEMAPHORE_RETURN(pInstance,E_XC_ID_VAR);
596     MsOS_EnableInterrupt(E_INT_IRQ_DISP);
597     return IRQ_HANDLED;
598 #else
599     // re-enable IRQ_DISP
600     MsOS_EnableInterrupt(E_INT_IRQ_DISP1);
601 #endif
602 }
603 
604 
605 //////////////////////////////////
606 // Interrupt Function
607 //////////////////////////////////
608 //-------------------------------------------------------------------------------------------------
609 /// Get maximum number of interrupts that scaler supports
610 /// @return @ref MS_U8 maximum number of interrupts that scaler supports
611 //-------------------------------------------------------------------------------------------------
MDrv_XC_InterruptGetMaxIntNum(void * pInstance)612 MS_U8   MDrv_XC_InterruptGetMaxIntNum(void *pInstance)
613 {
614     UNUSED(pInstance);
615     return MAX_SC_INT;
616 }
617 
618 //-------------------------------------------------------------------------------------------------
619 /// After get maximum number of interrupts by @ref MDrv_XC_InterruptGetMaxIntNum, you can
620 /// check each interrupt supported btuy scaler or not.
621 /// @param eIntNum      \b IN: the interrupt number to query
622 /// @return @ref MS_BOOL the interrupt number supported or not
623 //-------------------------------------------------------------------------------------------------
MDrv_XC_InterruptAvaliable(void * pInstance,SC_INT_SRC eIntNum)624 MS_BOOL MDrv_XC_InterruptAvaliable(void *pInstance, SC_INT_SRC eIntNum)
625 {
626     MS_U8 i = 0;
627     MS_BOOL bReturn = FALSE;
628 
629     // check if out of range or not supported
630     if((eIntNum >= MDrv_XC_InterruptGetMaxIntNum(pInstance)) || (((1UL << eIntNum) & SUPPORTED_XC_INT) == 0))
631     {
632         return bReturn;
633     }
634     XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
635     UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
636     XC_RESOURCE_PRIVATE* pXCResourcePrivate = NULL;
637     UtopiaResourceGetPrivate(g_pXCResource[_XC_SELECT_INTERNAL_VARIABLE(psXCInstPri->u32DeviceID)],(void**)(&pXCResourcePrivate));
638     // search avaliable CB to attach
639     for(i=0; i<MAX_ISR_NUM_OF_EACH_INT; i++)
640     {
641         if(pXCResourcePrivate->stdrvXC_ISR.stXCIsrInfo[eIntNum][i].aryXC_ISR == NULL)
642         {
643             bReturn = TRUE;
644             break;
645         }
646     }
647 
648     return bReturn;
649 }
650 
651 //-------------------------------------------------------------------------------------------------
652 /// Check if ISR already attached or not because we allowed to attach same ISR for many times
653 /// @param eIntNum @ref SC_INT_SRC          \b IN: the interrupt number that you want to attach
654 /// @param pIntCb  @ref SC_InterruptCb      \b IN: the ISR that you want to attach to the interrupt number
655 /// @param pParam                           \b IN: the parameter that you want to pass to the ISR when called
656 /// @return @ref MS_BOOL Is ISR already attached or not.
657 //-------------------------------------------------------------------------------------------------
MDrv_XC_InterruptIsAttached(void * pInstance,SC_INT_SRC eIntNum,SC_InterruptCb pIntCb,void * pParam)658 MS_BOOL MDrv_XC_InterruptIsAttached(void *pInstance, SC_INT_SRC eIntNum, SC_InterruptCb pIntCb, void * pParam)
659 {
660     MS_U8 i = 0;
661     XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
662     UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
663     XC_RESOURCE_PRIVATE* pXCResourcePrivate = NULL;
664     UtopiaResourceGetPrivate(g_pXCResource[_XC_SELECT_INTERNAL_VARIABLE(psXCInstPri->u32DeviceID)],(void**)(&pXCResourcePrivate));
665     for(i=0; i<MAX_ISR_NUM_OF_EACH_INT; i++)
666     {
667         if((pXCResourcePrivate->stdrvXC_ISR.stXCIsrInfo[eIntNum][i].aryXC_ISR == pIntCb) && (pXCResourcePrivate->stdrvXC_ISR.stXCIsrInfo[eIntNum][i].aryXC_ISR_Param == pParam))
668         {
669             return TRUE;
670         }
671     }
672 
673     return FALSE;
674 }
675 
676 //-------------------------------------------------------------------------------------------------
677 /// Attach interrupt to specified interrupt number
678 /// @param eIntNum @ref SC_INT_SRC          \b IN: the interrupt number that you want to attach
679 /// @param pIntCb  @ref SC_InterruptCb      \b IN: the ISR that you want to attach to the interrupt number
680 /// @param pParam                           \b IN: the parameter that you want to pass to the ISR when called
681 /// @return @ref MS_BOOL attach successed or not, FALSE means can't attach more ISR
682 //-------------------------------------------------------------------------------------------------
MDrv_XC_InterruptAttach(void * pInstance,SC_INT_SRC eIntNum,SC_InterruptCb pIntCb,void * pParam)683 MS_BOOL MDrv_XC_InterruptAttach(void *pInstance, SC_INT_SRC eIntNum, SC_InterruptCb pIntCb, void * pParam)
684 {
685     MS_BOOL bReturn = FALSE;
686     _XC_ENTRY(pInstance);
687     bReturn = MDrv_XC_InterruptAttachWithoutMutex(pInstance, eIntNum, pIntCb, pParam);
688     _XC_RETURN(pInstance);
689     return bReturn;
690 }
691 
692 //-------------------------------------------------------------------------------------------------
693 /// DeAttach interrupt to specified interrupt number
694 /// @param eIntNum @ref SC_INT_SRC          \b IN: the interrupt number that you want to de-attach
695 /// @param pIntCb  @ref SC_InterruptCb      \b IN: the ISR that you want to de-attach to the interrupt number
696 /// @param pParam                           \b IN: the parameter that you want to pass to the ISR when called
697 /// @return @ref MS_BOOL attach successed or not, FALSE means can't de-attach this ISR because it not exist
698 //-------------------------------------------------------------------------------------------------
MDrv_XC_InterruptDeAttach(void * pInstance,SC_INT_SRC eIntNum,SC_InterruptCb pIntCb,void * pParam)699 MS_BOOL MDrv_XC_InterruptDeAttach(void *pInstance, SC_INT_SRC eIntNum, SC_InterruptCb pIntCb, void * pParam)
700 {
701     MS_BOOL bReturn = FALSE;
702 
703     _XC_ENTRY(pInstance);
704     bReturn = MDrv_XC_InterruptDeAttachWithoutMutex(pInstance, eIntNum, pIntCb, pParam);
705     _XC_RETURN(pInstance);
706     return bReturn;
707 }
708 
MDrv_XC_InterruptAttachWithoutMutex(void * pInstance,SC_INT_SRC eIntNum,SC_InterruptCb pIntCb,void * pParam)709 MS_BOOL MDrv_XC_InterruptAttachWithoutMutex(void *pInstance, SC_INT_SRC eIntNum, SC_InterruptCb pIntCb, void * pParam)
710 {
711     MS_U8 i = 0;
712     MS_BOOL bReturn = FALSE;
713 
714     // do SetWindow in AN to create DS script,so this isn't need attach interrupt function
715     if (g_bSWDSGenScenario == TRUE)
716     {
717         printf("ISRAttach failed %d ! do SetWindow in AN to create DS script,so this isn't need attach interrupt function!\n", eIntNum);
718         return bReturn;
719     }
720 
721     // check if out of range or not supported
722     if((eIntNum >= MDrv_XC_InterruptGetMaxIntNum(pInstance)) || (((1UL << eIntNum) & SUPPORTED_XC_INT) == 0))
723     {
724         SC_ISR_DBG(printf("ISRAttach failed %d (max %d, supported %lx)\n", eIntNum, MDrv_XC_InterruptGetMaxIntNum(pInstance), (MS_U32)SUPPORTED_XC_INT));
725         return bReturn;
726     }
727     XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
728     UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
729     XC_RESOURCE_PRIVATE* pXCResourcePrivate = NULL;
730     UtopiaResourceGetPrivate(g_pXCResource[_XC_SELECT_INTERNAL_VARIABLE(psXCInstPri->u32DeviceID)],(void**)(&pXCResourcePrivate));
731     // attach ISR
732     for(i=0; i<MAX_ISR_NUM_OF_EACH_INT; i++)
733     {
734         if(pXCResourcePrivate->stdrvXC_ISR.stXCIsrInfo[eIntNum][i].aryXC_ISR == NULL)
735         {
736             // disable interrupt first to avoid racing condition, for example, interrupt come in after set pIntCb but before set pParam, will call ISR and passing parameter NULL
737             MDrv_SC_set_interrupt(pInstance, eIntNum, DISABLE);
738 
739             pXCResourcePrivate->stdrvXC_ISR.stXCIsrInfo[eIntNum][i].aryXC_ISR_Param = pParam;
740             pXCResourcePrivate->stdrvXC_ISR.stXCIsrInfo[eIntNum][i].aryXC_ISR = pIntCb;
741 
742             // enable interrupt
743             MDrv_SC_set_interrupt(pInstance, eIntNum, ENABLE);
744 
745             SC_ISR_DBG(printf("ISRAttach %d successed to [%d][%d]\n", eIntNum, eIntNum, i));
746 
747             bReturn = TRUE;
748             break;
749         }
750     }
751 
752     return bReturn;
753 }
754 
755 
MDrv_XC_InterruptDeAttachWithoutMutex(void * pInstance,SC_INT_SRC eIntNum,SC_InterruptCb pIntCb,void * pParam)756 MS_BOOL MDrv_XC_InterruptDeAttachWithoutMutex(void *pInstance, SC_INT_SRC eIntNum, SC_InterruptCb pIntCb, void * pParam)
757 {
758     MS_U8 i = 0;
759     MS_BOOL bReturn = FALSE;
760 
761     // check if out of range or not supported
762     if((eIntNum >= MDrv_XC_InterruptGetMaxIntNum(pInstance)) || (((1UL << eIntNum) & SUPPORTED_XC_INT) == 0))
763     {
764         SC_ISR_DBG(printf("ISRDeAttach failed %d (max %d, supported %lx)\n", eIntNum, MDrv_XC_InterruptGetMaxIntNum(pInstance), SUPPORTED_XC_INT));
765         return bReturn;
766     }
767     XC_INSTANCE_PRIVATE *psXCInstPri = NULL;
768     UtopiaInstanceGetPrivate(pInstance, (void**)&psXCInstPri);
769     XC_RESOURCE_PRIVATE* pXCResourcePrivate = NULL;
770     UtopiaResourceGetPrivate(g_pXCResource[_XC_SELECT_INTERNAL_VARIABLE(psXCInstPri->u32DeviceID)],(void**)(&pXCResourcePrivate));
771     // de-attach the ISR
772     for(i=0; i<MAX_ISR_NUM_OF_EACH_INT; i++)
773     {
774         if((pXCResourcePrivate->stdrvXC_ISR.stXCIsrInfo[eIntNum][i].aryXC_ISR == pIntCb) &&
775             (pXCResourcePrivate->stdrvXC_ISR.stXCIsrInfo[eIntNum][i].aryXC_ISR_Param == pParam))
776         {
777             // disable interrupt first to avoid racing condition
778             MDrv_SC_set_interrupt(pInstance, eIntNum, DISABLE);
779 
780             pXCResourcePrivate->stdrvXC_ISR.stXCIsrInfo[eIntNum][i].aryXC_ISR = NULL;
781             pXCResourcePrivate->stdrvXC_ISR.stXCIsrInfo[eIntNum][i].aryXC_ISR_Param = NULL;
782             bReturn = TRUE;
783 
784             SC_ISR_DBG(printf("ISRDeAttach %d successed to [%d][%d]\n", eIntNum, eIntNum, i));
785             break;
786         }
787     }
788 
789     // re-enable interrupt
790     if(bReturn)
791     {
792         // removed ISR, check if there is other ISR left
793         for(i=0; i<MAX_ISR_NUM_OF_EACH_INT; i++)
794         {
795             if(pXCResourcePrivate->stdrvXC_ISR.stXCIsrInfo[eIntNum][i].aryXC_ISR != NULL)
796             {
797                 // re-enable interrupt
798                 MDrv_SC_set_interrupt(pInstance, eIntNum, ENABLE);
799                 SC_ISR_DBG(printf("ISRAttach %d re-enable ISR\n", eIntNum));
800             }
801         }
802     }
803 
804     return bReturn;
805 }
806 #undef _MDRV_XC_ISR_C_
807 
808