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