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