• 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 "vou.h"
20 #include "hi_osal.h"
21 #include "hi_debug_adapt.h"
22 #include "hi_comm_vo_adapt.h"
23 #include "hi_comm_video_adapt.h"
24 
25 #include "mkp_vo_dev.h"
26 #include "hi_board.h"
27 #include "vou_drv.h"
28 #include "vou_chn.h"
29 #include "vou_dev_exp.h"
30 
31 #include "valg_plat.h"
32 #ifdef CONFIG_HI_VO_GRAPH
33 #include "vou_graphics.h"
34 #endif
35 #ifdef CONFIG_HI_PROC_SHOW_SUPPORT
36 #include "vou_proc.h"
37 #endif
38 #ifdef CONFIG_DRM_HISI_HISMART
39 #include "drm_display_func_ext.h"
40 #endif
41 
42 #ifdef __cplusplus
43 #if __cplusplus
44 extern "C" {
45 #endif
46 #endif /* end of #ifdef __cplusplus */
47 
48 hi_u32 g_vou_state = VOU_STATE_STOPPED;
49 static osal_atomic_t g_vou_user_ref = OSAL_ATOMIC_INIT(0);
50 
51 osal_spinlock_t g_vo_lock;
52 osal_spinlock_t g_vou_list_lock;
53 
54 struct osal_semaphore g_dev_sem;
55 struct osal_semaphore g_chn_sem;
56 
57 static osal_dev_t *g_vo_device;
58 
59 hi_vo_mod_param g_vo_mod_param = {
60     .transparent_transmit = HI_FALSE,
61     .exit_dev = HI_TRUE,
62     .wbc_bg_black_en = HI_FALSE,
63     .dev_clk_ext_en = HI_FALSE,
64     .save_buf_mode = { [0 ... VO_MAX_PHY_DEV_NUM - 1] = HI_FALSE },
65 };
66 
67 vo_dev_info g_vo_dev[VO_MAX_DEV_NUM];
68 
69 #ifdef CONFIG_HI_VO_VIRTDEV_SUPPORT
70 vou_virt_dev g_vou_virt_dev[VO_MAX_VIRT_DEV_NUM];
71 #endif
72 
73 unsigned int g_transparent_transmit = HI_FALSE;
74 
75 unsigned int g_low_power_mode = HI_TRUE;
76 
vo_get_vo_state(hi_void)77 hi_u32 vo_get_vo_state(hi_void)
78 {
79     return g_vou_state;
80 }
81 
vo_get_dev_lock(hi_void)82 osal_spinlock_t *vo_get_dev_lock(hi_void)
83 {
84     return &g_vo_lock;
85 }
86 
vo_get_list_lock(hi_void)87 osal_spinlock_t *vo_get_list_lock(hi_void)
88 {
89     return &g_vou_list_lock;
90 }
vo_get_chn_sem(hi_void)91 struct osal_semaphore *vo_get_chn_sem(hi_void)
92 {
93     return &g_chn_sem;
94 }
95 
vo_get_dev_sem(hi_void)96 struct osal_semaphore *vo_get_dev_sem(hi_void)
97 {
98     return &g_dev_sem;
99 }
100 
vo_get_vo_mod_param(hi_void)101 hi_vo_mod_param *vo_get_vo_mod_param(hi_void)
102 {
103     return &g_vo_mod_param;
104 }
105 
vo_get_dev_ctx(hi_vo_dev vo_dev)106 vo_dev_info *vo_get_dev_ctx(hi_vo_dev vo_dev)
107 {
108     return &g_vo_dev[vo_dev];
109 }
110 
111 #ifdef CONFIG_HI_VO_VIRTDEV_SUPPORT
vo_get_virt_dev_ctx(hi_vo_dev vo_dev)112 vou_virt_dev *vo_get_virt_dev_ctx(hi_vo_dev vo_dev)
113 {
114     return &g_vou_virt_dev[vo_dev];
115 }
116 #endif
117 
vo_get_transparent_transmit(hi_void)118 hi_u32 vo_get_transparent_transmit(hi_void)
119 {
120     return g_transparent_transmit;
121 }
122 
vo_def_check_dev_id(hi_vo_dev dev)123 hi_s32 vo_def_check_dev_id(hi_vo_dev dev)
124 {
125     if ((dev < 0) || (dev >= VO_MAX_DEV_NUM)) {
126         return HI_ERR_VO_INVALID_DEVID;
127     }
128 
129     return HI_SUCCESS;
130 }
131 
vou_sync_resource_init(hi_void)132 hi_void vou_sync_resource_init(hi_void)
133 {
134     vo_init_lock(&g_vou_list_lock);
135     vo_init_lock(&g_vo_lock);
136 
137 #ifdef CONFIG_HI_VO_GRAPH
138     vou_graphics_lock_init();
139 #endif
140 
141     osal_sema_init(&g_dev_sem, 1);
142     osal_sema_init(&g_chn_sem, 1);
143 }
144 
vou_sync_resource_de_init(hi_void)145 hi_void vou_sync_resource_de_init(hi_void)
146 {
147 #ifdef CONFIG_HI_VO_GRAPH
148     vou_graphics_lock_de_init();
149 #endif
150 
151     vo_deinit_lock(&g_vo_lock);
152     vo_deinit_lock(&g_vou_list_lock);
153 
154     osal_sema_destroy(&g_dev_sem);
155     osal_sema_destroy(&g_chn_sem);
156 }
157 
vou_disable_soft(hi_vo_dev dev)158 static hi_s32 vou_disable_soft(hi_vo_dev dev)
159 {
160     hi_u32 flags = 0;
161 
162     vo_check_dev_id_return(dev);
163 
164     vo_spin_lock(&g_vo_lock, &flags);
165 
166     g_vo_dev[dev].config = HI_FALSE;
167     g_vo_dev[dev].vo_enable = HI_FALSE;
168 
169     vo_drv_disable(dev);
170 
171     vo_spin_unlock(&g_vo_lock, &flags);
172 
173     return HI_SUCCESS;
174 }
175 
vo_dev_info_init(hi_void)176 static hi_s32 vo_dev_info_init(hi_void)
177 {
178     vo_dev_info *ctx = HI_NULL;
179     hi_u32 i;
180 
181     vo_drv_dev_info_init();
182 
183     for (i = 0; i < VO_MAX_DEV_NUM; i++) {
184         ctx = &g_vo_dev[i];
185         (hi_void)memset_s(ctx, sizeof(vo_dev_info), 0, sizeof(vo_dev_info));
186     }
187 
188     return HI_SUCCESS;
189 }
190 
vou_dev_info_de_init(hi_void)191 static hi_s32 vou_dev_info_de_init(hi_void)
192 {
193     vo_dev_info *ctx = HI_NULL;
194     hi_u32 i;
195     vo_drv_dev_info_de_init();
196     for (i = 0; i < VO_MAX_DEV_NUM; i++) {
197         ctx = &g_vo_dev[i];
198 
199         (hi_void)memset_s(ctx, sizeof(vo_dev_info), 0, sizeof(vo_dev_info));
200     }
201 
202     return HI_SUCCESS;
203 }
204 
vou_dev_ioctl(unsigned int cmd,unsigned long arg,void * private_data)205 static hi_s32 vou_dev_ioctl(unsigned int cmd, unsigned long arg, void *private_data)
206 {
207     hi_vo_dev dev = vo_get_dev(private_data);
208 #ifdef CONFIG_HI_VO_GRAPH
209     hi_graphic_layer gfx_layer = *(hi_u32 *)((hi_uintptr_t)(private_data));
210 #endif
211 
212     vo_debug_trace("cmd: %#x, dev: %d\n", cmd, dev);
213 
214     switch (cmd) {
215         /* device operation */
216         case VOU_DEV_SET_FD: {
217             UMAP_SET_CHN(private_data, *((hi_u32 *)(hi_uintptr_t)arg));
218             break;
219         }
220         case VOU_OPEN_CTRL: {
221             return vou_enable(dev);
222         }
223         case VOU_CLOSE_CTRL: {
224             return vou_disable(dev);
225         }
226         case VOU_PUB_ATTR_SET_CTRL: {
227             hi_vo_pub_attr *attr = (hi_vo_pub_attr *)(hi_uintptr_t)arg;
228             return vou_set_pub_attr(dev, attr);
229         }
230         case VOU_PUB_ATTR_GET_CTRL: {
231             hi_vo_pub_attr *attr = (hi_vo_pub_attr *)(hi_uintptr_t)arg;
232             return vou_get_pub_attr(dev, attr);
233         }
234         case VOU_DEV_FPS_SET_CTRL: {
235             hi_u32 *frame_rate = (hi_u32 *)(hi_uintptr_t)arg;
236             return vou_set_dev_frame_rate(dev, frame_rate);
237         }
238         case VOU_DEV_FPS_GET_CTRL: {
239             hi_u32 *frame_rate = (hi_u32 *)(hi_uintptr_t)arg;
240             return vou_get_dev_frame_rate(dev, frame_rate);
241         }
242         case VOU_DEV_VTTH_SET_CTRL: {
243             hi_u32 *vtth = (hi_u32 *)(hi_uintptr_t)arg;
244             return vou_set_vtth(dev, vtth);
245         }
246         case VOU_DEV_VTTH_GET_CTRL: {
247             hi_u32 *vtth = (hi_u32 *)(hi_uintptr_t)arg;
248             return vou_get_vtth(dev, vtth);
249         }
250         case VOU_DEV_VTTH2_SET_CTRL: {
251             hi_u32 *vtth = (hi_u32 *)(hi_uintptr_t)arg;
252             return vou_set_vtth2(dev, vtth);
253         }
254         case VOU_DEV_VTTH2_GET_CTRL: {
255             hi_u32 *vtth = (hi_u32 *)(hi_uintptr_t)arg;
256             return vou_get_vtth2(dev, vtth);
257         }
258 
259         case VOU_USER_INTFSYNC_INFO_SET_CTRL: {
260             hi_vo_user_intfsync_info *vo_user_sync_info = (hi_vo_user_intfsync_info *)(hi_uintptr_t)arg;
261             return vou_set_user_intf_sync_info(dev, vo_user_sync_info);
262         }
263 
264         /* graphic */
265         case VOU_GFX_LAYER_BIND_CTRL: {
266 #ifdef CONFIG_HI_VO_GRAPH
267             vo_check_null_ptr_return((hi_vo_dev *)(hi_uintptr_t)arg);
268 
269             dev = *(hi_vo_dev *)(hi_uintptr_t)arg;
270             return vou_graphics_bind_dev(gfx_layer, dev);
271 #else
272             vo_err_trace("hi_mpi_vo_bind_graphic_layer is not supported!\n");
273             return HI_ERR_VO_NOT_SUPPORT;
274 #endif
275         }
276         case VOU_GFX_LAYER_UNBIND_CTRL: {
277 #ifdef CONFIG_HI_VO_GRAPH
278             vo_check_null_ptr_return((hi_vo_dev *)(hi_uintptr_t)arg);
279 
280             dev = *(hi_vo_dev *)(hi_uintptr_t)arg;
281 
282             return vou_graphics_un_bind_dev(gfx_layer, dev);
283 #else
284             vo_err_trace("hi_mpi_vo_un_bind_graphic_layer is not supported!\n");
285             return HI_ERR_VO_NOT_SUPPORT;
286 #endif
287         }
288         case VOU_GFX_LAYER_CSC_SET_CTRL: {
289 #ifdef CONFIG_HI_VO_GRAPH
290 
291             hi_vo_csc *csc = (hi_vo_csc *)(hi_uintptr_t)arg;
292             return vou_graphics_set_csc(gfx_layer, csc);
293 
294 #else
295             vo_err_trace("hi_mpi_vo_set_graphic_layer_csc is not supported!\n");
296             return HI_ERR_VO_NOT_SUPPORT;
297 #endif
298         }
299         case VOU_GFX_LAYER_CSC_GET_CTRL: {
300 #ifdef CONFIG_HI_VO_GRAPH
301             hi_vo_csc *csc = (hi_vo_csc *)(hi_uintptr_t)arg;
302             return vou_graphics_get_csc(gfx_layer, csc);
303 #else
304             vo_err_trace("hi_mpi_vo_get_graphic_layer_csc is not supported!\n");
305             return HI_ERR_VO_NOT_SUPPORT;
306 #endif
307         }
308         case VO_MOD_PARAM_SET_CTRL: {
309             hi_vo_mod_param *vo_mod_param = (hi_vo_mod_param *)(hi_uintptr_t)arg;
310             return vo_set_mod_param(vo_mod_param);
311         }
312         case VO_MOD_PARAM_GET_CTRL: {
313             hi_vo_mod_param *vo_mod_param = (hi_vo_mod_param *)(hi_uintptr_t)arg;
314             return vo_get_mod_param(vo_mod_param);
315         }
316 
317         default: {
318             vo_warn_trace("ERR IOCTL CMD %#x!\n", cmd);
319             return HI_FAILURE;
320         }
321     }
322 
323     return HI_SUCCESS;
324 }
325 
326 #ifdef CONFIG_COMPAT
vou_dev_compat_ioctl(unsigned int cmd,unsigned long arg,void * private_data)327 static hi_s32 vou_dev_compat_ioctl(unsigned int cmd, unsigned long arg, void *private_data)
328 {
329     return vou_dev_ioctl(cmd, arg, private_data);
330 }
331 #endif
332 
vou_device_ioctl(unsigned int cmd,unsigned long arg,void * private_data)333 static long vou_device_ioctl(unsigned int cmd, unsigned long arg, void *private_data)
334 {
335     int ret;
336 
337     if (g_vou_state != VOU_STATE_STARTED) {
338         vo_err_trace("vo not init !\n");
339         return HI_ERR_VO_SYS_NOTREADY;
340     }
341 
342     osal_atomic_inc_return(&g_vou_user_ref);
343 
344     ret = vou_dev_ioctl(cmd, arg, private_data);
345 
346     osal_atomic_dec_return(&g_vou_user_ref);
347 
348     return ret;
349 }
350 
351 #ifdef CONFIG_COMPAT
vou_device_compat_ioctl(unsigned int cmd,unsigned long arg,void * private_data)352 static long vou_device_compat_ioctl(unsigned int cmd, unsigned long arg, void *private_data)
353 {
354     int ret;
355 
356     if (g_vou_state != VOU_STATE_STARTED) {
357         vo_err_trace("vo not init !\n");
358         return HI_ERR_VO_SYS_NOTREADY;
359     }
360 
361     osal_atomic_inc_return(&g_vou_user_ref);
362 
363     ret = vou_dev_compat_ioctl(cmd, arg, private_data);
364 
365     osal_atomic_dec_return(&g_vou_user_ref);
366 
367     return ret;
368 }
369 #endif
370 
vou_open(void * private_data)371 static hi_s32 vou_open(void *private_data)
372 {
373     hi_unused(private_data);
374     return 0;
375 }
376 
vou_close(void * private_data)377 static hi_s32 vou_close(void *private_data)
378 {
379     hi_unused(private_data);
380     return 0;
381 }
382 
vou_poll(osal_poll_t * osal_poll,void * private_data)383 static unsigned int vou_poll(osal_poll_t *osal_poll, void *private_data)
384 {
385     hi_unused(osal_poll);
386     hi_unused(private_data);
387     return HI_SUCCESS;
388 }
389 
390 #ifdef CONFIG_HISI_SNAPSHOT_BOOT
vou_freeze(osal_dev_t * dev)391 static hi_s32 vou_freeze(osal_dev_t *dev)
392 {
393     HI_PRINT("%s %d\n", __func__, __LINE__);
394     return HI_SUCCESS;
395 }
396 
vou_restore(osal_dev_t * dev)397 static hi_s32 vou_restore(osal_dev_t *dev)
398 {
399     hi_u32 flags = 0;
400 
401     vo_lpw_bus_reset(HI_FALSE);
402 
403     vo_spin_lock(&g_vo_lock, &flags);
404     vo_drv_set_all_crg_clk(HI_TRUE);
405 
406     vou_drv_default_setting();
407 
408     if (g_low_power_mode) {
409         vo_drv_set_all_crg_clk(HI_FALSE);
410     }
411 
412     vo_spin_unlock(&g_vo_lock, &flags);
413 
414     HI_PRINT("%s %d\n", __func__, __LINE__);
415     return HI_SUCCESS;
416 }
417 #else
vou_freeze(osal_dev_t * dev)418 static hi_s32 vou_freeze(osal_dev_t *dev)
419 {
420     hi_unused(dev);
421     return HI_SUCCESS;
422 }
423 
vou_restore(osal_dev_t * dev)424 static hi_s32 vou_restore(osal_dev_t *dev)
425 {
426     hi_unused(dev);
427     return HI_SUCCESS;
428 }
429 #endif
430 
431 static struct osal_fileops g_vo_file_op = {
432     .open = vou_open,
433     .unlocked_ioctl = vou_device_ioctl,
434     .release = vou_close,
435     .poll = vou_poll,
436 #ifdef CONFIG_COMPAT
437     .compat_ioctl = vou_device_compat_ioctl,
438 #endif
439 };
440 
441 struct osal_pmops g_vou_drv_ops = {
442     .pm_freeze = vou_freeze,
443     .pm_restore = vou_restore,
444 };
445 
vou_receive_sys_call_back(hi_vo_layer layer,hi_vo_chn chn,hi_bool block,mpp_data_type data_type,hi_void * data)446 hi_s32 vou_receive_sys_call_back(hi_vo_layer layer, hi_vo_chn chn, hi_bool block,
447                                  mpp_data_type data_type, hi_void *data)
448 {
449     hi_unused(data);
450     return HI_SUCCESS;
451 }
452 
vou_reset_call_back(hi_vo_layer layer,hi_vo_chn chn,hi_void * data)453 hi_s32 vou_reset_call_back(hi_vo_layer layer, hi_vo_chn chn, hi_void *data)
454 {
455     hi_unused(data);
456     return HI_SUCCESS;
457 }
458 
459 unsigned int g_vou_irq = VOU_IRQ_NR;
460 
461 static hi_bool g_is_initialized = HI_FALSE;
462 
463 #ifdef CONFIG_HI_VO_VIRTDEV_SUPPORT
vou_virt_dev_context_init(hi_void)464 static hi_void vou_virt_dev_context_init(hi_void)
465 {
466     hi_s32 i = 0;
467 
468     for (i = 0; i < VO_MAX_VIRT_DEV_NUM; i++) {
469         valg_timer_init(&g_vou_virt_dev[i].timer, vou_virt_dev_timer_func, i + VO_VIRT_LAYER_0);
470         g_vou_virt_dev[i].scale_pts = 0;
471     }
472 }
473 #endif
474 
vou_context_init(hi_void)475 hi_void vou_context_init(hi_void)
476 {
477     if ((g_is_initialized == HI_FALSE) || (g_vo_mod_param.exit_dev == HI_TRUE)) {
478         vo_dev_info_init();
479     } else {
480         vo_drv_dev_info_part_init();
481     }
482 
483 #ifdef CONFIG_HI_VO_VIRTDEV_SUPPORT
484     vou_virt_dev_context_init();
485 #endif
486 }
487 
vou_context_de_init(hi_void)488 hi_void vou_context_de_init(hi_void)
489 {
490     hi_s32 i = 0;
491 
492     if (g_vo_mod_param.exit_dev == HI_TRUE) {
493         vou_dev_info_de_init();
494     } else {
495         vo_drv_dev_info_de_init();
496     }
497 
498     for (i = 0; i < VO_MAX_DEV_NUM; i++) {
499         if (vou_drv_check_dev_id(i) == HI_SUCCESS) {
500             if (g_vo_mod_param.exit_dev == HI_FALSE) {
501             } else {
502                 vou_disable_soft(i);
503             }
504         }
505     }
506 
507 #ifdef CONFIG_HI_VO_VIRTDEV_SUPPORT
508     for (i = 0; i < VO_MAX_VIRT_DEV_NUM; i++) {
509         if (g_vou_virt_dev[i].timer.timer != HI_NULL) {
510             valg_timer_delete(&g_vou_virt_dev[i].timer);
511         }
512     }
513 #endif
514 }
515 
vo_init_set_sys_clk(hi_void)516 static hi_void vo_init_set_sys_clk(hi_void)
517 {
518     vo_set_low_power_ctrl_clk_en(HI_TRUE);
519     vo_lpw_bus_reset(HI_FALSE);
520     vo_drv_set_hd_clk_sel(0);
521 
522     return;
523 }
524 
vo_init_crg_clk(hi_void)525 static hi_void vo_init_crg_clk(hi_void)
526 {
527     hi_u32 flags = 0;
528 
529     vo_spin_lock(&g_vo_lock, &flags);
530     vo_drv_set_all_crg_clk(HI_TRUE);
531     vo_spin_unlock(&g_vo_lock, &flags);
532 }
533 
vo_init_default_setting(hi_void)534 static hi_void vo_init_default_setting(hi_void)
535 {
536     hi_u32 flags = 0;
537 
538     vo_spin_lock(&g_vo_lock, &flags);
539     vou_drv_default_setting();
540     vo_spin_unlock(&g_vo_lock, &flags);
541 }
542 
vo_set_drv_dev_int_enable(hi_void)543 static hi_void vo_set_drv_dev_int_enable(hi_void)
544 {
545     hi_s32 i;
546 
547     if (g_vo_mod_param.exit_dev == HI_FALSE) {
548         for (i = 0; i < VO_MAX_PHY_DEV_NUM; i++) {
549             if (vou_drv_check_dev_id(i) == HI_SUCCESS) {
550                 vo_drv_dev_int_enable(i, HI_TRUE);
551             }
552         }
553     }
554 }
555 
vo_register_receiver(hi_void)556 static hi_s32 vo_register_receiver(hi_void)
557 {
558     bind_receiver_info receiver_info;
559 
560     receiver_info.mod_id = HI_ID_VO_DEV;
561     receiver_info.max_dev_cnt = VO_MAX_DEV_NUM;
562     receiver_info.max_chn_cnt = VO_MAX_DEV_NUM;
563     receiver_info.support_delay_data = HI_TRUE;
564     receiver_info.call_back = vou_receive_sys_call_back;
565     receiver_info.reset_call_back = vou_reset_call_back;
566 
567     return call_sys_register_receiver(&receiver_info);
568 }
569 
vo_register_sender(hi_void)570 static hi_s32 vo_register_sender(hi_void)
571 {
572     bind_sender_info sender_info;
573 
574     sender_info.mod_id = HI_ID_VO_DEV;
575     sender_info.max_dev_cnt = VO_MAX_DEV_NUM;
576     sender_info.max_chn_cnt = VO_MAX_DEV_NUM;
577 
578     return call_sys_register_sender(&sender_info);
579 }
580 
vo_init_regitster(hi_void)581 static hi_s32 vo_init_regitster(hi_void)
582 {
583     hi_s32 ret;
584 
585     ret = vo_register_receiver();
586     if (ret != HI_SUCCESS) {
587         vo_alert_trace("register receiver failed!\n");
588         return HI_FAILURE;
589     }
590 
591     ret = vo_register_sender();
592     if (ret != HI_SUCCESS) {
593         vo_alert_trace("register sender failed!\n");
594         call_sys_unregister_receiver(HI_ID_VO_DEV);
595     }
596 
597     return HI_SUCCESS;
598 }
599 
vo_init(hi_void)600 hi_s32 vo_init(hi_void)
601 {
602     hi_s32 ret;
603 
604     vo_init_set_sys_clk();
605     if (g_vou_state == VOU_STATE_STARTED) {
606         return HI_SUCCESS;
607     }
608     vo_init_crg_clk();
609     vou_context_init();
610     vo_init_default_setting();
611     ret = vo_init_regitster();
612     if (ret != HI_SUCCESS) {
613         return ret;
614     }
615     g_vou_state = VOU_STATE_STARTED;
616 #ifdef CONFIG_HI_VO_GRAPH
617     vo_graphics_init();
618 #endif
619 
620     g_is_initialized = HI_TRUE;
621 
622     vo_set_drv_dev_int_enable();
623     return HI_SUCCESS;
624 }
625 
vo_exit_dev(hi_void)626 static hi_void vo_exit_dev(hi_void)
627 {
628     hi_s32 i;
629 
630     for (i = 0; i < VO_MAX_DEV_NUM; i++) {
631         if (vou_drv_check_dev_id(i) != HI_SUCCESS) {
632             continue;
633         }
634 
635         if (g_vo_dev[i].vo_enable) {
636             if (g_vo_mod_param.exit_dev == HI_FALSE) {
637             } else {
638                 vou_disable(i);
639             }
640         }
641     }
642 }
643 
vo_exit_unregister(hi_void)644 static hi_void vo_exit_unregister(hi_void)
645 {
646     call_sys_unregister_sender(HI_ID_VO_DEV);
647     call_sys_unregister_receiver(HI_ID_VO_DEV);
648 }
649 
vo_exit_set_clk(hi_void)650 static hi_void vo_exit_set_clk(hi_void)
651 {
652     hi_u32 flags = 0;
653 
654     if (g_vo_mod_param.exit_dev == HI_FALSE) {
655     } else {
656         vo_lpw_bus_reset(HI_TRUE);
657         vo_set_low_power_ctrl_clk_en(HI_FALSE);
658 
659         vo_spin_lock(&g_vo_lock, &flags);
660         vo_drv_set_all_crg_clk(HI_FALSE);
661         vo_spin_unlock(&g_vo_lock, &flags);
662     }
663 }
664 
vou_exit(hi_void)665 hi_void vou_exit(hi_void)
666 {
667     hi_u32 flags = 0;
668     if (g_vou_state == VOU_STATE_STOPPED) {
669         return;
670     }
671     if (g_vo_mod_param.exit_dev == HI_TRUE) {
672         vo_spin_lock(&g_vo_lock, &flags);
673         vo_drv_set_all_crg_clk(HI_TRUE);
674         vo_spin_unlock(&g_vo_lock, &flags);
675     }
676     vo_exit_dev();
677     vou_drv_int_disable_all();
678     vou_drv_int_clear(VOU_INTCLEAR_ALL);
679 
680     vou_context_de_init();
681 
682     vo_exit_unregister();
683 
684 #ifdef CONFIG_HI_VO_GRAPH
685     vo_graphics_de_init();
686 #endif
687     vo_exit_set_clk();
688 
689     g_vou_state = VOU_STATE_STOPPED;
690     vo_debug_trace("VOU exit!");
691 
692     return;
693 }
694 
vou_check_module_param(hi_void)695 hi_void vou_check_module_param(hi_void)
696 {
697     if ((g_transparent_transmit != 0) && (g_transparent_transmit != 1)) {
698         osal_printk("module param g_transparent_transmit(%u) should be 0 or 1, it will be set to 1\n",
699                     g_transparent_transmit);
700         g_transparent_transmit = 1;
701     }
702 
703     if ((g_low_power_mode != 0) && (g_low_power_mode != 1)) {
704         osal_printk("module param g_low_power_mode(%u) should be 0 or 1, it will be set to 1\n", g_low_power_mode);
705         g_low_power_mode = 1;
706     }
707 
708     return;
709 }
710 
711 vou_export_symbol_s g_vou_exp_symbol = {0};
712 vou_export_callback_s g_vo_exp_callback = {0};
713 
vo_get_exp_callback(hi_void)714 vou_export_callback_s *vo_get_exp_callback(hi_void)
715 {
716     return &g_vo_exp_callback;
717 }
718 
vou_register_extern_call_back(vou_export_callback_s * vo_exp_callback)719 hi_s32 vou_register_extern_call_back(vou_export_callback_s *vo_exp_callback)
720 {
721     if (vo_exp_callback == NULL) {
722         vo_err_trace("vo register export callback fail!\n");
723         return HI_ERR_VO_NULL_PTR;
724     }
725 
726     g_vo_exp_callback.pfnVoNotify = vo_exp_callback->pfnVoNotify;
727     return HI_SUCCESS;
728 }
729 
vo_mod_init_device(hi_void)730 static hi_s32 vo_mod_init_device(hi_void)
731 {
732     g_vo_device = osal_createdev(UMAP_DEVNAME_VO_DEV_BASE);
733     if (g_vo_device == HI_NULL) {
734         vo_alert_trace("VO create dev failed\n");
735         return HI_FAILURE;
736     }
737     g_vo_device->fops = &g_vo_file_op;
738     g_vo_device->osal_pmops = &g_vou_drv_ops;
739     g_vo_device->minor = UMAP_VO_DEV_MINOR_BASE;
740 
741     return HI_SUCCESS;
742 }
743 
vo_mod_init_global_variable(hi_void)744 static hi_void vo_mod_init_global_variable(hi_void)
745 {
746     osal_atomic_set(&g_vou_user_ref, 0);
747 
748     (hi_void)memset_s(&g_vou_exp_symbol, sizeof(vou_export_symbol_s), 0, sizeof(vou_export_symbol_s));
749     (hi_void)memset_s(&g_vo_exp_callback, sizeof(vou_export_callback_s), 0, sizeof(vou_export_callback_s));
750 
751     g_vou_exp_symbol.pfn_vo_register_exp_callback = vou_register_extern_call_back;
752 }
753 
vou_dev_module_init(void)754 int vou_dev_module_init(void)
755 {
756     vou_check_module_param();
757 
758     vou_sync_resource_init();
759 
760     if (vo_mod_init_device() != HI_SUCCESS) {
761         goto out0;
762     }
763 
764     if (osal_registerdevice(g_vo_device) < 0) {
765         vo_alert_trace("VO register failed\n");
766         goto out1;
767     }
768 
769 #ifdef CONFIG_HI_PROC_SHOW_SUPPORT
770     if (vo_mod_init_proc() != HI_SUCCESS) {
771         goto out2;
772     }
773 #endif
774     vou_drv_board_init();
775     vo_init();
776 
777     if (osal_atomic_init(&g_vou_user_ref)) {
778         vo_alert_trace("VO mod atomic failed\n");
779         goto out3;
780     }
781 
782     vo_mod_init_global_variable();
783 
784 #ifdef CONFIG_DRM_HISI_HISMART
785     drm_hal_disp_dev_register();
786 #endif
787 
788     HI_PRINT("load vo_dev.ko for %s...OK!\n", CHIP_NAME);
789     return HI_SUCCESS;
790 
791 out3:
792 #ifdef CONFIG_HI_PROC_SHOW_SUPPORT
793     osal_remove_proc_entry(PROC_ENTRY_VO_DEV, HI_NULL);
794 #endif
795 out2:
796     osal_deregisterdevice(g_vo_device);
797 out1:
798     osal_destroydev(g_vo_device);
799     g_vo_device = HI_NULL;
800 out0:
801     vou_sync_resource_de_init();
802     HI_PRINT("load vo_dev.ko for %s...FAILURE!\n", CHIP_NAME);
803     return HI_FAILURE;
804 }
805 
vou_dev_module_exit(void)806 void vou_dev_module_exit(void)
807 {
808 #ifdef CONFIG_DRM_HISI_HISMART
809     drm_hal_disp_dev_unregister();
810 #endif
811     osal_atomic_destroy(&g_vou_user_ref);
812 
813     vou_drv_board_de_init();
814 
815     vou_exit();
816 
817 #ifdef CONFIG_HI_PROC_SHOW_SUPPORT
818     osal_remove_proc_entry(PROC_ENTRY_VO_DEV, HI_NULL);
819 #endif
820     osal_deregisterdevice(g_vo_device);
821 
822     osal_destroydev(g_vo_device);
823 
824     vo_drv_set_all_crg_clk(HI_TRUE);
825 
826     vo_lpw_bus_reset(HI_TRUE);
827 
828     vo_drv_set_all_crg_clk(HI_FALSE);
829 
830     vou_sync_resource_de_init();
831 
832     (hi_void)memset_s(&g_vou_exp_symbol, sizeof(vou_export_symbol_s), 0, sizeof(vou_export_symbol_s));
833     (hi_void)memset_s(&g_vo_exp_callback, sizeof(vou_export_callback_s), 0, sizeof(vou_export_callback_s));
834 
835     HI_PRINT("unload vo_dev.ko ....OK!\n");
836     return;
837 }
838 
839 #ifdef __cplusplus
840 #if __cplusplus
841 }
842 #endif
843 #endif /* end of #ifdef __cplusplus */
844