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