• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 
19 #include "sys_ext.h"
20 #include "securec.h"
21 #include "hi_osal.h"
22 #include "hi_comm_sys.h"
23 #include "mkp_sys.h"
24 #include "sys_drv.h"
25 #include "sys_bind.h"
26 #include "sys.h"
27 #include "sys_hal.h"
28 
29 static sys_context g_sys_ctx = {0};
30 
31 static hi_bool g_conf = HI_FALSE;
32 static hi_u64 g_global_pts_base = 0;
33 static hi_u64 g_local_pts_base = 0;
34 static hi_u64 g_global_pts_last = 0;
35 static sys_mem_ctx g_mem_ctx[HI_ID_BUTT] = {0};
36 static struct osal_list_head g_list_mmz;
37 static osal_spinlock_t g_sys_spin_lock;
38 
39 #define sys_spin_lock(flags) osal_spin_lock_irqsave(&g_sys_spin_lock, &(flags))
40 #define sys_spin_unlock(flags) osal_spin_unlock_irqrestore(&g_sys_spin_lock, &(flags))
41 
42 #define SYS_STATE_STARTED    0
43 #define SYS_STATE_STOPPING   1
44 #define SYS_STATE_STOPPED    2
45 
46 
sys_get_sched_clock(void)47 static hi_u64 sys_get_sched_clock(void)
48 {
49     return osal_sched_clock();
50 }
51 
52 /*
53  * the return value of sched_clock may loopback after some years.
54  * but we should better deal with 'loopback'.
55  */
sys_get_local_cur_pts(void)56 static hi_u64 sys_get_local_cur_pts(void)
57 {
58     static hi_u64 time_last = 0;
59     hi_u64 time_now;
60 
61     time_now = osal_sched_clock();
62     if (time_last > time_now) {
63         osal_printk("sys_get_local_cur_pts osal_sched_clock error time_now=%llu,time_last=%llu\n",
64                     time_now, time_last);
65     }
66 
67     time_last = time_now;
68     time_now = osal_div_u64(time_now, 1000); /* 1000:unit conversion */
69 
70     return time_now;
71 }
72 
73 /* sys_get_time_stamp using sample:us */
sys_get_time_stamp(void)74 static hi_u64 sys_get_time_stamp(void)
75 {
76     hi_u64 pts_cur;
77     unsigned long flags;
78 
79     sys_spin_lock(flags);
80     pts_cur = g_global_pts_base + (sys_get_local_cur_pts() - g_local_pts_base);
81     /*
82      * the pts_cur will never overflow. but g_global_pts_base may be reduced.
83      * the pts_cur shouldn't recycle, so we adjust it bigger than pts_last;
84      */
85     if ((pts_cur < g_global_pts_last) && (g_global_pts_last != 0)) {
86         pts_cur = g_global_pts_last + 10; /* 10:ms */
87     }
88 
89     g_global_pts_last = pts_cur;
90     sys_spin_unlock(flags);
91     return pts_cur;
92 }
93 
94 /*
95  * sys_sync_time_stamp using sample:
96  * if no media bussines running, we should set init=HI_TRUE.
97  * but if media bussines is running, we only should use init=HI_FALSE to
98  * gently adjust the PTS.
99  * !!!!! if no necessary, don't call it !!!!
100  */
sys_sync_time_stamp(hi_u64 base,hi_bool init)101 static hi_void sys_sync_time_stamp(hi_u64 base, hi_bool init)
102 {
103     unsigned long flags;
104 
105     sys_spin_lock(flags);
106     g_global_pts_base = base;
107     g_local_pts_base = sys_get_local_cur_pts();
108     if (init == HI_TRUE) {
109         g_global_pts_last = 0;
110     }
111     sys_spin_unlock(flags);
112 }
113 
sys_user_init(hi_void)114 static hi_s32 sys_user_init(hi_void)
115 {
116     unsigned long flags;
117 
118     if (g_sys_ctx.state == SYS_STATE_STARTED) {
119         sys_info_trace("sys init again!\n");
120         return 0;
121     }
122 
123     if (g_sys_ctx.state == SYS_STATE_STOPPING) {
124         sys_err_trace("sys is busy!\n");
125         return HI_ERR_SYS_BUSY;
126     }
127 
128     /* init the PTS system */
129     sys_spin_lock(flags);
130     g_global_pts_base = sys_get_local_cur_pts();
131     g_local_pts_base = g_global_pts_base;
132     sys_spin_unlock(flags);
133 
134     if (cmpi_init_modules()) {
135         sys_err_trace("init modules failed!\n");
136         return HI_FAILURE;
137     }
138 
139     g_sys_ctx.state = SYS_STATE_STARTED;
140     sys_debug_trace("sys init ok!\n");
141 
142     return HI_SUCCESS;
143 }
144 
sys_user_exit(hi_void)145 static hi_s32 sys_user_exit(hi_void)
146 {
147     hi_u32 try_times = 10;
148 
149     if (g_sys_ctx.state == SYS_STATE_STOPPED) {
150         sys_info_trace("sys exit again!\n");
151         return HI_SUCCESS;
152     }
153 
154     /* notify all modules to stop only one time. */
155     if (g_sys_ctx.state == SYS_STATE_STARTED) {
156         cmpi_stop_modules();
157     }
158 
159     while (try_times) {
160         try_times--;
161         if (!cmpi_query_modules()) {
162             break;
163         }
164         osal_msleep(50);    /* 50:time period */
165     }
166 
167     /* if timeout */
168     if (!try_times) {
169         g_sys_ctx.state = SYS_STATE_STOPPING;
170         return HI_ERR_SYS_BUSY;
171     }
172     osal_msleep(50);    /* 50:time period */
173 
174     cmpi_exit_modules();
175     g_sys_ctx.state = SYS_STATE_STOPPED;
176 
177     sys_drv_vi_vpss_mode_init();
178 
179     g_conf = HI_FALSE;
180 
181     sys_debug_trace("sys exit ok!\n");
182     return HI_SUCCESS;
183 }
184 
sys_init_audio_mem_cnt(hi_void)185 static hi_void sys_init_audio_mem_cnt(hi_void)
186 {
187     g_mem_ctx[HI_ID_AIO].max_dev_cnt = AIO_MAX_NUM;
188     g_mem_ctx[HI_ID_AIO].max_chn_cnt = 1;
189 
190     g_mem_ctx[HI_ID_AI].max_dev_cnt = AI_DEV_MAX_NUM;
191     g_mem_ctx[HI_ID_AI].max_chn_cnt = AI_MAX_CHN_NUM;
192 
193     g_mem_ctx[HI_ID_AO].max_dev_cnt = AO_DEV_MAX_NUM;
194     g_mem_ctx[HI_ID_AO].max_chn_cnt = AO_MAX_CHN_NUM;
195 
196     g_mem_ctx[HI_ID_AENC].max_dev_cnt = 1;
197     g_mem_ctx[HI_ID_AENC].max_chn_cnt = AENC_MAX_CHN_NUM;
198 
199     g_mem_ctx[HI_ID_ADEC].max_dev_cnt = 1;
200     g_mem_ctx[HI_ID_ADEC].max_chn_cnt = ADEC_MAX_CHN_NUM;
201 }
202 
sys_init_video_mem_cnt(hi_void)203 static hi_void sys_init_video_mem_cnt(hi_void)
204 {
205 #ifdef CONFIG_HI_AVS_SUPPORT
206     g_mem_ctx[HI_ID_AVS].max_dev_cnt = AVS_MAX_GRP_NUM;
207     g_mem_ctx[HI_ID_AVS].max_chn_cnt = 1;
208 #endif
209 
210 #ifdef CONFIG_HI_VDEC_SUPPORT
211     g_mem_ctx[HI_ID_VDEC].max_dev_cnt = 1;
212     g_mem_ctx[HI_ID_VDEC].max_chn_cnt = VDEC_MAX_CHN_NUM;
213     g_mem_ctx[HI_ID_VFMW].max_dev_cnt = 1;
214     g_mem_ctx[HI_ID_VFMW].max_chn_cnt = 1;
215 #endif
216 
217 #ifdef CONFIG_HI_VO_SUPPORT
218     g_mem_ctx[HI_ID_VO].max_dev_cnt = VO_MAX_LAYER_NUM;
219     g_mem_ctx[HI_ID_VO].max_chn_cnt = VO_MAX_CHN_NUM;
220     g_mem_ctx[HI_ID_VO_DEV].max_dev_cnt = VO_MAX_DEV_NUM;
221     g_mem_ctx[HI_ID_VO_DEV].max_chn_cnt = VO_MAX_DEV_NUM;
222 #endif
223 
224     g_mem_ctx[HI_ID_VI].max_dev_cnt = VI_MAX_PIPE_NUM;
225     g_mem_ctx[HI_ID_VI].max_chn_cnt = VI_MAX_CHN_NUM;
226 
227     g_mem_ctx[HI_ID_VPSS].max_dev_cnt = VPSS_MAX_GRP_NUM;
228     g_mem_ctx[HI_ID_VPSS].max_chn_cnt = 1;
229 
230     g_mem_ctx[HI_ID_VENC].max_dev_cnt = VENC_MAX_RECEIVE_SOURCE;
231     g_mem_ctx[HI_ID_VENC].max_chn_cnt = VENC_MAX_CHN_NUM;
232 
233     g_mem_ctx[HI_ID_RGN].max_dev_cnt = 1;
234     g_mem_ctx[HI_ID_RGN].max_chn_cnt = 1;
235 
236 #ifdef CONFIG_HI_HIFB_SUPPORT
237     g_mem_ctx[HI_ID_FB].max_dev_cnt = VO_MAX_GRAPHICS_LAYER_NUM;
238     g_mem_ctx[HI_ID_FB].max_chn_cnt = 1;
239 #endif
240 
241 #ifdef CONFIG_HI_PCIV_SUPPORT
242     g_mem_ctx[HI_ID_PCIV].max_dev_cnt = 1;
243     g_mem_ctx[HI_ID_PCIV].max_chn_cnt = PCIV_MAX_CHN_NUM;
244 #endif
245 
246 #ifdef CONFIG_HI_VGS_SUPPORT
247     g_mem_ctx[HI_ID_VGS].max_dev_cnt = 1;
248     g_mem_ctx[HI_ID_VGS].max_chn_cnt = 1;
249 #endif
250 
251 #ifdef CONFIG_HI_GDC_SUPPORT
252     g_mem_ctx[HI_ID_GDC].max_dev_cnt = 1;
253     g_mem_ctx[HI_ID_GDC].max_chn_cnt = 1;
254 #endif
255 
256 #ifdef CONFIG_HI_MONO_COLOR_FUSION_SUPPORT
257     g_mem_ctx[HI_ID_MCF].max_dev_cnt = MCF_MAX_GRP_NUM;
258     g_mem_ctx[HI_ID_MCF].max_chn_cnt = MCF_MAX_CHN_NUM;
259 #endif
260 }
261 
sys_init_svp_mem_cnt(hi_void)262 static hi_void sys_init_svp_mem_cnt(hi_void)
263 {
264 #ifdef CONFIG_HI_SVP_SUPPORT
265     g_mem_ctx[HI_ID_SVP].max_dev_cnt = 1;
266     g_mem_ctx[HI_ID_SVP].max_chn_cnt = 1;
267 
268 #ifdef CONFIG_HI_SVP_DSP
269     g_mem_ctx[HI_ID_SVP_DSP].max_dev_cnt = 1;
270     g_mem_ctx[HI_ID_SVP_DSP].max_chn_cnt = 1;
271 #endif
272 
273 #ifdef CONFIG_HI_SVP_CNN
274     g_mem_ctx[HI_ID_SVP_NNIE].max_dev_cnt = 1;
275     g_mem_ctx[HI_ID_SVP_NNIE].max_chn_cnt = 1;
276 #endif
277 #endif
278 
279 #ifdef CONFIG_HI_SVP_DPU_RECT
280     g_mem_ctx[HI_ID_DPU_RECT].max_dev_cnt = DPU_RECT_MAX_GRP_NUM;
281     g_mem_ctx[HI_ID_DPU_RECT].max_chn_cnt = 1;
282 #endif
283 
284 #ifdef CONFIG_HI_SVP_DPU_MATCH
285     g_mem_ctx[HI_ID_DPU_MATCH].max_dev_cnt = DPU_MATCH_MAX_GRP_NUM;
286     g_mem_ctx[HI_ID_DPU_MATCH].max_chn_cnt = 1;
287 #endif
288 
289 #ifdef CONFIG_HI_SVP_IVE
290     g_mem_ctx[HI_ID_IVE].max_dev_cnt = 1;
291     g_mem_ctx[HI_ID_IVE].max_chn_cnt = 1;
292 #endif
293 
294 #ifdef CONFIG_HI_SVP_FD
295     g_mem_ctx[HI_ID_FD].max_dev_cnt = 1;
296     g_mem_ctx[HI_ID_FD].max_chn_cnt = 1;
297 #endif
298 }
299 
sys_malloc_mmz_tbl(hi_void)300 static hi_s32 sys_malloc_mmz_tbl(hi_void)
301 {
302     hi_s32 ret = HI_SUCCESS;
303     hi_s32 i;
304     hi_u32 size;
305 
306     for (i = 0; i < HI_ID_BUTT; i++) {
307         if ((g_mem_ctx[i].max_dev_cnt != 0) &&
308             (g_mem_ctx[i].max_chn_cnt != 0)) {
309             size = sizeof(sys_mod_chn_mmz) * g_mem_ctx[i].max_dev_cnt * g_mem_ctx[i].max_chn_cnt;
310 
311             g_mem_ctx[i].mmz_tbl = osal_kmalloc(size, osal_gfp_kernel);
312             if (g_mem_ctx[i].mmz_tbl == HI_NULL) {
313                 sys_err_trace("no memory for mmz_tbl!\n");
314                 ret = HI_ERR_SYS_NOMEM;
315                 goto failed;
316             }
317 
318             (hi_void)memset_s(g_mem_ctx[i].mmz_tbl, size, 0, size);
319         }
320     }
321 
322     OSAL_INIT_LIST_HEAD(&g_list_mmz);
323     return ret;
324 
325 failed:
326     for (i = 0; i < HI_ID_BUTT; i++) {
327         if ((g_mem_ctx[i].max_dev_cnt != 0) &&
328             (g_mem_ctx[i].max_chn_cnt != 0)) {
329             if (g_mem_ctx[i].mmz_tbl != HI_NULL) {
330                 osal_kfree(g_mem_ctx[i].mmz_tbl);
331                 g_mem_ctx[i].mmz_tbl = HI_NULL;
332             }
333         }
334     }
335 
336     return ret;
337 }
338 
sys_init_mem_conf(hi_void)339 hi_s32 sys_init_mem_conf(hi_void)
340 {
341     (hi_void)memset_s(g_mem_ctx, sizeof(g_mem_ctx), 0, sizeof(g_mem_ctx));
342 
343     sys_init_audio_mem_cnt();
344     sys_init_video_mem_cnt();
345     sys_init_svp_mem_cnt();
346 
347     return sys_malloc_mmz_tbl();
348 }
349 
sys_exit_mem_conf(hi_void)350 hi_s32 sys_exit_mem_conf(hi_void)
351 {
352     hi_s32 ret = HI_SUCCESS;
353     hi_s32 i;
354     sys_mem_node *node = HI_NULL;
355     struct osal_list_head *list_tmp = HI_NULL;
356     struct osal_list_head *list_node = HI_NULL;
357 
358     for (i = 0; i < HI_ID_BUTT; i++) {
359         if ((g_mem_ctx[i].max_dev_cnt != 0) &&
360             (g_mem_ctx[i].max_chn_cnt != 0)) {
361             if (g_mem_ctx[i].mmz_tbl != HI_NULL) {
362                 osal_kfree(g_mem_ctx[i].mmz_tbl);
363                 g_mem_ctx[i].mmz_tbl = HI_NULL;
364             }
365         }
366     }
367 
368     osal_list_for_each_safe(list_node, list_tmp, &g_list_mmz) {
369         node = osal_list_entry(list_node, sys_mem_node, list);
370         osal_list_del(list_node);
371         osal_vfree(node);
372     }
373 
374     return ret;
375 }
376 
sys_check_mem_chn(hi_mpp_chn * chn)377 static hi_s32 sys_check_mem_chn(hi_mpp_chn *chn)
378 {
379     if (chn->mod_id >= HI_ID_BUTT) {
380         sys_err_trace("mod_id:%d is invalid !\n", chn->mod_id);
381         return HI_ERR_SYS_ILLEGAL_PARAM;
382     }
383 
384     if ((chn->dev_id < 0) || (chn->dev_id >= (hi_s32)g_mem_ctx[chn->mod_id].max_dev_cnt) ||
385         (chn->chn_id < 0) || (chn->chn_id >= (hi_s32)g_mem_ctx[chn->mod_id].max_chn_cnt)) {
386         sys_err_trace("mod_id:%d mod dev or chn is invalid, dev:%d, chn:%d !\n",
387             chn->mod_id, chn->dev_id, chn->chn_id);
388         return HI_ERR_SYS_ILLEGAL_PARAM;
389     }
390 
391     return HI_SUCCESS;
392 }
393 
sys_mem_get_idx(sys_mem_ctx * mem_ctx,hi_s32 dev_id,hi_s32 chn_id)394 static hi_s32 sys_mem_get_idx(sys_mem_ctx *mem_ctx, hi_s32 dev_id, hi_s32 chn_id)
395 {
396     return (mem_ctx->max_chn_cnt * dev_id) + chn_id;
397 }
398 
sys_get_valid_mmz_tbl(hi_mpp_chn * mpp_chn,sys_mod_chn_mmz ** mmz_tbl)399 static hi_s32 sys_get_valid_mmz_tbl(hi_mpp_chn *mpp_chn, sys_mod_chn_mmz **mmz_tbl)
400 {
401     hi_s32 ret;
402     hi_u32 index;
403     sys_mem_ctx *mem_ctx = HI_NULL;
404 
405     ret = sys_check_mem_chn(mpp_chn);
406     if (ret != HI_SUCCESS) {
407         return ret;
408     }
409 
410     mem_ctx = &g_mem_ctx[mpp_chn->mod_id];
411     index = sys_mem_get_idx(mem_ctx, mpp_chn->dev_id, mpp_chn->chn_id);
412 
413     *mmz_tbl = &mem_ctx->mmz_tbl[index];
414 
415     return HI_SUCCESS;
416 }
417 
sys_set_mem_conf(hi_mpp_chn * mpp_chn,hi_char * pc_mmz_name)418 static hi_s32 sys_set_mem_conf(hi_mpp_chn *mpp_chn, hi_char *pc_mmz_name)
419 {
420     hi_s32 ret;
421     hi_bool find;
422     sys_mod_chn_mmz *mmz_tbl = HI_NULL;
423     sys_mem_node *node = HI_NULL;
424     struct osal_list_head *list_tmp = HI_NULL;
425     struct osal_list_head *list_node = HI_NULL;
426 
427     sys_check_null_ptr_return(mpp_chn);
428 
429     ret = sys_get_valid_mmz_tbl(mpp_chn, &mmz_tbl);
430     if (ret != HI_SUCCESS) {
431         return ret;
432     }
433 
434     if ((pc_mmz_name == HI_NULL) || (osal_strcmp(pc_mmz_name, "\0") == 0)) {
435         mmz_tbl->mmz_name = HI_NULL;
436     } else {
437         find = HI_FALSE;
438 
439         osal_list_for_each_safe(list_node, list_tmp, &g_list_mmz) {
440             node = osal_list_entry(list_node, sys_mem_node, list);
441             if (!osal_strcmp(pc_mmz_name, node->mmz_name)) {
442                 find = HI_TRUE;
443                 mmz_tbl->mmz_name = node->mmz_name;
444                 break;
445             }
446         }
447 
448         if (!find) {
449             node = osal_vmalloc(sizeof(sys_mem_node));
450             if (node == HI_NULL) {
451                 sys_err_trace("no memory for set memconf!\n");
452                 ret = HI_ERR_SYS_NOMEM;
453                 return ret;
454             }
455 
456             (hi_void)memset_s(node->mmz_name, sizeof(node->mmz_name), 0, sizeof(node->mmz_name));
457             if (strncpy_s(node->mmz_name, sizeof(node->mmz_name), pc_mmz_name, sizeof(node->mmz_name) - 1) != EOK) {
458                 osal_vfree(node);
459                 return HI_ERR_SYS_ILLEGAL_PARAM;
460             }
461             osal_list_add_tail(&node->list, &g_list_mmz);
462             mmz_tbl->mmz_name = node->mmz_name;
463         }
464     }
465 
466     return ret;
467 }
468 
sys_get_mem_conf(hi_mpp_chn * mpp_chn,hi_char * pc_mmz_name,hi_u32 mmz_name_len)469 static hi_s32 sys_get_mem_conf(hi_mpp_chn *mpp_chn, hi_char *pc_mmz_name, hi_u32 mmz_name_len)
470 {
471     hi_s32 ret;
472     hi_u32 index;
473     sys_mem_ctx *mem_ctx = HI_NULL;
474     sys_mod_chn_mmz *mmz_tbl = HI_NULL;
475 
476     sys_check_null_ptr_return(mpp_chn);
477 
478     ret = sys_check_mem_chn(mpp_chn);
479     if (ret != HI_SUCCESS) {
480         return ret;
481     }
482 
483     mem_ctx = &g_mem_ctx[mpp_chn->mod_id];
484     index = sys_mem_get_idx(mem_ctx, mpp_chn->dev_id, mpp_chn->chn_id);
485 
486     mmz_tbl = &mem_ctx->mmz_tbl[index];
487     if (mmz_tbl == HI_NULL) {
488         sys_err_trace("mmz_tbl null!\n");
489         return HI_ERR_SYS_NULL_PTR;
490     }
491 
492     if (mmz_tbl->mmz_name == HI_NULL) {
493         if (strncpy_s(pc_mmz_name, mmz_name_len, "\0", MAX_MMZ_NAME_LEN - 1) != EOK) {
494             return HI_ERR_SYS_ILLEGAL_PARAM;
495         }
496     } else {
497         if (strncpy_s(pc_mmz_name, mmz_name_len, mmz_tbl->mmz_name, MAX_MMZ_NAME_LEN - 1) != EOK) {
498             return HI_ERR_SYS_ILLEGAL_PARAM;
499         }
500     }
501 
502     return ret;
503 }
504 
sys_get_mmz_name(hi_mpp_chn * chn,hi_void ** mmz_name)505 static hi_s32 sys_get_mmz_name(hi_mpp_chn *chn, hi_void **mmz_name)
506 {
507     hi_s32 ret;
508     hi_u32 index;
509     sys_mem_ctx *mem_ctx = HI_NULL;
510     sys_mod_chn_mmz *mmz_tbl = HI_NULL;
511 
512     sys_check_null_ptr_return(chn);
513     sys_check_null_ptr_return(mmz_name);
514 
515     ret = sys_check_mem_chn(chn);
516     if (ret != HI_SUCCESS) {
517         return ret;
518     }
519 
520     mem_ctx = &g_mem_ctx[chn->mod_id];
521     index = sys_mem_get_idx(mem_ctx, chn->dev_id, chn->chn_id);
522 
523     mmz_tbl = &mem_ctx->mmz_tbl[index];
524     if (mmz_tbl == HI_NULL) {
525         sys_err_trace("mmz_tbl null!\n");
526         return HI_ERR_SYS_NULL_PTR;
527     }
528     *mmz_name = mmz_tbl->mmz_name;
529 
530     return ret;
531 }
532 
sys_ioctl(unsigned int cmd,unsigned long arg,void * private_data)533 static long sys_ioctl(unsigned int cmd, unsigned long arg, void *private_data)
534 {
535     int ret = 0;
536     hi_unused(private_data);
537 
538     if (osal_down_interruptible(&g_sys_ctx.sem)) {
539         return (-ERESTARTSYS);
540     }
541 
542     if (cmd == SYS_EXIT_CTRL) {
543         ret = sys_user_exit();
544     } else {
545         osal_atomic_inc_return(&g_sys_ctx.user_ref);
546 
547         switch (cmd) {
548             case SYS_INIT_CTRL:
549                 ret = sys_user_init();
550                 break;
551 
552             case SYS_EXIT_CTRL:
553                 ret = sys_user_exit();
554                 break;
555 
556             case SYS_GET_CURPTS: {
557                 *((hi_u64 *)(hi_uintptr_t)arg) = sys_get_time_stamp();
558                 ret = HI_SUCCESS;
559                 break;
560             }
561 
562             case SYS_INIT_PTSBASE: {
563                 sys_sync_time_stamp(*((hi_u64 *)(hi_uintptr_t)arg), HI_TRUE);
564                 ret = HI_SUCCESS;
565                 break;
566             }
567 
568             case SYS_SYNC_PTS: {
569                 sys_sync_time_stamp(*((hi_u64 *)(hi_uintptr_t)arg), HI_FALSE);
570                 ret = HI_SUCCESS;
571                 break;
572             }
573 
574             case SYS_BIND_CTRL: {
575                 sys_bind_args *bind_arg = (sys_bind_args *)(hi_uintptr_t)arg;
576                 ret = sys_bind(&bind_arg->src_chn, &bind_arg->dest_chn);
577                 break;
578             }
579 
580             case SYS_UNBIND_CTRL: {
581                 sys_bind_args *bind_arg = (sys_bind_args *)(hi_uintptr_t)arg;
582                 ret = sys_unbind(&bind_arg->src_chn, &bind_arg->dest_chn);
583                 break;
584             }
585 
586             case SYS_GETBINDBYDEST: {
587                 sys_bind_args *bind_arg = (sys_bind_args *)(hi_uintptr_t)arg;
588                 ret = sys_get_bind_by_dest(&bind_arg->dest_chn, &bind_arg->src_chn, HI_FALSE);
589                 break;
590             }
591 
592             case SYS_GETBINDBYSRC: {
593                 sys_bind_src_args *bind_src_arg = (sys_bind_src_args *)(hi_uintptr_t)arg;
594                 ret = sys_get_bind_by_src(&bind_src_arg->src_chn, &bind_src_arg->dest_chns);
595                 break;
596             }
597 
598             case SYS_MEM_SET_CTRL: {
599                 sys_mem_args *mem_arg = (sys_mem_args *)(hi_uintptr_t)arg;
600                 ret = sys_set_mem_conf(&mem_arg->mpp_chn, mem_arg->mmz_name);
601                 break;
602             }
603 
604             case SYS_MEM_GET_CTRL: {
605                 sys_mem_args *mem_arg = (sys_mem_args *)(hi_uintptr_t)arg;
606                 ret = sys_get_mem_conf(&mem_arg->mpp_chn, mem_arg->mmz_name, MAX_MMZ_NAME_LEN);
607                 break;
608             }
609 
610             case SYSCONFIG_SET_VI_VPSS_WORK_MODE: {
611                 hi_s32 mode = *(hi_s32 *)(hi_uintptr_t)arg;
612                 sysconfig_drv_set_vi_vpss_mode(mode);
613                 break;
614             }
615 
616             default:
617                 ret = HI_FAILURE;
618                 sys_err_trace("ioctl cmd %x is not supported!\n", cmd);
619             }
620 
621         osal_atomic_dec_return(&g_sys_ctx.user_ref);
622     }
623 
624     osal_up(&g_sys_ctx.sem);
625 
626     return ret;
627 }
628 
629 #ifdef CONFIG_COMPAT
sys_compat_ioctl(unsigned int cmd,unsigned long arg,void * private_data)630 static long sys_compat_ioctl(unsigned int cmd, unsigned long arg, void *private_data)
631 {
632     switch (cmd) {
633         case SYS_MFLUSH_CACHE: {
634             sys_mem_cache_info *mem_info = (sys_mem_cache_info *)(hi_uintptr_t)arg;
635             COMPAT_POINTER(mem_info->vir_addr, hi_void *);
636             break;
637         }
638 
639         default:
640         {
641             break;
642         }
643     }
644 
645     return sys_ioctl(cmd, arg, private_data);
646 }
647 #endif
648 
open(void * private_data)649 static hi_s32 open(void *private_data)
650 {
651     hi_unused(private_data);
652     return 0;
653 }
654 
close(void * private_data)655 static hi_s32 close(void *private_data)
656 {
657     hi_unused(private_data);
658     return 0;
659 }
660 
661 #define SYS_PAGE_SHIFT       12
662 
sys_mmap(osal_vm_t * vm,unsigned long start,unsigned long end,unsigned long vm_pgoff,void * private_data)663 static int sys_mmap(osal_vm_t *vm, unsigned long start, unsigned long end, unsigned long vm_pgoff, void *private_data)
664 {
665     int size = end - start;
666     hi_u64 phy_addr;
667     hi_unused(private_data);
668 
669     phy_addr = (hi_u64)(vm_pgoff << SYS_PAGE_SHIFT);
670     if (cmpi_check_mmz_phy_addr(phy_addr, size) != HI_SUCCESS) {
671         sys_err_trace("addr: %#llx, size: %d, invalid phyaddr!\n", phy_addr, size);
672         return HI_FAILURE;
673     }
674 
675     osal_pgprot_cached(vm);
676     if (osal_remap_pfn_range(vm, start, vm_pgoff, size)) {
677         return HI_FAILURE;
678     }
679 
680     return 0;
681 }
682 
683 #ifdef CONFIG_HI_PROC_SHOW_SUPPORT
sys_mem_proc_show(osal_proc_entry_t * s)684 static hi_void sys_mem_proc_show(osal_proc_entry_t *s)
685 {
686     hi_s32 i;
687     hi_u32 j;
688     hi_u32 tbl_size;
689     sys_mem_ctx *mem_ctx = HI_NULL;
690 
691     osal_seq_printf(s, "\n-----MEM TABLE------------------------------------------------------------------\n");
692     osal_seq_printf(s, "%8s" "%16s" "%8s" "%8s" "%16s" "\n", "Mod", "ModName", "Dev", "Chn", "MmzName");
693     for (i = 0; i < HI_ID_BUTT; i++) {
694         mem_ctx = &g_mem_ctx[i];
695         if ((mem_ctx->max_dev_cnt == 0) || (mem_ctx->max_chn_cnt == 0)) {
696             continue;
697         }
698 
699         tbl_size = mem_ctx->max_dev_cnt * mem_ctx->max_chn_cnt;
700 
701         for (j = 0; j < tbl_size; j++) {
702             if (mem_ctx->mmz_tbl[j].mmz_name != HI_NULL) {
703                 osal_seq_printf(s, "%8d" "%16s" "%8d" "%8d" "%16s" "\n",
704                     i, cmpi_get_module_name(i), (j / (mem_ctx->max_chn_cnt)),
705                     (j % (mem_ctx->max_chn_cnt)), mem_ctx->mmz_tbl[j].mmz_name);
706             }
707         }
708     }
709 
710     return;
711 }
712 
713 char *g_sys_state_string[] = { "run", "exiting", "exited" };
714 
sys_proc_show(osal_proc_entry_t * s)715 static hi_s32 sys_proc_show(osal_proc_entry_t *s)
716 {
717     osal_seq_printf(s, "\n[SYS] Version: [" MPP_VERSION "], Build Time["__DATE__
718         ", "__TIME__"]\n\n");
719     osal_seq_printf(s, "\n");
720 
721     if (g_sys_ctx.state != SYS_STATE_STARTED) {
722         return HI_SUCCESS;
723     }
724 
725     osal_seq_printf(s, "-----MODULE STATUS--------------------------------------------------------------\n");
726     osal_seq_printf(s, "  Status\n");
727     osal_seq_printf(s, "%8s\n", g_sys_state_string[g_sys_ctx.state]);
728 
729     sys_mem_proc_show(s);
730     sys_bind_proc_show(s);
731 
732     return HI_SUCCESS;
733 }
734 #endif
735 
736 static osal_fileops_t g_sys_file_op = {
737     .open = open,
738     .unlocked_ioctl = sys_ioctl,
739     .release = close,
740     .mmap = sys_mmap,
741 
742 #ifdef CONFIG_COMPAT
743     .compat_ioctl = sys_compat_ioctl,
744 #endif
745 };
746 
747 static osal_dev_t *g_sys_device = HI_NULL;
748 
749 static sys_export_func g_export_funcs = {
750     .pfn_sys_get_time_stamp = sys_get_time_stamp,
751     .pfn_sys_get_local_time_stamp = sys_get_local_cur_pts,
752     .pfn_sys_sync_time_stamp = sys_sync_time_stamp,
753     .pfn_sys_drv_ioctrl = sys_drv_drv_ioctrl,
754     .pfn_sys_register_sender = sys_bind_register_sender,
755     .pfn_sys_unregister_sender = sys_bind_unregister_sender,
756     .pfn_sys_register_receiver = sys_bind_register_receiver,
757     .pfn_sys_unregister_receiver = sys_bind_unregister_receiver,
758     .pfn_sys_send_data = sys_bind_send_data,
759     .pfn_sys_reset_data = sys_bind_reset_data,
760     .pfn_get_bind_by_src = sys_get_bind_by_src_with_lock,
761     .pfn_get_bind_num_by_src = sys_get_bind_num_by_src,
762     .pfn_get_bind_by_dest = sys_get_bind_by_dest_inner,
763     .pfn_get_mmz_name = sys_get_mmz_name,
764     .pfn_sys_get_sched_clock = sys_get_sched_clock,
765 };
766 
sys_do_init(hi_void * arg)767 hi_s32 sys_do_init(hi_void *arg)
768 {
769     hi_unused(arg);
770     return 0;
771 }
772 
sys_do_exit(hi_void)773 hi_void sys_do_exit(hi_void)
774 {
775     sys_bind_exit();
776     sys_debug_trace("sys mod exit ok!\n");
777     return;
778 }
779 
sys_query_state(mod_state * state)780 static hi_void sys_query_state(mod_state *state)
781 {
782     if (osal_atomic_read(&g_sys_ctx.user_ref) == 0) {
783         *state = MOD_STATE_FREE;
784     } else {
785         *state = MOD_STATE_BUSY;
786     }
787     return;
788 }
789 
sys_notify(mod_notice_id notice)790 static hi_void sys_notify(mod_notice_id notice)
791 {
792     hi_unused(notice);
793     return;
794 }
795 
796 static umap_module g_module = {
797     .mod_id = HI_ID_SYS,
798     .mod_name = "sys",
799 
800     .pfn_init = sys_do_init,
801     .pfn_exit = sys_do_exit,
802     .pfn_query_state = sys_query_state,
803     .pfn_notify = sys_notify,
804     .pfn_ver_checker = HI_NULL,
805     .export_funcs = &g_export_funcs,
806     .data = HI_NULL,
807 };
808 
sys_freeze(osal_dev_t * dev)809 static hi_s32 sys_freeze(osal_dev_t *dev)
810 {
811     hi_unused(dev);
812     return HI_SUCCESS;
813 }
814 
sys_restore(osal_dev_t * dev)815 static hi_s32 sys_restore(osal_dev_t *dev)
816 {
817     hi_unused(dev);
818     return HI_SUCCESS;
819 }
820 
821 osal_pmops_t g_sys_drv_ops = {
822     .pm_freeze = sys_freeze,
823     .pm_restore = sys_restore,
824 };
825 
sys_lock_init(hi_void)826 static hi_s32 sys_lock_init(hi_void)
827 {
828     if (osal_spin_lock_init(&g_sys_spin_lock) < 0) {
829         return HI_FAILURE;
830     }
831 
832     if (osal_atomic_init(&g_sys_ctx.user_ref) < 0) {
833         osal_spin_lock_destroy(&g_sys_spin_lock);
834         return HI_FAILURE;
835     }
836 
837     osal_atomic_set(&g_sys_ctx.user_ref, 0);
838 
839     if (osal_sema_init(&g_sys_ctx.sem, 1) < 0) {
840         osal_atomic_destroy(&g_sys_ctx.user_ref);
841         osal_spin_lock_destroy(&g_sys_spin_lock);
842         return HI_FAILURE;
843     }
844 
845     return HI_SUCCESS;
846 }
847 
sys_lock_destory(hi_void)848 static hi_void sys_lock_destory(hi_void)
849 {
850     osal_atomic_destroy(&g_sys_ctx.user_ref);
851     osal_sema_destroy(&g_sys_ctx.sem);
852     osal_spin_lock_destroy(&g_sys_spin_lock);
853 
854     return;
855 }
856 
sys_device_deinit(hi_void)857 static inline hi_void sys_device_deinit(hi_void)
858 {
859     osal_deregisterdevice(g_sys_device);
860     osal_destroydev(g_sys_device);
861     g_sys_device = HI_NULL;
862 }
863 
sys_device_init(hi_void)864 static hi_s32 sys_device_init(hi_void)
865 {
866     g_sys_device = osal_createdev(UMAP_DEVNAME_SYSCTL);
867     if (g_sys_device == HI_NULL) {
868         sys_err_trace("SYS createdev failed!\n");
869         return HI_FAILURE;
870     }
871     g_sys_device->fops = &g_sys_file_op;
872     g_sys_device->minor = UMAP_SYS_MINOR_BASE;
873     g_sys_device->osal_pmops = &g_sys_drv_ops;
874     if (osal_registerdevice(g_sys_device)) {
875         sys_err_trace("register system device failed!\n");
876         osal_destroydev(g_sys_device);
877         return HI_FAILURE;
878     }
879 
880     return HI_SUCCESS;
881 }
882 
sys_do_mpp_deinit(hi_void)883 static hi_void sys_do_mpp_deinit(hi_void)
884 {
885     sys_bind_mod_exit();
886     sys_drv_exit();
887     sys_exit_mem_conf();
888 }
889 
sys_do_mpp_init(hi_void)890 static hi_s32 sys_do_mpp_init(hi_void)
891 {
892     if (sys_init_mem_conf() != HI_SUCCESS) {
893         sys_err_trace("sys_init_mem_conf failed!\n");
894         return HI_FAILURE;
895     }
896 
897     if (sys_drv_init()) {
898         sys_err_trace("sys_drv_init failed!\n");
899         goto mem_exit;
900     }
901 
902     if (sys_bind_mod_init() != HI_SUCCESS) {
903         sys_err_trace("sys_bind_mod_init failed!\n");
904         goto drv_exit;
905     }
906 
907     sys_bind_init();
908 
909     return HI_SUCCESS;
910 
911 drv_exit:
912     sys_drv_exit();
913 mem_exit:
914     sys_exit_mem_conf();
915 
916     return HI_FAILURE;
917 }
918 
sys_do_mod_init(hi_void)919 hi_s32 sys_do_mod_init(hi_void)
920 {
921 #ifdef CONFIG_HI_PROC_SHOW_SUPPORT
922     osal_proc_entry_t *proc = HI_NULL;
923 #endif
924 
925     if (sys_lock_init() != HI_SUCCESS) {
926         sys_err_trace("SYS lock init failed!\n");
927         return HI_FAILURE;
928     }
929 
930     g_conf = HI_FALSE;
931     g_sys_ctx.state = SYS_STATE_STOPPED;
932     g_sys_ctx.sys_cfg.align = DEFAULT_ALIGN;
933 
934     if (sys_device_init()) {
935         goto lock_destroy;
936     }
937 
938     if (cmpi_register_module(&g_module)) {
939         sys_err_trace("register mod failed!\n");
940         goto dev_deinit;
941     }
942 
943 #ifdef CONFIG_HI_PROC_SHOW_SUPPORT
944     proc = osal_create_proc_entry(PROC_ENTRY_SYS, HI_NULL);
945     if (proc == HI_NULL) {
946         sys_err_trace("create proc failed!\n");
947         goto mod_unregister;
948     }
949     proc->read = sys_proc_show;
950 #endif
951 
952     if (sys_do_mpp_init() != HI_SUCCESS) {
953         goto proc_remove;
954     }
955 
956     HI_PRINT("load sys.ko for %s...OK!\n", CHIP_NAME);
957     return HI_SUCCESS;
958 proc_remove:
959     osal_remove_proc_entry(PROC_ENTRY_SYS, HI_NULL);
960 mod_unregister:
961     cmpi_unregister_module(HI_ID_SYS);
962 dev_deinit:
963     sys_device_deinit();
964 lock_destroy:
965     sys_lock_destory();
966     HI_PRINT("load sys.ko for %s...FAILURE!\n", CHIP_NAME);
967     return HI_FAILURE;
968 }
969 
sys_do_mod_exit(hi_void)970 hi_void sys_do_mod_exit(hi_void)
971 {
972     sys_do_mpp_deinit();
973 
974     if (g_sys_ctx.state != SYS_STATE_STOPPED) {
975         return;
976     }
977 
978     cmpi_unregister_module(HI_ID_SYS);
979 
980 #ifdef CONFIG_HI_PROC_SHOW_SUPPORT
981     osal_remove_proc_entry(PROC_ENTRY_SYS, HI_NULL);
982 #endif
983 
984     sys_device_deinit();
985 
986     sys_lock_destory();
987 
988     return;
989 }
990