1 #include <linux/init.h>
2 #include <linux/module.h>
3 #include <linux/kernel.h>
4 #include <linux/types.h>
5 #include <linux/device.h>
6 #include <linux/kdev_t.h>
8 #include <linux/cdev.h>
9 #include <linux/platform_device.h>
10 #include <linux/dma-mapping.h>
11 #include <linux/mm_types.h>
13 #include <linux/jiffies.h>
14 #include <linux/sched.h>
15 #include <linux/cpumask.h>
16 #include <asm/uaccess.h>
18 #include <linux/vmalloc.h>
19 #include <linux/interrupt.h>
20 #include <mach/irqs.h>
21 #include <linux/wait.h>
22 #include <linux/proc_fs.h>
23 #include <linux/semaphore.h>
25 #include <linux/delay.h>
26 #include <linux/earlysuspend.h>
27 #include "mach/sync_write.h"
28 #include "mach/mt_reg_base.h"
29 #include "mach/mt_clkmgr.h"
30 #ifdef CONFIG_MTK_HIBERNATION
31 #include "mach/mtk_hibernate_dpm.h"
34 #include "videocodec_kernel_driver.h"
36 #include <asm/cacheflush.h>
38 #include <asm/sizes.h>
39 #include "val_types_private.h"
40 #include "hal_types_private.h"
41 #include "val_api_private.h"
45 #define VDO_HW_WRITE(ptr,data) mt65xx_reg_sync_writel(data,ptr)
46 #define VDO_HW_READ(ptr) (*((volatile unsigned int * const)(ptr)))
48 #define VCODEC_DEVNAME "Vcodec"
49 #define MT8127_VCODEC_DEV_MAJOR_NUMBER 160 //189
50 //#define VDEC_USE_L2C
52 static dev_t vcodec_devno
= MKDEV(MT8127_VCODEC_DEV_MAJOR_NUMBER
,0);
53 static struct cdev
*vcodec_cdev
;
54 static struct class *vcodec_class
= NULL
;
55 static struct device
*vcodec_device
= NULL
;
57 static DEFINE_MUTEX(IsOpenedLock
);
58 static DEFINE_MUTEX(PWRLock
);
59 static DEFINE_MUTEX(VdecHWLock
);
60 static DEFINE_MUTEX(VencHWLock
);
61 static DEFINE_MUTEX(EncEMILock
);
62 static DEFINE_MUTEX(L2CLock
);
63 static DEFINE_MUTEX(DecEMILock
);
64 static DEFINE_MUTEX(DriverOpenCountLock
);
65 static DEFINE_MUTEX(DecHWLockEventTimeoutLock
);
66 static DEFINE_MUTEX(EncHWLockEventTimeoutLock
);
67 static DEFINE_MUTEX(VdecPWRLock
);
68 static DEFINE_MUTEX(VencPWRLock
);
70 static DEFINE_SPINLOCK(DecIsrLock
);
71 static DEFINE_SPINLOCK(EncIsrLock
);
72 static DEFINE_SPINLOCK(LockDecHWCountLock
);
73 static DEFINE_SPINLOCK(LockEncHWCountLock
);
74 static DEFINE_SPINLOCK(DecISRCountLock
);
75 static DEFINE_SPINLOCK(EncISRCountLock
);
78 static VAL_EVENT_T DecHWLockEvent
; //mutex : HWLockEventTimeoutLock
79 static VAL_EVENT_T EncHWLockEvent
; //mutex : HWLockEventTimeoutLock
80 static VAL_EVENT_T DecIsrEvent
; //mutex : HWLockEventTimeoutLock
81 static VAL_EVENT_T EncIsrEvent
; //mutex : HWLockEventTimeoutLock
82 static int MT8127Driver_Open_Count
; //mutex : DriverOpenCountLock
83 static VAL_UINT32_T gu4PWRCounter
= 0; //mutex : PWRLock
84 static VAL_UINT32_T gu4EncEMICounter
= 0; //mutex : EncEMILock
85 static VAL_UINT32_T gu4DecEMICounter
= 0; //mutex : DecEMILock
86 static VAL_UINT32_T gu4L2CCounter
= 0; //mutex : L2CLock
87 static VAL_BOOL_T bIsOpened
= VAL_FALSE
; //mutex : IsOpenedLock
88 static VAL_UINT32_T gu4HwVencIrqStatus
= 0; //hardware VENC IRQ status (VP8/H264)
90 static VAL_UINT32_T gu4VdecPWRCounter
= 0; //mutex : VdecPWRLock
91 static VAL_UINT32_T gu4VencPWRCounter
= 0; //mutex : VencPWRLock
94 static VAL_UINT32_T gu4VdecLockThreadId
= 0;
96 //#define MT8127_VCODEC_DEBUG
97 #ifdef MT8127_VCODEC_DEBUG
99 #define VCODEC_DEBUG MFV_LOGE
101 #define MFV_LOGD MFV_LOGE
103 #define VCODEC_DEBUG(...)
105 //#define MFV_LOGD MFV_LOGE
106 #define MFV_LOGD(...)
109 // VENC physical base address
111 #define VENC_BASE 0x15009000
112 #define VENC_REGION 0x1000
113 #define VENC_IRQ_STATUS_addr VENC_BASE + 0x05C
114 #define VENC_IRQ_ACK_addr VENC_BASE + 0x060
115 #define VENC_MP4_IRQ_ACK_addr VENC_BASE + 0x678
116 #define VENC_MP4_IRQ_STATUS_addr VENC_BASE + 0x67C
117 #define VENC_ZERO_COEF_COUNT_addr VENC_BASE + 0x688
118 #define VENC_BYTE_COUNT_addr VENC_BASE + 0x680
119 #define VENC_MP4_IRQ_ENABLE_addr VENC_BASE + 0x668
120 #define VENC_SW_PAUSE VENC_BASE + 0x0AC
121 #define VENC_SW_HRST_N VENC_BASE + 0x0A8
123 #define VENC_MP4_STATUS_addr VENC_BASE + 0x664
124 #define VENC_MP4_MVQP_STATUS_addr VENC_BASE + 0x6E4
126 #define VENC_IRQ_STATUS_SPS 0x1
127 #define VENC_IRQ_STATUS_PPS 0x2
128 #define VENC_IRQ_STATUS_FRM 0x4
129 #define VENC_IRQ_STATUS_DRAM 0x8
130 #define VENC_IRQ_STATUS_PAUSE 0x10
131 #define VENC_IRQ_STATUS_SWITCH 0x20
133 //#define VENC_PWR_FPGA
134 // Cheng-Jung 20120621 VENC power physical base address (FPGA only, should use API) [
136 #define CLK_CFG_0_addr 0x10000140
137 #define CLK_CFG_4_addr 0x10000150
138 #define VENC_PWR_addr 0x10006230
139 #define VENCSYS_CG_SET_addr 0x15000004
141 #define PWR_ONS_1_D 3
142 #define PWR_CKD_1_D 4
143 #define PWR_ONN_1_D 2
144 #define PWR_ISO_1_D 1
145 #define PWR_RST_0_D 0
147 #define PWR_ON_SEQ_0 ((0x1 << PWR_ONS_1_D) | (0x1 << PWR_CKD_1_D) | (0x1 << PWR_ONN_1_D) | (0x1 << PWR_ISO_1_D) | (0x0 << PWR_RST_0_D))
148 #define PWR_ON_SEQ_1 ((0x1 << PWR_ONS_1_D) | (0x0 << PWR_CKD_1_D) | (0x1 << PWR_ONN_1_D) | (0x1 << PWR_ISO_1_D) | (0x0 << PWR_RST_0_D))
149 #define PWR_ON_SEQ_2 ((0x1 << PWR_ONS_1_D) | (0x0 << PWR_CKD_1_D) | (0x1 << PWR_ONN_1_D) | (0x0 << PWR_ISO_1_D) | (0x0 << PWR_RST_0_D))
150 #define PWR_ON_SEQ_3 ((0x1 << PWR_ONS_1_D) | (0x0 << PWR_CKD_1_D) | (0x1 << PWR_ONN_1_D) | (0x0 << PWR_ISO_1_D) | (0x1 << PWR_RST_0_D))
154 // VDEC virtual base address
155 #define VDEC_BASE_PHY 0x16000000
156 #define VDEC_REGION 0x29000
157 #define VDEC_MISC_BASE VDEC_BASE + 0x0000
158 #define VDEC_VLD_BASE VDEC_BASE + 0x1000
160 #define HW_BASE 0x7FFF000
161 #define HW_REGION 0x2000
163 #define INFO_BASE_1 0x08000000
164 #define INFO_REGION_1 0x1000
165 #define INFO_BASE_2 0x10000000
166 #define INFO_REGION_2 0x1000
167 #define INFO_BASE_3 0x10004000
168 #define INFO_REGION_3 0x1000
170 int KVA_VENC_IRQ_ACK_ADDR
;
171 int KVA_VENC_IRQ_STATUS_ADDR
;
172 int KVA_VENC_SW_PAUSE
, KVA_VENC_SW_HRST_N
;
174 // Cheng-Jung 20120621 VENC power physical base address (FPGA only, should use API) [
175 int KVA_VENC_CLK_CFG_0_ADDR
, KVA_VENC_CLK_CFG_4_ADDR
, KVA_VENC_PWR_ADDR
, KVA_VENCSYS_CG_SET_ADDR
;
179 extern unsigned int pmem_user_v2p_video(unsigned int va
);
181 extern int config_L2(int size
);
184 void vdec_power_on(void)
186 mutex_lock(&VdecPWRLock
);
188 mutex_unlock(&VdecPWRLock
);
191 enable_clock(MT_CG_DISP0_SMI_COMMON
, "VDEC");
192 enable_clock(MT_CG_VDEC0_VDEC
, "VDEC");
193 enable_clock(MT_CG_VDEC1_LARB
, "VDEC");
195 enable_clock(MT_CG_INFRA_L2C_SRAM
, "VDEC");
197 if (0x111 != VDO_HW_READ(VDEC_GCON_BASE
))
199 MFV_LOGE("[MFV][ERROR] Failed to turn VDEC clock on! VDEC_CG = 0x%08x, VDEC_LARB_CG = 0x%08x", VDO_HW_READ(VDEC_GCON_BASE
), VDO_HW_READ(VDEC_GCON_BASE
+ 0x0008));
203 void vdec_power_off(void)
205 mutex_lock(&VdecPWRLock
);
206 if (gu4VdecPWRCounter
== 0)
213 disable_clock(MT_CG_VDEC0_VDEC
, "VDEC");
214 disable_clock(MT_CG_VDEC1_LARB
, "VDEC");
215 disable_clock(MT_CG_DISP0_SMI_COMMON
, "VDEC");
217 disable_clock(MT_CG_INFRA_L2C_SRAM
, "VDEC");
220 mutex_unlock(&VdecPWRLock
);
223 void venc_power_on(void)
225 mutex_lock(&VencPWRLock
);
227 mutex_unlock(&VencPWRLock
);
229 MFV_LOGD("venc_power_on +\n");
231 // Cheng-Jung 20120621 VENC power physical base address (FPGA only, should use API) [
232 //VDO_HW_WRITE(KVA_VENC_CLK_CFG_0_ADDR, ((VDO_HW_READ(KVA_VENC_CLK_CFG_0_ADDR) & 0xfffffff8) | 0x00000001));
233 //VDO_HW_WRITE(KVA_VENC_CLK_CFG_0_ADDR, ((VDO_HW_READ(KVA_VENC_CLK_CFG_0_ADDR) & 0xfffff8ff) | 0x00000100));
234 //VDO_HW_WRITE(KVA_VENC_CLK_CFG_4_ADDR, ((VDO_HW_READ(KVA_VENC_CLK_CFG_4_ADDR) & 0xffff00ff) | 0x00000600));
237 VDO_HW_WRITE(KVA_VENC_PWR_ADDR
, ((VDO_HW_READ(KVA_VENC_PWR_ADDR
) & 0xffffffc0) | PWR_ON_SEQ_0
));
238 VDO_HW_WRITE(KVA_VENC_PWR_ADDR
, ((VDO_HW_READ(KVA_VENC_PWR_ADDR
) & 0xffffffc0) | PWR_ON_SEQ_1
));
239 VDO_HW_WRITE(KVA_VENC_PWR_ADDR
, ((VDO_HW_READ(KVA_VENC_PWR_ADDR
) & 0xffffffc0) | PWR_ON_SEQ_2
));
240 VDO_HW_WRITE(KVA_VENC_PWR_ADDR
, ((VDO_HW_READ(KVA_VENC_PWR_ADDR
) & 0xffffffc0) | PWR_ON_SEQ_3
));
242 // CG (clock gate) on
243 VDO_HW_WRITE(KVA_VENCSYS_CG_SET_ADDR
, 0x00000001);
246 enable_clock(MT_CG_DISP0_SMI_COMMON
, "VENC");
247 enable_clock(MT_CG_IMAGE_VENC_JPENC
, "VENC");
248 enable_clock(MT_CG_IMAGE_LARB2_SMI
, "VENC");
251 MFV_LOGD("venc_power_on -\n");
254 void venc_power_off(void)
256 mutex_lock(&VencPWRLock
);
257 if (gu4VencPWRCounter
== 0)
263 MFV_LOGD("venc_power_off +\n");
264 disable_clock(MT_CG_IMAGE_VENC_JPENC
, "VENC");
265 disable_clock(MT_CG_IMAGE_LARB2_SMI
, "VENC");
266 disable_clock(MT_CG_DISP0_SMI_COMMON
, "VENC");
267 MFV_LOGD("venc_power_off -\n");
269 mutex_unlock(&VencPWRLock
);
274 VAL_RESULT_T eValRet
;
275 unsigned long ulFlags
, ulFlagsISR
, ulFlagsLockHW
;
277 VAL_UINT32_T u4TempDecISRCount
= 0;
278 VAL_UINT32_T u4TempLockDecHWCount
= 0;
279 VAL_UINT32_T u4CgStatus
= 0;
280 VAL_UINT32_T u4DecDoneStatus
= 0;
282 u4CgStatus
= VDO_HW_READ(0xF6000000);
283 if ((u4CgStatus
& 0x10) != 0)
285 MFV_LOGE("[MFV][ERROR] DEC ISR, VDEC active is not 0x0 (0x%08x)", u4CgStatus
);
289 u4DecDoneStatus
= VDO_HW_READ(0xF60200A4);
290 if ((u4DecDoneStatus
& (0x1 << 16)) != 0x10000)
292 MFV_LOGE("[MFV][ERROR] DEC ISR, Decode done status is not 0x1 (0x%08x)", u4DecDoneStatus
);
297 spin_lock_irqsave(&DecISRCountLock
, ulFlagsISR
);
299 u4TempDecISRCount
= gu4DecISRCount
;
300 spin_unlock_irqrestore(&DecISRCountLock
, ulFlagsISR
);
302 spin_lock_irqsave(&LockDecHWCountLock
, ulFlagsLockHW
);
303 u4TempLockDecHWCount
= gu4LockDecHWCount
;
304 spin_unlock_irqrestore(&LockDecHWCountLock
, ulFlagsLockHW
);
306 if (u4TempDecISRCount
!= u4TempLockDecHWCount
)
308 //MFV_LOGE("[INFO] Dec ISRCount: 0x%x, LockHWCount:0x%x\n", u4TempDecISRCount, u4TempLockDecHWCount);
312 VDO_HW_WRITE(VDEC_MISC_BASE
+41*4, VDO_HW_READ(VDEC_MISC_BASE
+ 41*4) | 0x11);
313 VDO_HW_WRITE(VDEC_MISC_BASE
+41*4, VDO_HW_READ(VDEC_MISC_BASE
+ 41*4) & ~0x10);
316 spin_lock_irqsave(&DecIsrLock
, ulFlags
);
317 eValRet
= eVideoSetEvent(&DecIsrEvent
, sizeof(VAL_EVENT_T
));
318 if(VAL_RESULT_NO_ERROR
!= eValRet
)
320 MFV_LOGE("[MFV][ERROR] ISR set DecIsrEvent error\n");
322 spin_unlock_irqrestore(&DecIsrLock
, ulFlags
);
330 VAL_RESULT_T eValRet
;
331 unsigned long ulFlagsISR
, ulFlagsLockHW
;
334 VAL_UINT32_T u4TempEncISRCount
= 0;
335 VAL_UINT32_T u4TempLockEncHWCount
= 0;
336 //----------------------
338 spin_lock_irqsave(&EncISRCountLock
, ulFlagsISR
);
340 u4TempEncISRCount
= gu4EncISRCount
;
341 spin_unlock_irqrestore(&EncISRCountLock
, ulFlagsISR
);
343 spin_lock_irqsave(&LockEncHWCountLock
, ulFlagsLockHW
);
344 u4TempLockEncHWCount
= gu4LockEncHWCount
;
345 spin_unlock_irqrestore(&LockEncHWCountLock
, ulFlagsLockHW
);
347 if (u4TempEncISRCount
!= u4TempLockEncHWCount
)
349 //MFV_LOGE("[INFO] Enc ISRCount: 0x%x, LockHWCount:0x%x\n", u4TempEncISRCount, u4TempLockEncHWCount);
352 if (grVcodecEncHWLock
.pvHandle
== 0)
354 MFV_LOGE("[ERROR] NO one Lock Enc HW, please check!!\n");
357 //VDO_HW_WRITE(KVA_VENC_MP4_IRQ_ACK_ADDR, 1);
358 VDO_HW_WRITE(KVA_VENC_IRQ_ACK_ADDR
, VENC_IRQ_STATUS_PAUSE
);
359 //VDO_HW_WRITE(KVA_VENC_IRQ_ACK_ADDR, VENC_IRQ_STATUS_DRAM_VP8);
360 VDO_HW_WRITE(KVA_VENC_IRQ_ACK_ADDR
, VENC_IRQ_STATUS_SWITCH
);
361 VDO_HW_WRITE(KVA_VENC_IRQ_ACK_ADDR
, VENC_IRQ_STATUS_DRAM
);
362 VDO_HW_WRITE(KVA_VENC_IRQ_ACK_ADDR
, VENC_IRQ_STATUS_SPS
);
363 VDO_HW_WRITE(KVA_VENC_IRQ_ACK_ADDR
, VENC_IRQ_STATUS_PPS
);
364 VDO_HW_WRITE(KVA_VENC_IRQ_ACK_ADDR
, VENC_IRQ_STATUS_FRM
);
368 if (grVcodecEncHWLock
.eDriverType
== VAL_DRIVER_TYPE_H264_ENC
) // hardwire
370 gu4HwVencIrqStatus
= VDO_HW_READ(KVA_VENC_IRQ_STATUS_ADDR
);
371 if (gu4HwVencIrqStatus
& VENC_IRQ_STATUS_PAUSE
)
373 VDO_HW_WRITE(KVA_VENC_IRQ_ACK_ADDR
, VENC_IRQ_STATUS_PAUSE
);
375 if (gu4HwVencIrqStatus
& VENC_IRQ_STATUS_SWITCH
)
377 VDO_HW_WRITE(KVA_VENC_IRQ_ACK_ADDR
, VENC_IRQ_STATUS_SWITCH
);
379 if (gu4HwVencIrqStatus
& VENC_IRQ_STATUS_DRAM
)
381 VDO_HW_WRITE(KVA_VENC_IRQ_ACK_ADDR
, VENC_IRQ_STATUS_DRAM
);
383 if (gu4HwVencIrqStatus
& VENC_IRQ_STATUS_SPS
)
385 VDO_HW_WRITE(KVA_VENC_IRQ_ACK_ADDR
, VENC_IRQ_STATUS_SPS
);
387 if (gu4HwVencIrqStatus
& VENC_IRQ_STATUS_PPS
)
389 VDO_HW_WRITE(KVA_VENC_IRQ_ACK_ADDR
, VENC_IRQ_STATUS_PPS
);
391 if (gu4HwVencIrqStatus
& VENC_IRQ_STATUS_FRM
)
393 VDO_HW_WRITE(KVA_VENC_IRQ_ACK_ADDR
, VENC_IRQ_STATUS_FRM
);
398 MFV_LOGE("Invalid lock holder driver type = %d\n", grVcodecEncHWLock
.eDriverType
);
401 eValRet
= eVideoSetEvent(&EncIsrEvent
, sizeof(VAL_EVENT_T
));
402 if(VAL_RESULT_NO_ERROR
!= eValRet
)
404 MFV_LOGE("[MFV][ERROR] ISR set EncIsrEvent error\n");
408 static irqreturn_t
video_intr_dlr(int irq
, void *dev_id
)
414 static irqreturn_t
video_intr_dlr2(int irq
, void *dev_id
)
421 static long vcodec_unlocked_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
424 VAL_UINT8_T
*user_data_addr
;
425 VAL_RESULT_T eValRet
;
426 VAL_UINT32_T ulFlags
, ulFlagsLockHW
;
427 VAL_HW_LOCK_T rHWLock
;
428 VAL_BOOL_T bLockedHW
= VAL_FALSE
;
429 VAL_UINT32_T FirstUseDecHW
= 0;
430 VAL_UINT32_T FirstUseEncHW
= 0;
432 VAL_UINT32_T u4TimeInterval
;
434 VAL_VCODEC_CORE_LOADING_T rTempCoreLoading
;
435 VAL_VCODEC_CPU_OPP_LIMIT_T rCpuOppLimit
;
436 VAL_INT32_T temp_nr_cpu_ids
;
437 VAL_POWER_T rPowerParam
;
439 VCODEC_DRV_CMD_QUEUE_T rDrvCmdQueue
;
440 P_VCODEC_DRV_CMD_T cmd_queue
= VAL_NULL
;
441 VAL_UINT32_T u4Size
, uValue
, nCount
;
445 case VCODEC_SET_THREAD_ID
:
446 MFV_LOGE("[MT8127] VCODEC_SET_THREAD_ID [EMPTY] + tid = %d\n", current
->pid
);
448 MFV_LOGE("[MT8127] VCODEC_SET_THREAD_ID [EMPTY] - tid = %d\n", current
->pid
);
451 case VCODEC_ALLOC_NON_CACHE_BUFFER
:
452 MFV_LOGE("[MT8127][M4U]! VCODEC_ALLOC_NON_CACHE_BUFFER [EMPTY] + tid = %d\n", current
->pid
);
454 MFV_LOGE("[MT8127][M4U]! VCODEC_ALLOC_NON_CACHE_BUFFER [EMPTY] - tid = %d\n", current
->pid
);
457 case VCODEC_FREE_NON_CACHE_BUFFER
:
458 MFV_LOGE("[MT8127][M4U]! VCODEC_FREE_NON_CACHE_BUFFER [EMPTY] + tid = %d\n", current
->pid
);
460 MFV_LOGE("[MT8127][M4U]! VCODEC_FREE_NON_CACHE_BUFFER [EMPTY] - tid = %d\n", current
->pid
);
463 case VCODEC_INC_DEC_EMI_USER
:
464 MFV_LOGD("[MT8127] VCODEC_INC_DEC_EMI_USER + tid = %d\n", current
->pid
);
466 mutex_lock(&DecEMILock
);
468 MFV_LOGE("DEC_EMI_USER = %d\n", gu4DecEMICounter
);
469 user_data_addr
= (VAL_UINT8_T
*)arg
;
470 ret
= copy_to_user(user_data_addr
, &gu4DecEMICounter
, sizeof(VAL_UINT32_T
));
473 MFV_LOGE("[ERROR] VCODEC_INC_DEC_EMI_USER, copy_to_user failed: %d\n", ret
);
474 mutex_unlock(&DecEMILock
);
477 mutex_unlock(&DecEMILock
);
479 MFV_LOGD("[MT8127] VCODEC_INC_DEC_EMI_USER - tid = %d\n", current
->pid
);
482 case VCODEC_DEC_DEC_EMI_USER
:
483 MFV_LOGD("[MT8127] VCODEC_DEC_DEC_EMI_USER + tid = %d\n", current
->pid
);
485 mutex_lock(&DecEMILock
);
487 MFV_LOGE("DEC_EMI_USER = %d\n", gu4DecEMICounter
);
488 user_data_addr
= (VAL_UINT8_T
*)arg
;
489 ret
= copy_to_user(user_data_addr
, &gu4DecEMICounter
, sizeof(VAL_UINT32_T
));
492 MFV_LOGE("[ERROR] VCODEC_DEC_DEC_EMI_USER, copy_to_user failed: %d\n", ret
);
493 mutex_unlock(&DecEMILock
);
496 mutex_unlock(&DecEMILock
);
498 MFV_LOGD("[MT8127] VCODEC_DEC_DEC_EMI_USER - tid = %d\n", current
->pid
);
501 case VCODEC_INC_ENC_EMI_USER
:
502 MFV_LOGD("[MT8127] VCODEC_INC_ENC_EMI_USER + tid = %d\n", current
->pid
);
504 mutex_lock(&EncEMILock
);
506 MFV_LOGE("ENC_EMI_USER = %d\n", gu4EncEMICounter
);
507 user_data_addr
= (VAL_UINT8_T
*)arg
;
508 ret
= copy_to_user(user_data_addr
, &gu4EncEMICounter
, sizeof(VAL_UINT32_T
));
510 MFV_LOGE("[ERROR] VCODEC_INC_ENC_EMI_USER, copy_to_user failed: %d\n", ret
);
511 mutex_unlock(&EncEMILock
);
514 mutex_unlock(&EncEMILock
);
516 MFV_LOGD("[MT8127] VCODEC_INC_ENC_EMI_USER - tid = %d\n", current
->pid
);
519 case VCODEC_DEC_ENC_EMI_USER
:
520 MFV_LOGD("[MT8127] VCODEC_DEC_ENC_EMI_USER + tid = %d\n", current
->pid
);
522 mutex_lock(&EncEMILock
);
524 MFV_LOGE("ENC_EMI_USER = %d\n", gu4EncEMICounter
);
525 user_data_addr
= (VAL_UINT8_T
*)arg
;
526 ret
= copy_to_user(user_data_addr
, &gu4EncEMICounter
, sizeof(VAL_UINT32_T
));
528 MFV_LOGE("[ERROR] VCODEC_DEC_ENC_EMI_USER, copy_to_user failed: %d\n", ret
);
529 mutex_unlock(&EncEMILock
);
532 mutex_unlock(&EncEMILock
);
534 MFV_LOGD("[MT8127] VCODEC_DEC_ENC_EMI_USER - tid = %d\n", current
->pid
);
538 MFV_LOGD("[MT8127] VCODEC_LOCKHW + tid = %d\n", current
->pid
);
539 user_data_addr
= (VAL_UINT8_T
*)arg
;
540 ret
= copy_from_user(&rHWLock
, user_data_addr
, sizeof(VAL_HW_LOCK_T
));
542 MFV_LOGE("[ERROR] VCODEC_LOCKHW, copy_from_user failed: %d\n", ret
);
546 MFV_LOGD("LOCKHW eDriverType = %d\n", rHWLock
.eDriverType
);
547 eValRet
= VAL_RESULT_INVALID_ISR
;
548 if (rHWLock
.eDriverType
== VAL_DRIVER_TYPE_MP4_DEC
||
549 rHWLock
.eDriverType
== VAL_DRIVER_TYPE_HEVC_DEC
||
550 rHWLock
.eDriverType
== VAL_DRIVER_TYPE_H264_DEC
)
552 while (bLockedHW
== VAL_FALSE
)
554 mutex_lock(&DecHWLockEventTimeoutLock
);
555 if (DecHWLockEvent
.u4TimeoutMs
== 1) {
556 MFV_LOGE("[NOT ERROR][VCODEC_LOCKHW] First Use Dec HW!!\n");
562 mutex_unlock(&DecHWLockEventTimeoutLock
);
563 if (FirstUseDecHW
== 1)
565 eValRet
= eVideoWaitEvent(&DecHWLockEvent
, sizeof(VAL_EVENT_T
));
567 mutex_lock(&DecHWLockEventTimeoutLock
);
568 if (DecHWLockEvent
.u4TimeoutMs
!= 1000)
570 DecHWLockEvent
.u4TimeoutMs
= 1000;
577 mutex_unlock(&DecHWLockEventTimeoutLock
);
579 mutex_lock(&VdecHWLock
);
580 // one process try to lock twice
581 if (grVcodecDecHWLock
.pvHandle
== (VAL_VOID_T
*)pmem_user_v2p_video((unsigned int)rHWLock
.pvHandle
)) {
582 MFV_LOGE("[WARNING] one decoder instance try to lock twice, may cause lock HW timeout!! instance = 0x%x, CurrentTID = %d\n",
583 grVcodecDecHWLock
.pvHandle
, current
->pid
);
585 mutex_unlock(&VdecHWLock
);
587 if (FirstUseDecHW
== 0) {
588 MFV_LOGD("Not first time use HW, timeout = %d\n", DecHWLockEvent
.u4TimeoutMs
);
589 eValRet
= eVideoWaitEvent(&DecHWLockEvent
, sizeof(VAL_EVENT_T
));
592 if (VAL_RESULT_INVALID_ISR
== eValRet
) {
593 MFV_LOGE("[ERROR][VCODEC_LOCKHW] DecHWLockEvent TimeOut, CurrentTID = %d\n", current
->pid
);
594 if (FirstUseDecHW
!= 1) {
595 mutex_lock(&VdecHWLock
);
596 if (grVcodecDecHWLock
.pvHandle
== 0) {
597 MFV_LOGE("[WARNING] maybe mediaserver restart before, please check!!\n");
600 MFV_LOGE("[WARNING] someone use HW, and check timeout value!!\n");
602 mutex_unlock(&VdecHWLock
);
605 else if (VAL_RESULT_RESTARTSYS
== eValRet
)
607 MFV_LOGE("[WARNING] VAL_RESULT_RESTARTSYS return when HWLock!!\n");
611 mutex_lock(&VdecHWLock
);
612 if (grVcodecDecHWLock
.pvHandle
== 0) // No one holds dec hw lock now
614 gu4VdecLockThreadId
= current
->pid
;
615 grVcodecDecHWLock
.pvHandle
= (VAL_VOID_T
*)pmem_user_v2p_video((unsigned int)rHWLock
.pvHandle
);
616 grVcodecDecHWLock
.eDriverType
= rHWLock
.eDriverType
;
617 eVideoGetTimeOfDay(&grVcodecDecHWLock
.rLockedTime
, sizeof(VAL_TIME_T
));
619 MFV_LOGD("No process use dec HW, so current process can use HW\n");
620 MFV_LOGD("LockInstance = 0x%x CurrentTID = %d, rLockedTime(s, us) = %d, %d\n",
621 grVcodecDecHWLock
.pvHandle
, current
->pid
, grVcodecDecHWLock
.rLockedTime
.u4Sec
, grVcodecDecHWLock
.rLockedTime
.u4uSec
);
623 bLockedHW
= VAL_TRUE
;
624 if (VAL_RESULT_INVALID_ISR
== eValRet
&& FirstUseDecHW
!= 1) {
625 MFV_LOGE("[WARNING] reset power/irq when HWLock!!\n");
627 disable_irq(MT_VDEC_IRQ_ID
);
630 enable_irq(MT_VDEC_IRQ_ID
);
632 else // Another one holding dec hw now
634 MFV_LOGE("[NOT ERROR][VCODEC_LOCKHW] E\n");
635 eVideoGetTimeOfDay(&rCurTime
, sizeof(VAL_TIME_T
));
636 u4TimeInterval
= (((((rCurTime
.u4Sec
- grVcodecDecHWLock
.rLockedTime
.u4Sec
) * 1000000) + rCurTime
.u4uSec
)
637 - grVcodecDecHWLock
.rLockedTime
.u4uSec
) / 1000);
639 MFV_LOGD("someone use dec HW, and check timeout value\n");
640 MFV_LOGD("Instance = 0x%x CurrentTID = %d, TimeInterval(ms) = %d, TimeOutValue(ms)) = %d\n",
641 grVcodecDecHWLock
.pvHandle
, current
->pid
, u4TimeInterval
, rHWLock
.u4TimeoutMs
);
643 MFV_LOGD("Instance = 0x%x, CurrentTID = %d, rLockedTime(s, us) = %d, %d, rCurTime(s, us) = %d, %d\n",
644 grVcodecDecHWLock
.pvHandle
, current
->pid
,
645 grVcodecDecHWLock
.rLockedTime
.u4Sec
, grVcodecDecHWLock
.rLockedTime
.u4uSec
,
646 rCurTime
.u4Sec
, rCurTime
.u4uSec
649 // 2012/12/16. Cheng-Jung Never steal hardware lock
651 //if (u4TimeInterval >= rHWLock.u4TimeoutMs)
653 grVcodecDecHWLock
.pvHandle
= (VAL_VOID_T
*)pmem_user_v2p_video((unsigned int)rHWLock
.pvHandle
);
654 grVcodecDecHWLock
.eDriverType
= rHWLock
.eDriverType
;
655 eVideoGetTimeOfDay(&grVcodecDecHWLock
.rLockedTime
, sizeof(VAL_TIME_T
));
656 bLockedHW
= VAL_TRUE
;
658 // TODO: Error handling, VDEC break, reset?
661 mutex_unlock(&VdecHWLock
);
662 spin_lock_irqsave(&LockDecHWCountLock
, ulFlagsLockHW
);
664 spin_unlock_irqrestore(&LockDecHWCountLock
, ulFlagsLockHW
);
667 else if (rHWLock
.eDriverType
== VAL_DRIVER_TYPE_H264_ENC
||
668 rHWLock
.eDriverType
== VAL_DRIVER_TYPE_JPEG_ENC
)
670 VAL_UINT32_T u4VencLockTimeOutCount
= 0;
671 while (bLockedHW
== VAL_FALSE
)
673 // Early break for JPEG VENC
674 if (rHWLock
.u4TimeoutMs
== 0)
676 if (grVcodecEncHWLock
.pvHandle
!= 0)
682 // Wait to acquire Enc HW lock
683 mutex_lock(&EncHWLockEventTimeoutLock
);
684 if (EncHWLockEvent
.u4TimeoutMs
== 1) {
685 MFV_LOGE("[NOT ERROR][VCODEC_LOCKHW] First Use Enc HW %d!!\n", rHWLock
.eDriverType
);
691 MFV_LOGD("[VCODEC_LOCKHW] ENC Use Enc HW %d,line %d!!\n", rHWLock
.eDriverType
,__LINE__
);
692 mutex_unlock(&EncHWLockEventTimeoutLock
);
693 if (FirstUseEncHW
== 1)
695 eValRet
= eVideoWaitEvent(&EncHWLockEvent
, sizeof(VAL_EVENT_T
));
696 MFV_LOGD("[VCODEC_LOCKHW] [%d] Use Enc HW, wait event 1, ret[%d]!!\n", rHWLock
.eDriverType
,eValRet
);
698 //MFV_LOGD("[VCODEC_LOCKHW] ENC Use Enc HW %d,line %d!!\n", rHWLock.eDriverType,__LINE__);
700 mutex_lock(&EncHWLockEventTimeoutLock
);
701 //MFV_LOGD("[VCODEC_LOCKHW] ENC Use Enc HW %d,line %d!!\n", rHWLock.eDriverType,__LINE__);
703 if (EncHWLockEvent
.u4TimeoutMs
== 1)
705 EncHWLockEvent
.u4TimeoutMs
= 1000;
711 if (rHWLock
.u4TimeoutMs
== 0)
713 EncHWLockEvent
.u4TimeoutMs
= 0; // No wait
717 EncHWLockEvent
.u4TimeoutMs
= 1000; // Wait indefinitely
720 //MFV_LOGD("[VCODEC_LOCKHW] LOCK hW Enc HW %d,line %d!!\n", rHWLock.eDriverType,__LINE__);
722 mutex_unlock(&EncHWLockEventTimeoutLock
);
723 //MFV_LOGD("[VCODEC_LOCKHW] LOCK hW Enc HW %d,line %d!!\n", rHWLock.eDriverType,__LINE__);
725 mutex_lock(&VencHWLock
);
726 // one process try to lock twice
727 if (grVcodecEncHWLock
.pvHandle
== (VAL_VOID_T
*)pmem_user_v2p_video((unsigned int)rHWLock
.pvHandle
)) {
728 MFV_LOGE("[WARNING] [VCODEC_LOCKHW] one encoder instance try to lock twice, may cause lock HW timeout!! instance = 0x%x, CurrentTID = %d, type:%d\n",
729 grVcodecEncHWLock
.pvHandle
, current
->pid
, rHWLock
.eDriverType
);
731 //MFV_LOGD("[VCODEC_LOCKHW] LOCK hW Enc HW %d,line %d!!\n", rHWLock.eDriverType,__LINE__);
733 mutex_unlock(&VencHWLock
);
734 //MFV_LOGD("[VCODEC_LOCKHW] First[%d] Use Enc HW %d,line %d!!\n", FirstUseEncHW,rHWLock.eDriverType,__LINE__);
736 if (FirstUseEncHW
== 0) {
737 eValRet
= eVideoWaitEvent(&EncHWLockEvent
, sizeof(VAL_EVENT_T
));
738 MFV_LOGD("[VCODEC_LOCKHW] [%d] Use Enc HW, wait[%d] event 2, ret[%d]!!\n", rHWLock
.eDriverType
, EncHWLockEvent
.u4TimeoutMs
, eValRet
);
740 MFV_LOGD("[VCODEC_LOCKHW] LOCK hW Enc HW %d,line %d!!\n", rHWLock
.eDriverType
,__LINE__
);
742 if (VAL_RESULT_INVALID_ISR
== eValRet
) {
743 MFV_LOGE("[ERROR][VCODEC_LOCKHW] First[%d] TimeOut, CurrentTID = %d,line %d\n", FirstUseEncHW
, current
->pid
, __LINE__
);
744 if (FirstUseEncHW
!= 1) {
745 mutex_lock(&VencHWLock
);
746 if (grVcodecEncHWLock
.pvHandle
== 0) {
747 MFV_LOGE("[WARNING] VCODEC_LOCKHW maybe mediaserver restart before, please check!!\n");
750 MFV_LOGE("[WARNING] VCODEC_LOCKHW someone use HW, and check timeout value!! %d\n", u4VencLockTimeOutCount
);
751 ++u4VencLockTimeOutCount
;
752 if (u4VencLockTimeOutCount
> 30)
754 MFV_LOGE("VCODEC_LOCKHW - ID %d fail, someone locked HW time out more than 30 times %x, %x, %x, type:%d\n", current
->pid
, grVcodecEncHWLock
.pvHandle
, pmem_user_v2p_video((unsigned int)rHWLock
.pvHandle
), rHWLock
.pvHandle
, rHWLock
.eDriverType
);
755 mutex_unlock(&VencHWLock
);
759 if (rHWLock
.u4TimeoutMs
== 0)
761 MFV_LOGE("VCODEC_LOCKHW - ID %d fail, someone locked HW already %x, %x, %x, type:%d\n", current
->pid
, grVcodecEncHWLock
.pvHandle
, pmem_user_v2p_video((unsigned int)rHWLock
.pvHandle
), rHWLock
.pvHandle
, rHWLock
.eDriverType
);
762 mutex_unlock(&VencHWLock
);
766 mutex_unlock(&VencHWLock
);
769 else if (VAL_RESULT_RESTARTSYS
== eValRet
)
771 MFV_LOGD("[ERROR][VCODEC_LOCKHW] VAL_RESULT_RESTARTSYS Enc HW %d,line %d!!\n", rHWLock
.eDriverType
,__LINE__
);
774 //MFV_LOGD("[VCODEC_LOCKHW] LOCK hW Use Enc HW %d,line %d!!\n", rHWLock.eDriverType,__LINE__);
776 mutex_lock(&VencHWLock
);
777 MFV_LOGD("[VCODEC_LOCKHW] LOCK hW Use Enc HW %d,line %d!!\n", rHWLock
.eDriverType
,__LINE__
);
779 if (grVcodecEncHWLock
.pvHandle
== 0) //No process use HW, so current process can use HW
781 //MFV_LOGD("[VCODEC_LOCKHW] LOCK hW Use Enc HW %d,line %d!!\n", rHWLock.eDriverType,__LINE__);
783 if (rHWLock
.eDriverType
== VAL_DRIVER_TYPE_H264_ENC
||
784 rHWLock
.eDriverType
== VAL_DRIVER_TYPE_JPEG_ENC
)
786 grVcodecEncHWLock
.pvHandle
= (VAL_VOID_T
*)pmem_user_v2p_video((unsigned int)rHWLock
.pvHandle
);
787 MFV_LOGD("[VCODEC_LOCKHW] No process use HW, so current process can use HW, handle = 0x%x\n", grVcodecEncHWLock
.pvHandle
);
788 grVcodecEncHWLock
.eDriverType
= rHWLock
.eDriverType
;
789 eVideoGetTimeOfDay(&grVcodecEncHWLock
.rLockedTime
, sizeof(VAL_TIME_T
));
791 MFV_LOGD("VCODEC_LOCKHW No process use HW, so current process can use HW\n");
792 MFV_LOGD("VCODEC_LOCKHW LockInstance = 0x%x CurrentTID = %d, rLockedTime(s, us) = %d, %d\n",
793 grVcodecEncHWLock
.pvHandle
, current
->pid
, grVcodecEncHWLock
.rLockedTime
.u4Sec
, grVcodecEncHWLock
.rLockedTime
.u4uSec
);
795 bLockedHW
= VAL_TRUE
;
796 if (rHWLock
.eDriverType
== VAL_DRIVER_TYPE_H264_ENC
)
800 #ifdef MTK_SEC_VIDEO_PATH_SUPPORT
801 MFV_LOGD("[VCODEC_LOCKHW] rHWLock.bSecureInst 0x%x\n", rHWLock
.bSecureInst
);
802 if (rHWLock
.bSecureInst
== VAL_FALSE
)
804 MFV_LOGE("[VCODEC_LOCKHW] Request IR by type 0x%x\n", rHWLock
.eDriverType
);
805 if (request_irq(MT_VENC_IRQ_ID
, (irq_handler_t
)video_intr_dlr2
, IRQF_TRIGGER_LOW
, VCODEC_DEVNAME
, NULL
) < 0)
807 MFV_LOGE("[VCODEC_LOCKHW] ENC [MFV_DEBUG][ERROR] error to request enc irq\n");
811 MFV_LOGD("[VCODEC_LOCKHW] ENC [MFV_DEBUG] success to request enc irq\n");
813 //enable_irq(MT_VDEC_IRQ_ID);
816 if (rHWLock
.eDriverType
== VAL_DRIVER_TYPE_H264_ENC
)
819 enable_irq(MT_VENC_IRQ_ID
);
823 MFV_LOGD("[VCODEC_LOCKHW] LOCK hW Enc HW %d,line %d!!\n", rHWLock
.eDriverType
,__LINE__
);
826 else //someone use HW, and check timeout value
828 MFV_LOGD("[VCODEC_LOCKHW] LOCK hW Enc HW %d,line %d!!\n", rHWLock
.eDriverType
,__LINE__
);
830 if (rHWLock
.u4TimeoutMs
== 0)
832 bLockedHW
= VAL_FALSE
;
833 mutex_unlock(&VencHWLock
);
837 eVideoGetTimeOfDay(&rCurTime
, sizeof(VAL_TIME_T
));
838 u4TimeInterval
= (((((rCurTime
.u4Sec
- grVcodecEncHWLock
.rLockedTime
.u4Sec
) * 1000000) + rCurTime
.u4uSec
)
839 - grVcodecEncHWLock
.rLockedTime
.u4uSec
) / 1000);
841 MFV_LOGD("VCODEC_LOCKHW someone use enc HW, and check timeout value\n");
842 MFV_LOGD("VCODEC_LOCKHW LockInstance = 0x%x, CurrentInstance = 0x%x, CurrentTID = %d, TimeInterval(ms) = %d, TimeOutValue(ms)) = %d\n",
843 grVcodecEncHWLock
.pvHandle
, pmem_user_v2p_video((unsigned int)rHWLock
.pvHandle
), current
->pid
, u4TimeInterval
, rHWLock
.u4TimeoutMs
);
845 MFV_LOGD("VCODEC_LOCKHW LockInstance = 0x%x, CurrentInstance = 0x%x, CurrentTID = %d, rLockedTime(s, us) = %d, %d, rCurTime(s, us) = %d, %d\n",
846 grVcodecEncHWLock
.pvHandle
, pmem_user_v2p_video((unsigned int)rHWLock
.pvHandle
), current
->pid
,
847 grVcodecEncHWLock
.rLockedTime
.u4Sec
, grVcodecEncHWLock
.rLockedTime
.u4uSec
,
848 rCurTime
.u4Sec
, rCurTime
.u4uSec
851 // 2013/04/10. Cheng-Jung Never steal hardware lock
853 //if (u4TimeInterval >= rHWLock.u4TimeoutMs)
855 if (rHWLock
.eDriverType
== VAL_DRIVER_TYPE_H264_ENC
||
856 rHWLock
.eDriverType
== VAL_DRIVER_TYPE_JPEG_ENC
)
858 grVcodecEncHWLock
.pvHandle
= (VAL_VOID_T
*)pmem_user_v2p_video((unsigned int)rHWLock
.pvHandle
);
859 grVcodecEncHWLock
.eDriverType
= rHWLock
.eDriverType
;
860 eVideoGetTimeOfDay(&grVcodecEncHWLock
.rLockedTime
, sizeof(VAL_TIME_T
));
862 MFV_LOGD(" VCODEC_LOCKHW LockInstance = 0x%x, CurrentTID = %d, rLockedTime(s, us) = %d, %d\n",
863 grVcodecEncHWLock
.pvHandle
, current
->pid
, grVcodecEncHWLock
.rLockedTime
.u4Sec
, grVcodecEncHWLock
.rLockedTime
.u4uSec
);
865 bLockedHW
= VAL_TRUE
;
866 if (rHWLock
.eDriverType
== VAL_DRIVER_TYPE_H264_ENC
)
874 if (VAL_TRUE
== bLockedHW
)
876 MFV_LOGE(" VCODEC_LOCKHW Lock ok grVcodecEncHWLock.pvHandle = 0x%x, va:%x, type:%d", grVcodecEncHWLock
.pvHandle
, (unsigned int)rHWLock
.pvHandle
, rHWLock
.eDriverType
);
878 mutex_unlock(&VencHWLock
);
881 if (VAL_FALSE
== bLockedHW
)
883 MFV_LOGE("VCODEC_LOCKHW - ID %d fail, someone locked HW already , %x, %x, %x, type:%d\n", current
->pid
, grVcodecEncHWLock
.pvHandle
, pmem_user_v2p_video((unsigned int)rHWLock
.pvHandle
), rHWLock
.pvHandle
, rHWLock
.eDriverType
);
887 spin_lock_irqsave(&LockEncHWCountLock
, ulFlagsLockHW
);
889 spin_unlock_irqrestore(&LockEncHWCountLock
, ulFlagsLockHW
);
891 MFV_LOGD("VCODEC_LOCKHW get locked - ObjId =%d\n", current
->pid
);
893 MFV_LOGD("VCODEC_LOCKHW - tid = %d\n", current
->pid
);
897 MFV_LOGE("[WARNING] VCODEC_LOCKHW Unknown instance\n");
900 MFV_LOGD("VCODEC_LOCKHW - tid = %d\n", current
->pid
);
903 case VCODEC_UNLOCKHW
:
904 MFV_LOGD("VCODEC_UNLOCKHW + tid = %d\n", current
->pid
);
905 user_data_addr
= (VAL_UINT8_T
*)arg
;
906 ret
= copy_from_user(&rHWLock
, user_data_addr
, sizeof(VAL_HW_LOCK_T
));
908 MFV_LOGE("[ERROR] VCODEC_UNLOCKHW, copy_from_user failed: %d\n", ret
);
912 MFV_LOGD("VCODEC_UNLOCKHW eDriverType = %d\n", rHWLock
.eDriverType
);
913 eValRet
= VAL_RESULT_INVALID_ISR
;
914 if (rHWLock
.eDriverType
== VAL_DRIVER_TYPE_MP4_DEC
||
915 rHWLock
.eDriverType
== VAL_DRIVER_TYPE_HEVC_DEC
||
916 rHWLock
.eDriverType
== VAL_DRIVER_TYPE_H264_DEC
)
918 mutex_lock(&VdecHWLock
);
919 if (grVcodecDecHWLock
.pvHandle
== (VAL_VOID_T
*)pmem_user_v2p_video((unsigned int)rHWLock
.pvHandle
)) // Current owner give up hw lock
921 grVcodecDecHWLock
.pvHandle
= 0;
922 grVcodecDecHWLock
.eDriverType
= VAL_DRIVER_TYPE_NONE
;
923 disable_irq(MT_VDEC_IRQ_ID
);
924 // TODO: check if turning power off is ok
927 else // Not current owner
929 MFV_LOGD(" [ERROR] VCODEC_UNLOCKHW Not owner trying to unlock dec hardware 0x%x\n", pmem_user_v2p_video((unsigned int)rHWLock
.pvHandle
));
930 mutex_unlock(&VdecHWLock
);
933 mutex_unlock(&VdecHWLock
);
934 eValRet
= eVideoSetEvent(&DecHWLockEvent
, sizeof(VAL_EVENT_T
));
936 else if (rHWLock
.eDriverType
== VAL_DRIVER_TYPE_H264_ENC
||
937 rHWLock
.eDriverType
== VAL_DRIVER_TYPE_JPEG_ENC
)
939 mutex_lock(&VencHWLock
);
940 if (grVcodecEncHWLock
.pvHandle
== (VAL_VOID_T
*)pmem_user_v2p_video((unsigned int)rHWLock
.pvHandle
)) // Current owner give up hw lock
942 MFV_LOGD("VCODEC_UNLOCKHW match handle\n");
943 grVcodecEncHWLock
.pvHandle
= 0;
944 grVcodecEncHWLock
.eDriverType
= VAL_DRIVER_TYPE_NONE
;
945 #ifdef MTK_SEC_VIDEO_PATH_SUPPORT
946 if (rHWLock
.eDriverType
== VAL_DRIVER_TYPE_H264_ENC
)
948 if (rHWLock
.bSecureInst
== VAL_FALSE
)
950 free_irq(MT_VENC_IRQ_ID
, NULL
);
955 if (rHWLock
.eDriverType
== VAL_DRIVER_TYPE_H264_ENC
)
957 disable_irq(MT_VENC_IRQ_ID
);
958 // turn venc power off
963 else // Not current owner
965 // [TODO] error handling
966 MFV_LOGE("[ERROR] VCODEC_UNLOCKHW Not owner trying to unlock enc hardware 0x%x, pa:%x, va:%x type:%d\n", grVcodecEncHWLock
.pvHandle
, pmem_user_v2p_video((unsigned int)rHWLock
.pvHandle
), (unsigned int)rHWLock
.pvHandle
, rHWLock
.eDriverType
);
967 mutex_unlock(&VencHWLock
);
970 mutex_unlock(&VencHWLock
);
972 eValRet
= eVideoSetEvent(&EncHWLockEvent
, sizeof(VAL_EVENT_T
));
973 MFV_LOGE("VCODEC_UNLOCKHW ENC Set event ret %d\n", eValRet
);
977 MFV_LOGE("[WARNING] VCODEC_UNLOCKHW Unknown instance\n");
980 MFV_LOGD("VCODEC_UNLOCKHW - tid = %d\n", current
->pid
);
983 case VCODEC_INC_PWR_USER
:
984 MFV_LOGD("[MT8127] VCODEC_INC_PWR_USER + tid = %d\n", current
->pid
);
985 user_data_addr
= (VAL_UINT8_T
*)arg
;
986 ret
= copy_from_user(&rPowerParam
, user_data_addr
, sizeof(VAL_POWER_T
));
988 MFV_LOGE("[ERROR] VCODEC_INC_PWR_USER, copy_from_user failed: %d\n", ret
);
991 MFV_LOGD("INC_PWR_USER eDriverType = %d\n", rPowerParam
.eDriverType
);
992 mutex_lock(&L2CLock
);
993 if (rPowerParam
.eDriverType
== VAL_DRIVER_TYPE_H264_DEC
||
994 rPowerParam
.eDriverType
== VAL_DRIVER_TYPE_HEVC_DEC
||
995 rPowerParam
.eDriverType
== VAL_DRIVER_TYPE_MP4_DEC
)
998 MFV_LOGD("INC_PWR_USER L2C counter = %d\n", gu4L2CCounter
);
1001 if (1 == gu4L2CCounter
)
1003 if (config_L2(SZ_256K
))
1005 MFV_LOGE("[MFV][ERROR] Switch L2C size to 256K failed\n");
1006 mutex_unlock(&L2CLock
);
1011 MFV_LOGD("[MFV][ERROR] Switch L2C size to 256K successful\n");
1015 mutex_unlock(&L2CLock
);
1017 MFV_LOGD("[MT8127] VCODEC_INC_PWR_USER - tid = %d\n", current
->pid
);
1020 case VCODEC_DEC_PWR_USER
:
1021 MFV_LOGD("[MT8127] VCODEC_DEC_PWR_USER + tid = %d\n", current
->pid
);
1022 user_data_addr
= (VAL_UINT8_T
*)arg
;
1023 ret
= copy_from_user(&rPowerParam
, user_data_addr
, sizeof(VAL_POWER_T
));
1025 MFV_LOGE("[ERROR] VCODEC_DEC_PWR_USER, copy_from_user failed: %d\n", ret
);
1028 MFV_LOGD("DEC_PWR_USER eDriverType = %d\n", rPowerParam
.eDriverType
);
1030 mutex_lock(&L2CLock
);
1031 if (rPowerParam
.eDriverType
== VAL_DRIVER_TYPE_H264_DEC
||
1032 rPowerParam
.eDriverType
== VAL_DRIVER_TYPE_HEVC_DEC
||
1033 rPowerParam
.eDriverType
== VAL_DRIVER_TYPE_MP4_DEC
)
1036 MFV_LOGD("DEC_PWR_USER L2C counter = %d\n", gu4L2CCounter
);
1039 if (0 == gu4L2CCounter
)
1041 if (config_L2(SZ_512K
))
1043 MFV_LOGE("[MFV][ERROR] Switch L2C size to 512K failed\n");
1044 mutex_unlock(&L2CLock
);
1049 MFV_LOGD("[MFV][ERROR] Switch L2C size to 512K successful\n");
1053 mutex_unlock(&L2CLock
);
1054 MFV_LOGD("[MT8127] VCODEC_DEC_PWR_USER - tid = %d\n", current
->pid
);
1057 case VCODEC_WAITISR
:
1059 MFV_LOGD("[MT8127] VCODEC_WAITISR + tid = %d\n", current
->pid
);
1060 user_data_addr
= (VAL_UINT8_T
*)arg
;
1061 ret
= copy_from_user(&val_isr
, user_data_addr
, sizeof(VAL_ISR_T
));
1063 MFV_LOGE("[ERROR] VCODEC_WAITISR, copy_from_user failed: %d\n", ret
);
1067 if (val_isr
.eDriverType
== VAL_DRIVER_TYPE_MP4_DEC
||
1068 val_isr
.eDriverType
== VAL_DRIVER_TYPE_HEVC_DEC
||
1069 val_isr
.eDriverType
== VAL_DRIVER_TYPE_H264_DEC
)
1071 mutex_lock(&VdecHWLock
);
1072 if (grVcodecDecHWLock
.pvHandle
== (VAL_VOID_T
*)pmem_user_v2p_video((unsigned int)val_isr
.pvHandle
))
1074 bLockedHW
= VAL_TRUE
;
1079 mutex_unlock(&VdecHWLock
);
1081 if (bLockedHW
== VAL_FALSE
)
1083 MFV_LOGE("[ERROR] DO NOT have HWLock, so return fail\n");
1087 spin_lock_irqsave(&DecIsrLock
, ulFlags
);
1088 DecIsrEvent
.u4TimeoutMs
= val_isr
.u4TimeoutMs
;
1089 spin_unlock_irqrestore(&DecIsrLock
, ulFlags
);
1091 eValRet
= eVideoWaitEvent(&DecIsrEvent
, sizeof(VAL_EVENT_T
));
1092 if(VAL_RESULT_INVALID_ISR
== eValRet
)
1096 else if (VAL_RESULT_RESTARTSYS
== eValRet
)
1098 MFV_LOGE("[WARNING] VAL_RESULT_RESTARTSYS return when WAITISR!!\n");
1099 return -ERESTARTSYS
;
1102 else if (val_isr
.eDriverType
== VAL_DRIVER_TYPE_H264_ENC
)
1104 mutex_lock(&VencHWLock
);
1105 if (grVcodecEncHWLock
.pvHandle
== (VAL_VOID_T
*)pmem_user_v2p_video((unsigned int)val_isr
.pvHandle
))
1107 bLockedHW
= VAL_TRUE
;
1112 mutex_unlock(&VencHWLock
);
1114 if (bLockedHW
== VAL_FALSE
)
1116 MFV_LOGE("[ERROR] DO NOT have enc HWLock, so return fail pa:%x, va:%x\n", pmem_user_v2p_video((unsigned int)val_isr
.pvHandle
), val_isr
.pvHandle
);
1120 spin_lock_irqsave(&EncIsrLock
, ulFlags
);
1121 EncIsrEvent
.u4TimeoutMs
= val_isr
.u4TimeoutMs
;
1122 spin_unlock_irqrestore(&EncIsrLock
, ulFlags
);
1124 eValRet
= eVideoWaitEvent(&EncIsrEvent
, sizeof(VAL_EVENT_T
));
1125 if(VAL_RESULT_INVALID_ISR
== eValRet
)
1129 else if (VAL_RESULT_RESTARTSYS
== eValRet
)
1131 MFV_LOGE("[WARNING] VAL_RESULT_RESTARTSYS return when WAITISR!!\n");
1132 return -ERESTARTSYS
;
1135 if (val_isr
.u4IrqStatusNum
> 0)
1137 val_isr
.u4IrqStatus
[0] = gu4HwVencIrqStatus
;
1138 ret
= copy_to_user(user_data_addr
, &val_isr
, sizeof(VAL_ISR_T
));
1140 MFV_LOGE("[ERROR] VCODEC_WAITISR, copy_to_user failed: %d\n", ret
);
1147 MFV_LOGE("[WARNING] VCODEC_WAITISR Unknown instance\n");
1150 MFV_LOGD("[MT8127] VCODEC_WAITISR - tid = %d\n", current
->pid
);
1153 case VCODEC_INITHWLOCK
:
1155 MFV_LOGE("[MT8127] VCODEC_INITHWLOCK [EMPTY] + - tid = %d\n", current
->pid
);
1157 MFV_LOGE("[MT8127] VCODEC_INITHWLOCK [EMPTY] - - tid = %d\n", current
->pid
);
1161 case VCODEC_DEINITHWLOCK
:
1163 MFV_LOGE("[MT8127] VCODEC_DEINITHWLOCK [EMPTY] + - tid = %d\n", current
->pid
);
1165 MFV_LOGE("[MT8127] VCODEC_DEINITHWLOCK [EMPTY] - - tid = %d\n", current
->pid
);
1169 case VCODEC_GET_CPU_LOADING_INFO
:
1171 VAL_UINT8_T
*user_data_addr
, cpu_id
;
1172 VAL_VCODEC_CPU_LOADING_INFO_T _temp
;
1174 MFV_LOGD("[MT8127] VCODEC_GET_CPU_LOADING_INFO +\n");
1175 user_data_addr
= (VAL_UINT8_T
*)arg
;
1177 #if 1 // Morris Yang update for multi-core
1178 //MFV_LOGE("[MT8127] VCODEC_GET_CPU_LOADING_INFO num_possible_cpus(%d)\n", num_possible_cpus());
1179 for (cpu_id
= 0 ; cpu_id
< num_possible_cpus() ; cpu_id
++) {
1180 _temp
._cpu_idle_time
+= mt_get_cpu_idle(cpu_id
);
1181 _temp
._thread_cpu_time
+= mt_get_thread_cputime(cpu_id
);
1183 //spin_lock_irqsave(&OalHWContextLock, ulFlags);
1184 //_temp._inst_count = getCurInstanceCount();
1185 //spin_unlock_irqrestore(&OalHWContextLock, ulFlags);
1186 _temp
._sched_clock
= mt_sched_clock();
1188 ret
= copy_to_user(user_data_addr
, &_temp
, sizeof(VAL_VCODEC_CPU_LOADING_INFO_T
));
1190 MFV_LOGE("[ERROR] VCODEC_GET_CPU_LOADING_INFO, copy_to_user failed: %d\n", ret
);
1194 MFV_LOGD("[MT8127] VCODEC_GET_CPU_LOADING_INFO -\n");
1198 case VCODEC_GET_CORE_LOADING
:
1200 MFV_LOGD("[MT8127] VCODEC_GET_CORE_LOADING + - tid = %d\n", current
->pid
);
1202 user_data_addr
= (VAL_UINT8_T
*)arg
;
1203 ret
= copy_from_user(&rTempCoreLoading
, user_data_addr
, sizeof(VAL_VCODEC_CORE_LOADING_T
));
1206 MFV_LOGE("[ERROR] VCODEC_GET_CORE_LOADING, copy_from_user failed: %d\n", ret
);
1209 rTempCoreLoading
.Loading
= get_cpu_load(rTempCoreLoading
.CPUid
);
1210 ret
= copy_to_user(user_data_addr
, &rTempCoreLoading
, sizeof(VAL_VCODEC_CORE_LOADING_T
));
1212 MFV_LOGE("[ERROR] VCODEC_GET_CORE_LOADING, copy_to_user failed: %d\n", ret
);
1216 MFV_LOGD("[MT8127] VCODEC_GET_CORE_LOADING - - tid = %d\n", current
->pid
);
1220 case VCODEC_GET_CORE_NUMBER
:
1222 MFV_LOGD("[MT8127] VCODEC_GET_CORE_NUMBER + - tid = %d\n", current
->pid
);
1224 user_data_addr
= (VAL_UINT8_T
*)arg
;
1225 temp_nr_cpu_ids
= nr_cpu_ids
;
1226 ret
= copy_to_user(user_data_addr
, &temp_nr_cpu_ids
, sizeof(int));
1228 MFV_LOGE("[ERROR] VCODEC_GET_CORE_NUMBER, copy_to_user failed: %d\n", ret
);
1231 MFV_LOGD("[MT8127] VCODEC_GET_CORE_NUMBER - - tid = %d\n", current
->pid
);
1234 case VCODEC_SET_CPU_OPP_LIMIT
:
1235 MFV_LOGE("[MT8127] VCODEC_SET_CPU_OPP_LIMIT [EMPTY] + - tid = %d\n", current
->pid
);
1236 user_data_addr
= (VAL_UINT8_T
*)arg
;
1237 ret
= copy_from_user(&rCpuOppLimit
, user_data_addr
, sizeof(VAL_VCODEC_CPU_OPP_LIMIT_T
));
1239 MFV_LOGE("[ERROR] VCODEC_SET_CPU_OPP_LIMIT, copy_from_user failed: %d\n", ret
);
1242 MFV_LOGE("+VCODEC_SET_CPU_OPP_LIMIT (%d, %d, %d), tid = %d\n", rCpuOppLimit
.limited_freq
, rCpuOppLimit
.limited_cpu
, rCpuOppLimit
.enable
, current
->pid
);
1243 // TODO: Check if cpu_opp_limit is available
1244 //ret = cpu_opp_limit(EVENT_VIDEO, rCpuOppLimit.limited_freq, rCpuOppLimit.limited_cpu, rCpuOppLimit.enable); // 0: PASS, other: FAIL
1246 MFV_LOGE("[ERROR] cpu_opp_limit failed: %d\n", ret
);
1249 MFV_LOGE("-VCODEC_SET_CPU_OPP_LIMIT tid = %d, ret = %d\n", current
->pid
, ret
);
1250 MFV_LOGE("[MT8127] VCODEC_SET_CPU_OPP_LIMIT [EMPTY] - - tid = %d\n", current
->pid
);
1256 case MFV_SET_CMD_CMD
:
1257 MFV_LOGD("[MFV] MFV_SET_CMD_CMD\n");
1258 MFV_LOGD("[MFV] Arg = %x\n",arg
);
1259 user_data_addr
= (VAL_UINT8_T
*)arg
;
1260 ret
= copy_from_user(&rDrvCmdQueue
, user_data_addr
, sizeof(VCODEC_DRV_CMD_QUEUE_T
));
1261 MFV_LOGD("[MFV] CmdNum = %d\n",rDrvCmdQueue
.CmdNum
);
1262 u4Size
= (rDrvCmdQueue
.CmdNum
)*sizeof(VCODEC_DRV_CMD_T
);
1264 cmd_queue
= (P_VCODEC_DRV_CMD_T
)kmalloc(u4Size
,GFP_ATOMIC
);
1265 if (cmd_queue
!= VAL_NULL
&& rDrvCmdQueue
.pCmd
!= VAL_NULL
) {
1266 ret
= copy_from_user(cmd_queue
, rDrvCmdQueue
.pCmd
, u4Size
);
1267 while (cmd_queue
->type
!= END_CMD
) {
1268 switch (cmd_queue
->type
)
1272 case DISABLE_HW_CMD
:
1275 VDO_HW_WRITE(cmd_queue
->address
+ cmd_queue
->offset
, cmd_queue
->value
);
1278 uValue
= VDO_HW_READ(cmd_queue
->address
+ cmd_queue
->offset
);
1279 copy_to_user((void *)cmd_queue
->value
, &uValue
, sizeof(VAL_UINT32_T
));
1281 case WRITE_SYSRAM_CMD
:
1282 VDO_HW_WRITE(cmd_queue
->address
+ cmd_queue
->offset
, cmd_queue
->value
);
1284 case READ_SYSRAM_CMD
:
1285 uValue
= VDO_HW_READ(cmd_queue
->address
+ cmd_queue
->offset
);
1286 copy_to_user((void *)cmd_queue
->value
, &uValue
, sizeof(VAL_UINT32_T
));
1288 case MASTER_WRITE_CMD
:
1289 uValue
= VDO_HW_READ(cmd_queue
->address
+ cmd_queue
->offset
);
1290 VDO_HW_WRITE(cmd_queue
->address
+ cmd_queue
->offset
, cmd_queue
->value
| (uValue
& cmd_queue
->mask
));
1295 MFV_LOGD("HAL_CMD_SET_CMD_QUEUE: WAIT_ISR_CMD+\n");
1297 MFV_LOGD("HAL_CMD_SET_CMD_QUEUE: WAIT_ISR_CMD-\n");
1301 case WRITE_SYSRAM_RANGE_CMD
:
1303 case READ_SYSRAM_RANGE_CMD
:
1305 case POLL_REG_STATUS_CMD
:
1306 uValue
= VDO_HW_READ(cmd_queue
->address
+ cmd_queue
->offset
);
1308 while ((uValue
& cmd_queue
->mask
) != 0) {
1310 if (nCount
> 1000) {
1313 uValue
= VDO_HW_READ(cmd_queue
->address
+ cmd_queue
->offset
);
1326 MFV_LOGE("========[ERROR] vcodec_ioctl default case======== %u\n", cmd
);
1332 static int vcodec_open(struct inode
*inode
, struct file
*file
)
1334 MFV_LOGD("[VCODEC_DEBUG] vcodec_open\n");
1336 mutex_lock(&DriverOpenCountLock
);
1337 MT8127Driver_Open_Count
++;
1339 MFV_LOGE("vcodec_open pid = %d, MT8127Driver_Open_Count %d\n", current
->pid
, MT8127Driver_Open_Count
);
1340 mutex_unlock(&DriverOpenCountLock
);
1343 // TODO: Check upper limit of concurrent users?
1348 static int venc_hw_reset(int type
)
1350 VAL_UINT32_T uValue
;
1351 VAL_RESULT_T eValRet
;
1352 MFV_LOGE("Start VENC HW Reset");
1355 //EncIsrEvent.u4TimeoutMs = 1;
1356 //eValRet = eVideoWaitEvent(&EncIsrEvent, sizeof(VAL_EVENT_T));
1357 //MFV_LOGE("ret %d", eValRet);
1358 //if type == 0//Soft Reset
1360 VDO_HW_WRITE(KVA_VENC_SW_PAUSE
, 1);
1362 //EncIsrEvent.u4TimeoutMs = 10000;
1363 EncIsrEvent
.u4TimeoutMs
= 2;
1364 eValRet
= eVideoWaitEvent(&EncIsrEvent
, sizeof(VAL_EVENT_T
));
1365 if(VAL_RESULT_INVALID_ISR
== eValRet
|| gu4HwVencIrqStatus
!= VENC_IRQ_STATUS_PAUSE
)//timeout or don't get pasue
1367 uValue
= VDO_HW_READ(KVA_VENC_IRQ_STATUS_ADDR
);
1368 if (gu4HwVencIrqStatus
!= VENC_IRQ_STATUS_PAUSE
)
1372 MFV_LOGE("irq_status 0x%x", uValue
);
1373 VDO_HW_WRITE(KVA_VENC_SW_PAUSE
, 0);
1374 VDO_HW_WRITE(KVA_VENC_SW_HRST_N
, 0);
1375 uValue
= VDO_HW_READ(KVA_VENC_SW_HRST_N
);
1376 MFV_LOGE("3 HRST = %d, isr = 0x%x", uValue
, gu4HwVencIrqStatus
);
1380 VDO_HW_WRITE(KVA_VENC_SW_HRST_N
, 0);
1381 uValue
= gu4HwVencIrqStatus
;
1382 VDO_HW_WRITE(KVA_VENC_SW_PAUSE
, 0);
1383 MFV_LOGE("4 HRST = %d, isr = 0x%x", uValue
, gu4HwVencIrqStatus
);
1386 VDO_HW_WRITE(KVA_VENC_SW_HRST_N
, 1);
1387 uValue
= VDO_HW_READ(KVA_VENC_SW_HRST_N
);
1388 MFV_LOGE("HRST = %d", uValue
);
1393 static int vcodec_flush(struct file
*file
, fl_owner_t id
)
1395 MFV_LOGD("[VCODEC_DEBUG] vcodec_flush, curr_tid =%d\n", current
->pid
);
1396 MFV_LOGE("vcodec_flush pid = %d, MT8127Driver_Open_Count %d\n", current
->pid
, MT8127Driver_Open_Count
);
1401 static int vcodec_release(struct inode
*inode
, struct file
*file
)
1403 unsigned long ulFlagsLockHW
, ulFlagsISR
;
1406 MFV_LOGD("[VCODEC_DEBUG] vcodec_release, curr_tid =%d\n", current
->pid
);
1407 mutex_lock(&DriverOpenCountLock
);
1408 MFV_LOGE("vcodec_release pid = %d, MT8127Driver_Open_Count %d\n", current
->pid
, MT8127Driver_Open_Count
);
1410 MT8127Driver_Open_Count
--;
1412 if (MT8127Driver_Open_Count
== 0) {
1414 mutex_lock(&VdecHWLock
);
1415 if (grVcodecEncHWLock
.eDriverType
== VAL_DRIVER_TYPE_H264_ENC
)
1418 disable_irq(MT_VENC_IRQ_ID
);
1420 MFV_LOGE("Clean venc lock\n");
1422 mutex_unlock(&VdecHWLock
);
1424 mutex_lock(&VdecHWLock
);
1425 gu4VdecLockThreadId
= 0;
1426 grVcodecDecHWLock
.pvHandle
= 0;
1427 grVcodecDecHWLock
.eDriverType
= VAL_DRIVER_TYPE_NONE
;
1428 grVcodecDecHWLock
.rLockedTime
.u4Sec
= 0;
1429 grVcodecDecHWLock
.rLockedTime
.u4uSec
= 0;
1430 mutex_unlock(&VdecHWLock
);
1432 mutex_lock(&VencHWLock
);
1433 grVcodecEncHWLock
.pvHandle
= 0;
1434 grVcodecEncHWLock
.eDriverType
= VAL_DRIVER_TYPE_NONE
;
1435 grVcodecEncHWLock
.rLockedTime
.u4Sec
= 0;
1436 grVcodecEncHWLock
.rLockedTime
.u4uSec
= 0;
1437 mutex_unlock(&VencHWLock
);
1439 mutex_lock(&DecEMILock
);
1440 gu4DecEMICounter
= 0;
1441 mutex_unlock(&DecEMILock
);
1443 mutex_lock(&EncEMILock
);
1444 gu4EncEMICounter
= 0;
1445 mutex_unlock(&EncEMILock
);
1447 mutex_lock(&PWRLock
);
1449 mutex_unlock(&PWRLock
);
1451 mutex_lock(&L2CLock
);
1453 if (gu4L2CCounter
!= 0)
1455 MFV_LOGE("vcodec_flush pid = %d, L2 user = %d, force restore L2 settings\n", current
->pid
, gu4L2CCounter
);
1456 if (config_L2(SZ_512K
))
1458 MFV_LOGE("restore L2 settings failed\n");
1463 mutex_unlock(&L2CLock
);
1465 spin_lock_irqsave(&LockDecHWCountLock
, ulFlagsLockHW
);
1466 gu4LockDecHWCount
= 0;
1467 spin_unlock_irqrestore(&LockDecHWCountLock
, ulFlagsLockHW
);
1469 spin_lock_irqsave(&LockEncHWCountLock
, ulFlagsLockHW
);
1470 gu4LockEncHWCount
= 0;
1471 spin_unlock_irqrestore(&LockEncHWCountLock
, ulFlagsLockHW
);
1473 spin_lock_irqsave(&DecISRCountLock
, ulFlagsISR
);
1475 spin_unlock_irqrestore(&DecISRCountLock
, ulFlagsISR
);
1477 spin_lock_irqsave(&EncISRCountLock
, ulFlagsISR
);
1479 spin_unlock_irqrestore(&EncISRCountLock
, ulFlagsISR
);
1481 mutex_unlock(&DriverOpenCountLock
);
1486 void vcodec_vma_open(struct vm_area_struct
*vma
)
1488 MFV_LOGD("vcodec VMA open, virt %lx, phys %lx\n", vma
->vm_start
, vma
->vm_pgoff
<< PAGE_SHIFT
);
1491 void vcodec_vma_close(struct vm_area_struct
*vma
)
1493 MFV_LOGD("vcodec VMA close, virt %lx, phys %lx\n", vma
->vm_start
, vma
->vm_pgoff
<< PAGE_SHIFT
);
1496 static struct vm_operations_struct vcodec_remap_vm_ops
= {
1497 .open
= vcodec_vma_open
,
1498 .close
= vcodec_vma_close
,
1501 static int vcodec_mmap(struct file
* file
, struct vm_area_struct
* vma
)
1506 length
= vma
->vm_end
- vma
->vm_start
;
1507 pfn
= vma
->vm_pgoff
<<PAGE_SHIFT
;
1509 if(((length
> VENC_REGION
) || (pfn
< VENC_BASE
) || (pfn
> VENC_BASE
+VENC_REGION
)) &&
1510 ((length
> VDEC_REGION
) || (pfn
< VDEC_BASE_PHY
) || (pfn
> VDEC_BASE_PHY
+VDEC_REGION
)) &&
1511 ((length
> HW_REGION
) || (pfn
< HW_BASE
) || (pfn
> HW_BASE
+HW_REGION
)) &&
1512 ((length
> INFO_REGION_1
) || (pfn
< INFO_BASE_1
) || (pfn
> INFO_BASE_1
+INFO_REGION_1
)) &&
1513 ((length
> INFO_REGION_2
) || (pfn
< INFO_BASE_2
) || (pfn
> INFO_BASE_2
+INFO_REGION_2
)) &&
1514 ((length
> INFO_REGION_3
) || (pfn
< INFO_BASE_3
) || (pfn
> INFO_BASE_3
+INFO_REGION_3
))
1517 MFV_LOGE("[ERROR] mmap region error: Length(0x%x), pfn(0x%x)\n", length
, pfn
);
1521 vma
->vm_page_prot
= pgprot_noncached(vma
->vm_page_prot
);
1522 MFV_LOGE("[mmap] vma->start 0x%x, vma->end 0x%x, vma->pgoff 0x%x\n",
1523 (unsigned int)vma
->vm_start
, (unsigned int)vma
->vm_end
, (unsigned int)vma
->vm_pgoff
);
1524 if (remap_pfn_range(vma
, vma
->vm_start
, vma
->vm_pgoff
,
1525 vma
->vm_end
- vma
->vm_start
, vma
->vm_page_prot
)) {
1529 vma
->vm_ops
= &vcodec_remap_vm_ops
;
1530 vcodec_vma_open(vma
);
1535 #ifdef CONFIG_HAS_EARLYSUSPEND
1536 static void vcodec_early_suspend(struct early_suspend
*h
)
1538 mutex_lock(&PWRLock
);
1539 MFV_LOGE("vcodec_early_suspend, tid = %d, PWR_USER = %d\n", current
->pid
, gu4PWRCounter
);
1540 mutex_unlock(&PWRLock
);
1542 if (gu4PWRCounter != 0)
1544 MFV_LOGE("[MT6589_VCodec_early_suspend] Someone Use HW, Disable Power!\n");
1545 disable_clock(MT65XX_PDN_MM_VBUF, "Video_VBUF");
1546 disable_clock(MT_CG_VDEC0_VDE, "VideoDec");
1547 disable_clock(MT_CG_VENC_VEN, "VideoEnc");
1548 disable_clock(MT65XX_PDN_MM_GDC_SHARE_MACRO, "VideoEnc");
1551 MFV_LOGD("vcodec_early_suspend - tid = %d\n", current
->pid
);
1554 static void vcodec_late_resume(struct early_suspend
*h
)
1556 mutex_lock(&PWRLock
);
1557 MFV_LOGE("vcodec_late_resume, tid = %d, PWR_USER = %d\n", current
->pid
, gu4PWRCounter
);
1558 mutex_unlock(&PWRLock
);
1560 if (gu4PWRCounter != 0)
1562 MFV_LOGE("[vcodec_late_resume] Someone Use HW, Enable Power!\n");
1563 enable_clock(MT65XX_PDN_MM_VBUF, "Video_VBUF");
1564 enable_clock(MT_CG_VDEC0_VDE, "VideoDec");
1565 enable_clock(MT_CG_VENC_VEN, "VideoEnc");
1566 enable_clock(MT65XX_PDN_MM_GDC_SHARE_MACRO, "VideoEnc");
1569 MFV_LOGD("vcodec_late_resume - tid = %d\n", current
->pid
);
1572 static struct early_suspend vcodec_early_suspend_handler
=
1574 .level
= (EARLY_SUSPEND_LEVEL_DISABLE_FB
- 1),
1575 .suspend
= vcodec_early_suspend
,
1576 .resume
= vcodec_late_resume
,
1580 static struct file_operations vcodec_fops
= {
1581 .owner
= THIS_MODULE
,
1582 .unlocked_ioctl
= vcodec_unlocked_ioctl
,
1583 .open
= vcodec_open
,
1584 .flush
= vcodec_flush
,
1585 .release
= vcodec_release
,
1586 .mmap
= vcodec_mmap
,
1589 static int vcodec_probe(struct platform_device
*dev
)
1592 MFV_LOGD("+vcodec_probe\n");
1594 mutex_lock(&DecEMILock
);
1595 gu4DecEMICounter
= 0;
1596 mutex_unlock(&DecEMILock
);
1598 mutex_lock(&EncEMILock
);
1599 gu4EncEMICounter
= 0;
1600 mutex_unlock(&EncEMILock
);
1602 mutex_lock(&PWRLock
);
1604 mutex_unlock(&PWRLock
);
1606 mutex_lock(&L2CLock
);
1608 mutex_unlock(&L2CLock
);
1610 ret
= register_chrdev_region(vcodec_devno
, 1, VCODEC_DEVNAME
);
1612 MFV_LOGE("[VCODEC_DEBUG][ERROR] Can't Get Major number for VCodec Device\n");
1615 vcodec_cdev
= cdev_alloc();
1616 vcodec_cdev
->owner
= THIS_MODULE
;
1617 vcodec_cdev
->ops
= &vcodec_fops
;
1619 ret
= cdev_add(vcodec_cdev
, vcodec_devno
, 1);
1621 MFV_LOGE("[VCODEC_DEBUG][ERROR] Can't add Vcodec Device\n");
1624 vcodec_class
= class_create(THIS_MODULE
, VCODEC_DEVNAME
);
1625 if (IS_ERR(vcodec_class
)) {
1626 ret
= PTR_ERR(vcodec_class
);
1627 MFV_LOGE("Unable to create class, err = %d", ret
);
1631 vcodec_device
= device_create(vcodec_class
, NULL
, vcodec_devno
, NULL
, VCODEC_DEVNAME
);
1633 if (request_irq(MT_VDEC_IRQ_ID
, (irq_handler_t
)video_intr_dlr
, IRQF_TRIGGER_LOW
, VCODEC_DEVNAME
, NULL
) < 0)
1635 MFV_LOGD("[VCODEC_DEBUG][ERROR] error to request dec irq\n");
1639 MFV_LOGD("[VCODEC_DEBUG] success to request dec irq\n");
1641 #ifdef MTK_SEC_VIDEO_PATH_SUPPORT
1642 MFV_LOGD("[VCODEC_DEBUG] CONFIG_SEC_VIDEO_PATH_SUPPORT not request enc irq\n");
1644 if (request_irq(MT_VENC_IRQ_ID
, (irq_handler_t
)video_intr_dlr2
, IRQF_TRIGGER_LOW
, VCODEC_DEVNAME
, NULL
) < 0)
1646 MFV_LOGE("[VCODEC_DEBUG][ERROR] error to request enc irq\n");
1650 MFV_LOGD("[VCODEC_DEBUG] success to request enc irq\n");
1654 disable_irq(MT_VDEC_IRQ_ID
);
1655 #ifdef MTK_SEC_VIDEO_PATH_SUPPORT
1657 disable_irq(MT_VENC_IRQ_ID
);
1660 MFV_LOGD("[VCODEC_DEBUG] vcodec_probe Done\n");
1665 #ifdef CONFIG_MTK_HIBERNATION
1666 extern void mt_irq_set_sens(unsigned int irq
, unsigned int sens
);
1667 extern void mt_irq_set_polarity(unsigned int irq
, unsigned int polarity
);
1668 static int vcodec_pm_restore_noirq(struct device
*device
)
1670 // vdec : IRQF_TRIGGER_LOW
1671 mt_irq_set_sens(MT_VDEC_IRQ_ID
, MT_LEVEL_SENSITIVE
);
1672 mt_irq_set_polarity(MT_VDEC_IRQ_ID
, MT_POLARITY_LOW
);
1673 // venc: IRQF_TRIGGER_LOW
1674 mt_irq_set_sens(MT_VENC_IRQ_ID
, MT_LEVEL_SENSITIVE
);
1675 mt_irq_set_polarity(MT_VENC_IRQ_ID
, MT_POLARITY_LOW
);
1681 static int __init
vcodec_driver_init(void)
1683 VAL_RESULT_T eValHWLockRet
;
1684 unsigned long ulFlags
, ulFlagsLockHW
, ulFlagsISR
;
1686 MFV_LOGD("+vcodec_init !!\n");
1688 mutex_lock(&DriverOpenCountLock
);
1689 MT8127Driver_Open_Count
= 0;
1690 mutex_unlock(&DriverOpenCountLock
);
1692 KVA_VENC_IRQ_STATUS_ADDR
= (int)ioremap(VENC_IRQ_STATUS_addr
, 4);
1693 KVA_VENC_IRQ_ACK_ADDR
= (int)ioremap(VENC_IRQ_ACK_addr
, 4);
1694 KVA_VENC_SW_PAUSE
= (int)ioremap(VENC_SW_PAUSE
, 4);
1695 KVA_VENC_SW_HRST_N
= (int)ioremap(VENC_SW_HRST_N
, 4);
1696 #ifdef VENC_PWR_FPGA
1697 KVA_VENC_CLK_CFG_0_ADDR
= (int)ioremap(CLK_CFG_0_addr
, 4);
1698 KVA_VENC_CLK_CFG_4_ADDR
= (int)ioremap(CLK_CFG_4_addr
, 4);
1699 KVA_VENC_PWR_ADDR
= (int)ioremap(VENC_PWR_addr
, 4);
1700 KVA_VENCSYS_CG_SET_ADDR
= (int)ioremap(VENCSYS_CG_SET_addr
, 4);
1703 spin_lock_irqsave(&LockDecHWCountLock
, ulFlagsLockHW
);
1704 gu4LockDecHWCount
= 0;
1705 spin_unlock_irqrestore(&LockDecHWCountLock
, ulFlagsLockHW
);
1707 spin_lock_irqsave(&LockEncHWCountLock
, ulFlagsLockHW
);
1708 gu4LockEncHWCount
= 0;
1709 spin_unlock_irqrestore(&LockEncHWCountLock
, ulFlagsLockHW
);
1711 spin_lock_irqsave(&DecISRCountLock
, ulFlagsISR
);
1713 spin_unlock_irqrestore(&DecISRCountLock
, ulFlagsISR
);
1715 spin_lock_irqsave(&EncISRCountLock
, ulFlagsISR
);
1717 spin_unlock_irqrestore(&EncISRCountLock
, ulFlagsISR
);
1719 mutex_lock(&IsOpenedLock
);
1720 if (VAL_FALSE
== bIsOpened
) {
1721 bIsOpened
= VAL_TRUE
;
1724 mutex_unlock(&IsOpenedLock
);
1726 mutex_lock(&VdecHWLock
);
1727 gu4VdecLockThreadId
= 0;
1728 grVcodecDecHWLock
.pvHandle
= 0;
1729 grVcodecDecHWLock
.eDriverType
= VAL_DRIVER_TYPE_NONE
;
1730 grVcodecDecHWLock
.rLockedTime
.u4Sec
= 0;
1731 grVcodecDecHWLock
.rLockedTime
.u4uSec
= 0;
1732 mutex_unlock(&VdecHWLock
);
1734 mutex_lock(&VencHWLock
);
1735 grVcodecEncHWLock
.pvHandle
= 0;
1736 grVcodecEncHWLock
.eDriverType
= VAL_DRIVER_TYPE_NONE
;
1737 grVcodecEncHWLock
.rLockedTime
.u4Sec
= 0;
1738 grVcodecEncHWLock
.rLockedTime
.u4uSec
= 0;
1739 mutex_unlock(&VencHWLock
);
1741 //MT8127_HWLockEvent part
1742 mutex_lock(&DecHWLockEventTimeoutLock
);
1743 DecHWLockEvent
.pvHandle
= "DECHWLOCK_EVENT";
1744 DecHWLockEvent
.u4HandleSize
= sizeof("DECHWLOCK_EVENT")+1;
1745 DecHWLockEvent
.u4TimeoutMs
= 1;
1746 mutex_unlock(&DecHWLockEventTimeoutLock
);
1747 eValHWLockRet
= eVideoCreateEvent(&DecHWLockEvent
, sizeof(VAL_EVENT_T
));
1748 if (VAL_RESULT_NO_ERROR
!= eValHWLockRet
) {
1749 MFV_LOGE("[MFV][ERROR] create dec hwlock event error\n");
1752 mutex_lock(&EncHWLockEventTimeoutLock
);
1753 EncHWLockEvent
.pvHandle
= "ENCHWLOCK_EVENT";
1754 EncHWLockEvent
.u4HandleSize
= sizeof("ENCHWLOCK_EVENT")+1;
1755 EncHWLockEvent
.u4TimeoutMs
= 1;
1756 mutex_unlock(&EncHWLockEventTimeoutLock
);
1757 eValHWLockRet
= eVideoCreateEvent(&EncHWLockEvent
, sizeof(VAL_EVENT_T
));
1758 if (VAL_RESULT_NO_ERROR
!= eValHWLockRet
) {
1759 MFV_LOGE("[MFV][ERROR] create enc hwlock event error\n");
1762 //MT8127_IsrEvent part
1763 spin_lock_irqsave(&DecIsrLock
, ulFlags
);
1764 DecIsrEvent
.pvHandle
= "DECISR_EVENT";
1765 DecIsrEvent
.u4HandleSize
= sizeof("DECISR_EVENT")+1;
1766 DecIsrEvent
.u4TimeoutMs
= 1;
1767 spin_unlock_irqrestore(&DecIsrLock
, ulFlags
);
1768 eValHWLockRet
= eVideoCreateEvent(&DecIsrEvent
, sizeof(VAL_EVENT_T
));
1769 if(VAL_RESULT_NO_ERROR
!= eValHWLockRet
)
1771 MFV_LOGE("[MFV][ERROR] create dec isr event error\n");
1774 spin_lock_irqsave(&EncIsrLock
, ulFlags
);
1775 EncIsrEvent
.pvHandle
= "ENCISR_EVENT";
1776 EncIsrEvent
.u4HandleSize
= sizeof("ENCISR_EVENT")+1;
1777 EncIsrEvent
.u4TimeoutMs
= 1;
1778 spin_unlock_irqrestore(&EncIsrLock
, ulFlags
);
1779 eValHWLockRet
= eVideoCreateEvent(&EncIsrEvent
, sizeof(VAL_EVENT_T
));
1780 if(VAL_RESULT_NO_ERROR
!= eValHWLockRet
)
1782 MFV_LOGE("[MFV][ERROR] create enc isr event error\n");
1785 MFV_LOGD("[VCODEC_DEBUG] vcodec_driver_init Done\n");
1787 #ifdef CONFIG_HAS_EARLYSUSPEND
1788 register_early_suspend(&vcodec_early_suspend_handler
);
1791 #ifdef CONFIG_MTK_HIBERNATION
1792 register_swsusp_restore_noirq_func(ID_M_VCODEC
, vcodec_pm_restore_noirq
, NULL
);
1798 static void __exit
vcodec_driver_exit(void)
1800 VAL_RESULT_T eValHWLockRet
;
1802 MFV_LOGD("[VCODEC_DEBUG] mflexvideo_driver_exit\n");
1804 mutex_lock(&IsOpenedLock
);
1805 if (VAL_TRUE
== bIsOpened
) {
1806 bIsOpened
= VAL_FALSE
;
1808 mutex_unlock(&IsOpenedLock
);
1810 cdev_del(vcodec_cdev
);
1811 unregister_chrdev_region(vcodec_devno
, 1);
1813 // [TODO] iounmap the following?
1814 iounmap((void*)KVA_VENC_IRQ_STATUS_ADDR
);
1815 iounmap((void*)KVA_VENC_IRQ_ACK_ADDR
);
1816 iounmap((void*)KVA_VENC_SW_PAUSE
);
1817 iounmap((void*)KVA_VENC_SW_HRST_N
);
1818 #ifdef VENC_PWR_FPGA
1819 iounmap((void*)KVA_VENC_CLK_CFG_0_ADDR
);
1820 iounmap((void*)KVA_VENC_CLK_CFG_4_ADDR
);
1821 iounmap((void*)KVA_VENC_PWR_ADDR
);
1822 iounmap((void*)KVA_VENCSYS_CG_SET_ADDR
);
1825 // [TODO] free IRQ here
1826 free_irq(MT_VENC_IRQ_ID
, NULL
);
1827 free_irq(MT_VDEC_IRQ_ID
, NULL
);
1830 //MT6589_HWLockEvent part
1831 eValHWLockRet
= eVideoCloseEvent(&DecHWLockEvent
, sizeof(VAL_EVENT_T
));
1832 if (VAL_RESULT_NO_ERROR
!= eValHWLockRet
) {
1833 MFV_LOGE("[MFV][ERROR] close dec hwlock event error\n");
1836 eValHWLockRet
= eVideoCloseEvent(&EncHWLockEvent
, sizeof(VAL_EVENT_T
));
1837 if (VAL_RESULT_NO_ERROR
!= eValHWLockRet
) {
1838 MFV_LOGE("[MFV][ERROR] close enc hwlock event error\n");
1841 //MT6589_IsrEvent part
1842 eValHWLockRet
= eVideoCloseEvent(&DecIsrEvent
, sizeof(VAL_EVENT_T
));
1843 if (VAL_RESULT_NO_ERROR
!= eValHWLockRet
) {
1844 MFV_LOGE("[MFV][ERROR] close dec isr event error\n");
1847 eValHWLockRet
= eVideoCloseEvent(&EncIsrEvent
, sizeof(VAL_EVENT_T
));
1848 if (VAL_RESULT_NO_ERROR
!= eValHWLockRet
) {
1849 MFV_LOGE("[MFV][ERROR] close enc isr event error\n");
1854 #ifdef CONFIG_HAS_EARLYSUSPEND
1855 unregister_early_suspend(&vcodec_early_suspend_handler
);
1858 #ifdef CONFIG_MTK_HIBERNATION
1859 unregister_swsusp_restore_noirq_func(ID_M_VCODEC
);
1863 module_init(vcodec_driver_init
);
1864 module_exit(vcodec_driver_exit
);
1865 MODULE_AUTHOR("Legis, Lu <legis.lu@mediatek.com>");
1866 MODULE_DESCRIPTION("MT8127 Vcodec Driver");
1867 MODULE_LICENSE("GPL");