• 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_chn.h"
20 #include "hi_osal.h"
21 #include "hi_debug_adapt.h"
22 #include "hi_math_adapt.h"
23 #include "mkp_vo_dev.h"
24 #include "hi_board.h"
25 #include "valg_plat.h"
26 #include "graphics_drv.h"
27 
28 #ifdef __cplusplus
29 #if __cplusplus
30 extern "C" {
31 #endif
32 #endif /* end of #ifdef __cplusplus */
33 
34 #define VOU_DEBUG                0
35 
36 #define VO_ROTATION_TASK_MAX_CNT 2
37 
38 #define VO_WBC_MAX_VGS_TASK      200
39 #define VO_WBC_MAX_COVEREX_NUM   VO_WBC_MAX_VGS_TASK
40 
41 #define VO_DEV_MAX_FRMRATE       240
42 
43 volatile hi_bool g_wbc_bottom = HI_FALSE;
44 
45 vo_sync_basic_info g_vo_sync_basic_info[VO_OUTPUT_BUTT] = {
46     { VO_OUTPUT_PAL,          "PAL",          720,  576,  25 },
47     { VO_OUTPUT_NTSC,         "NTSC",         720,  480,  30 },
48     { VO_OUTPUT_1080P24,      "1080P@24",     1920, 1080, 24 },
49     { VO_OUTPUT_1080P25,      "1080P@25",     1920, 1080, 25 },
50     { VO_OUTPUT_1080P30,      "1080P@30",     1920, 1080, 30 },
51     { VO_OUTPUT_720P50,       "720P@50",      1280, 720,  50 },
52     { VO_OUTPUT_720P60,       "720P@60",      1280, 720,  60 },
53     { VO_OUTPUT_1080I50,      "1080I50",      1920, 1080, 25 },
54     { VO_OUTPUT_1080I60,      "1080I60",      1920, 1080, 30 },
55     { VO_OUTPUT_1080P50,      "1080P@50",     1920, 1080, 50 },
56     { VO_OUTPUT_1080P60,      "1080P@60",     1920, 1080, 60 },
57     { VO_OUTPUT_576P50,       "576p@50",      720,  576,  50 },
58     { VO_OUTPUT_480P60,       "480p@60",      720,  480,  60 },
59     { VO_OUTPUT_800x600_60,   "800x600@60",   800,  600,  60 },
60     { VO_OUTPUT_1024x768_60,  "1024x768@60",  1024, 768,  60 },
61     { VO_OUTPUT_1280x1024_60, "1280x1024@60", 1280, 1024, 60 },
62     { VO_OUTPUT_1366x768_60,  "1366x768@60",  1366, 768,  60 },
63     { VO_OUTPUT_1440x900_60,  "1440x900@60",  1440, 900,  60 },
64     { VO_OUTPUT_1280x800_60,  "1280x800@60",  1280, 800,  60 },
65     { VO_OUTPUT_1600x1200_60, "1600x1200@60", 1600, 1200, 60 },
66     { VO_OUTPUT_1680x1050_60, "1680x1050@60", 1680, 1050, 60 },
67     { VO_OUTPUT_1920x1200_60, "1920x1200@60", 1920, 1200, 60 },
68     { VO_OUTPUT_640x480_60,   "640x480@60",   640,  480,  60 },
69     { VO_OUTPUT_960H_PAL,     "960H_PAL",     960,  576,  25 },
70     { VO_OUTPUT_960H_NTSC,    "960H_NTSC",    960,  480,  30 },
71     { VO_OUTPUT_1920x2160_30, "1920x2160@30", 1920, 2160, 30 },
72     { VO_OUTPUT_2560x1440_30, "2560x1440@30", 2560, 1440, 30 },
73     { VO_OUTPUT_2560x1440_60, "2560x1440@60", 2560, 1440, 60 },
74     { VO_OUTPUT_2560x1600_60, "2560x1600@60", 2560, 1600, 60 },
75     { VO_OUTPUT_3840x2160_24, "3840x2160@24", 3840, 2160, 24 },
76     { VO_OUTPUT_3840x2160_25, "3840x2160@25", 3840, 2160, 25 },
77     { VO_OUTPUT_3840x2160_30, "3840x2160@30", 3840, 2160, 30 },
78     { VO_OUTPUT_3840x2160_50, "3840x2160@50", 3840, 2160, 50 },
79     { VO_OUTPUT_3840x2160_60, "3840x2160@60", 3840, 2160, 60 },
80     { VO_OUTPUT_4096x2160_24, "4096x2160@24", 4096, 2160, 24 },
81     { VO_OUTPUT_4096x2160_25, "4096x2160@25", 4096, 2160, 25 },
82     { VO_OUTPUT_4096x2160_30, "4096x2160@30", 4096, 2160, 30 },
83     { VO_OUTPUT_4096x2160_50, "4096x2160@50", 4096, 2160, 50 },
84     { VO_OUTPUT_4096x2160_60, "4096x2160@60", 4096, 2160, 60 },
85     { VO_OUTPUT_320x240_60,   "320x240@60",   320,  240,  60 },
86     { VO_OUTPUT_320x240_50,   "320x240@50",   320,  240,  50 },
87     { VO_OUTPUT_240x320_50,   "240x320@50",   240,  320,  50 },
88     { VO_OUTPUT_240x320_60,   "240x320@60",   240,  320,  60 },
89     { VO_OUTPUT_800x600_50,   "800x600@50",   800,  600,  50 },
90     { VO_OUTPUT_720x1280_60,  "720x1280@60",  720,  1280, 60 },
91     { VO_OUTPUT_1080x1920_60, "1080x1920@60", 1080, 1920, 60 },
92     { VO_OUTPUT_7680x4320_30, "7680x4320@30", 7680, 4320, 30 },
93     { VO_OUTPUT_USER,         "USER",         0,    0,    0 },
94 };
95 
vo_get_sync_basic_info(hi_void)96 vo_sync_basic_info *vo_get_sync_basic_info(hi_void)
97 {
98     return g_vo_sync_basic_info;
99 }
100 
vou_set_disp_max_size(hi_vo_dev dev,hi_vo_intf_sync intf_sync,hi_vo_sync_info sync_info)101 hi_void vou_set_disp_max_size(hi_vo_dev dev, hi_vo_intf_sync intf_sync, hi_vo_sync_info sync_info)
102 {
103     hi_u32 max_width = 720;
104     hi_u32 max_height = 576;
105     vo_dev_info *dev_ctx = HI_NULL;
106 
107     if (intf_sync >= VO_OUTPUT_PAL && intf_sync < VO_OUTPUT_USER) {
108         if (g_vo_sync_basic_info[intf_sync].index == intf_sync) {
109             max_width = g_vo_sync_basic_info[intf_sync].width;
110             max_height = g_vo_sync_basic_info[intf_sync].height;
111         } else {
112             max_width = VO_DISP_1080_WIDTH;
113             max_height = VO_DISP_1080_HEIGHT;
114         }
115     } else if (intf_sync == VO_OUTPUT_USER) {
116         max_width = sync_info.hact;
117         max_height = (sync_info.iop) ? sync_info.vact : sync_info.vact * 2;
118     } else {
119         max_width = VO_DISP_1080_WIDTH;
120         max_height = VO_DISP_1080_HEIGHT;
121     }
122 
123     dev_ctx = vo_get_dev_ctx(dev);
124     dev_ctx->max_width = max_width;
125     dev_ctx->max_height = max_height;
126 
127     vou_drv_set_disp_max_size(dev, max_width, max_height);
128 }
129 
vo_set_pub_attr_check(hi_vo_dev dev,hi_vo_pub_attr * pub_attr)130 hi_s32 vo_set_pub_attr_check(hi_vo_dev dev, hi_vo_pub_attr *pub_attr)
131 {
132     hi_s32 ret;
133     vo_dev_info *dev_ctx = HI_NULL;
134 
135     dev_ctx = vo_get_dev_ctx(dev);
136     if (dev_ctx->vo_enable == HI_TRUE) {
137         vo_err_trace("vo %d doesn't disabled!\n", dev);
138         return HI_ERR_VO_DEV_HAS_ENABLED;
139     }
140 
141     ret = vou_drv_check_dev_pub_attr(dev, pub_attr);
142     if (ret != HI_SUCCESS) {
143         vo_err_trace("vo%d's pub attr is illegal!\n", dev);
144         return ret;
145     }
146 
147     if (!vou_drv_is_virt_dev(dev)) {
148         if (pub_attr->intf_sync == VO_OUTPUT_USER) {
149             ret = vou_drv_check_usr_sync_timing(dev, &pub_attr->sync_info);
150             if (ret != HI_SUCCESS) {
151                 vo_err_trace("vo%d's usr sync_timing is illegal!\n", dev);
152                 return ret;
153             }
154         }
155     }
156 
157     return ret;
158 }
159 
vo_set_phy_dev_pub_attr(hi_vo_dev dev,hi_vo_pub_attr * pub_attr)160 hi_void vo_set_phy_dev_pub_attr(hi_vo_dev dev, hi_vo_pub_attr *pub_attr)
161 {
162     hi_u32 vtth = 0;
163 
164     vou_drv_set_dev_intf_type(dev, pub_attr->intf_type);
165     vou_drv_set_dev_out_sync(dev, pub_attr->intf_sync);
166 
167     vou_drv_set_dev_bk_grd(dev, pub_attr->bg_color);
168 
169     vou_drv_get_dev_vtth(dev, &vtth);
170     vou_drv_set_dev_vtth(dev, vtth);
171     if (pub_attr->intf_sync == VO_OUTPUT_USER) {
172         vou_drv_set_usr_sync_timing(&pub_attr->sync_info);
173     }
174 }
175 
vo_set_full_frame_rate(hi_vo_pub_attr * pub_attr,vo_dev_info * dev_ctx)176 hi_void vo_set_full_frame_rate(hi_vo_pub_attr *pub_attr, vo_dev_info *dev_ctx)
177 {
178     if (pub_attr->intf_sync >= VO_OUTPUT_PAL && pub_attr->intf_sync < VO_OUTPUT_USER) {
179         if (g_vo_sync_basic_info[pub_attr->intf_sync].index == pub_attr->intf_sync) {
180             dev_ctx->full_frame_rate = g_vo_sync_basic_info[pub_attr->intf_sync].frame_rate;
181         } else {
182             dev_ctx->full_frame_rate = VO_DISP_FREQ_VGA;
183         }
184     } else {
185         dev_ctx->full_frame_rate = VO_DISP_FREQ_VGA;
186     }
187 }
188 
vou_set_pub_attr(hi_vo_dev dev,hi_vo_pub_attr * pub_attr)189 hi_s32 vou_set_pub_attr(hi_vo_dev dev, hi_vo_pub_attr *pub_attr)
190 {
191     hi_s32 ret;
192     vo_dev_info *dev_ctx = HI_NULL;
193 
194     vo_check_dev_id_return(dev);
195     vo_check_null_ptr_return(pub_attr);
196 
197     vo_down_sem_return();
198 
199     ret = vo_set_pub_attr_check(dev, pub_attr);
200     if (ret != HI_SUCCESS) {
201         vo_up_sem();
202         return ret;
203     }
204 
205     if (!vou_drv_is_virt_dev(dev)) {
206         vo_set_phy_dev_pub_attr(dev, pub_attr);
207     }
208 
209     dev_ctx = vo_get_dev_ctx(dev);
210 
211 #ifndef FPSCTRL_BYTIME
212     vo_set_full_frame_rate(pub_attr, dev_ctx);
213 #endif
214 
215     vou_set_disp_max_size(dev, pub_attr->intf_sync, pub_attr->sync_info);
216     /* copy to drv level. */
217     vou_drv_set_dev_full_frame_rate(dev, dev_ctx->full_frame_rate);
218     vou_drv_set_pub_attr(dev, pub_attr);
219     (hi_void)memcpy_s(&dev_ctx->vou_attr, sizeof(hi_vo_pub_attr), pub_attr, sizeof(hi_vo_pub_attr));
220     dev_ctx->config = HI_TRUE;
221 
222     vo_up_sem();
223 
224     return HI_SUCCESS;
225 }
226 
vou_get_pub_attr(hi_vo_dev dev,hi_vo_pub_attr * pub_attr)227 hi_s32 vou_get_pub_attr(hi_vo_dev dev, hi_vo_pub_attr *pub_attr)
228 {
229     vo_dev_info *dev_ctx = HI_NULL;
230 
231     vo_check_dev_id_return(dev);
232     vo_check_null_ptr_return(pub_attr);
233 
234     vo_down_sem_return();
235 
236     dev_ctx = vo_get_dev_ctx(dev);
237     (hi_void)memcpy_s(pub_attr, sizeof(hi_vo_pub_attr), &dev_ctx->vou_attr, sizeof(hi_vo_pub_attr));
238 
239     vo_up_sem();
240 
241     return HI_SUCCESS;
242 }
243 
vou_set_dev_frame_rate(hi_vo_dev dev,hi_u32 * frm_rate)244 hi_s32 vou_set_dev_frame_rate(hi_vo_dev dev, hi_u32 *frm_rate)
245 {
246     vo_dev_info *dev_ctx = HI_NULL;
247     hi_u32 frame_rate;
248 
249     vo_check_dev_id_return(dev);
250     vo_check_null_ptr_return(frm_rate);
251 
252     frame_rate = *frm_rate;
253 
254     if (frame_rate <= 0 || frame_rate > VO_DEV_MAX_FRMRATE) {
255         vo_err_trace("vo %d framerate should be (0, %d] which is %u!\n", dev, VO_DEV_MAX_FRMRATE, frame_rate);
256         return HI_ERR_VO_ILLEGAL_PARAM;
257     }
258 
259     vo_down_sem_return();
260     dev_ctx = vo_get_dev_ctx(dev);
261     if (dev_ctx->vo_enable == HI_TRUE) {
262         vo_err_trace("vo %d doesn't disabled!\n", dev);
263         vo_up_sem();
264         return HI_ERR_VO_DEV_HAS_ENABLED;
265     }
266 
267     if (dev_ctx->config == HI_FALSE) {
268         vo_err_trace("vo %d doesn't set pub attr!\n", dev);
269         vo_up_sem();
270         return HI_ERR_VO_DEV_NOT_CONFIG;
271     }
272 
273     if (dev_ctx->vou_attr.intf_sync != VO_OUTPUT_USER) {
274         vo_err_trace("vo %d doesn't set user intf_sync!\n", dev);
275         vo_up_sem();
276         return HI_ERR_VO_DEV_NOT_CONFIG;
277     }
278 
279     dev_ctx->full_frame_rate = frame_rate;
280     vou_drv_set_dev_full_frame_rate(dev, dev_ctx->full_frame_rate);
281 
282     vo_up_sem();
283 
284     return HI_SUCCESS;
285 }
286 
vou_get_dev_frame_rate(hi_vo_dev dev,hi_u32 * frame_rate)287 hi_s32 vou_get_dev_frame_rate(hi_vo_dev dev, hi_u32 *frame_rate)
288 {
289     vo_dev_info *dev_ctx = HI_NULL;
290 
291     vo_check_dev_id_return(dev);
292     vo_check_null_ptr_return(frame_rate);
293 
294     vo_down_sem_return();
295     dev_ctx = vo_get_dev_ctx(dev);
296 
297     *frame_rate = dev_ctx->full_frame_rate;
298 
299     vo_up_sem();
300 
301     return HI_SUCCESS;
302 }
303 
vou_set_vtth(hi_vo_dev dev,hi_u32 * vtth_set)304 hi_s32 vou_set_vtth(hi_vo_dev dev, hi_u32 *vtth_set)
305 {
306     hi_s32 ret;
307     hi_u32 vtth;
308     vo_dev_info *dev_ctx = HI_NULL;
309     vo_check_dev_id_return(dev);
310     vo_check_null_ptr_return(vtth_set);
311     vo_down_sem_return();
312 
313     vtth = *vtth_set;
314 
315 #ifdef CONFIG_HI_VO_VIRTDEV_SUPPORT
316     if (vou_drv_is_virt_dev(dev)) {
317         vo_err_trace("invalid dev id %d! should set vtth for physic vo dev\n", dev);
318         vo_up_sem();
319         return HI_ERR_VO_INVALID_DEVID;
320     }
321 #endif
322 
323     dev_ctx = vo_get_dev_ctx(dev);
324     if (dev_ctx->vo_enable == HI_TRUE) {
325         vo_err_trace("can't set dev(%d)'s vtth after vo enabled!\n", dev);
326         vo_up_sem();
327         return HI_ERR_VO_DEV_HAS_ENABLED;
328     }
329 
330     if (vo_drv_is_phy_dev_hd(dev) && ((vtth < VO_HD_MIN_VTTH_WATERLINE) || (vtth > VO_HD_MAX_VTTH_WATERLINE))) {
331         vo_err_trace("dev(%d) vtth %u illegal\n", dev, vtth);
332         vo_up_sem();
333         return HI_ERR_VO_ILLEGAL_PARAM;
334     }
335 
336     if (vo_drv_is_phy_dev_sd(dev) && ((vtth < VO_SD_MIN_VTTH_WATERLINE) || (vtth > VO_SD_MAX_VTTH_WATERLINE))) {
337         vo_err_trace("dev(%d) vtth %u illegal\n", dev, vtth);
338         vo_up_sem();
339         return HI_ERR_VO_ILLEGAL_PARAM;
340     }
341 
342     ret = vou_drv_set_dev_vtth(dev, *vtth_set);
343     vo_up_sem();
344     return ret;
345 }
346 
vou_get_vtth(hi_vo_dev dev,hi_u32 * vtth)347 hi_s32 vou_get_vtth(hi_vo_dev dev, hi_u32 *vtth)
348 {
349     vo_check_dev_id_return(dev);
350     vo_check_null_ptr_return(vtth);
351     vo_down_sem_return();
352 
353     if (!(vo_drv_is_phy_dev_hd(dev) || vo_drv_is_phy_dev_sd(dev))) {
354         vo_err_trace("invalid dev id %d! only physic vo dev support vtth\n", dev);
355         vo_up_sem();
356         return HI_ERR_VO_INVALID_DEVID;
357     }
358 
359     vou_drv_get_dev_vtth(dev, vtth);
360     vo_up_sem();
361     return HI_SUCCESS;
362 }
363 
vou_set_vtth2(hi_vo_dev dev,hi_u32 * vtth)364 hi_s32 vou_set_vtth2(hi_vo_dev dev, hi_u32 *vtth)
365 {
366     hi_s32 ret;
367     hi_u32 vtth1;
368     hi_u32 vtth2;
369     hi_vo_mod_param *vo_mod_param = HI_NULL;
370     vo_dev_info *dev_ctx = HI_NULL;
371 
372     vo_check_dev_id_return(dev);
373     vo_check_null_ptr_return(vtth);
374 
375     if (vou_drv_is_support_save_buf_mode() == HI_FALSE) {
376         vo_err_trace("not support setting vtth2!\n");
377         return HI_ERR_VO_NOT_SUPPORT;
378     }
379 
380     vtth2 = *vtth;
381     vo_down_sem_return();
382 
383     if (dev >= VO_MAX_PHY_DEV_NUM) {
384         vo_err_trace("dev(%d) is not physical device!\n", dev);
385         vo_up_sem();
386         return HI_ERR_VO_INVALID_DEVID;
387     }
388 
389     vo_mod_param = vo_get_vo_mod_param();
390     if (vo_mod_param->save_buf_mode[dev] == HI_FALSE) {
391         vo_err_trace("save_buf_mode must be true\n");
392         vo_up_sem();
393         return HI_ERR_VO_NOT_PERMIT;
394     }
395 
396     dev_ctx = vo_get_dev_ctx(dev);
397     if (dev_ctx->vo_enable == HI_TRUE) {
398         vo_err_trace("can't set dev(%d)'s vtth after vo enabled!\n", dev);
399         vo_up_sem();
400         return HI_ERR_VO_DEV_HAS_ENABLED;
401     }
402 
403     vou_drv_get_dev_vtth(dev, &vtth1);
404 
405     if (vo_drv_is_phy_dev_hd(dev) && ((vtth2 < VO_HD_MIN_VTTH_WATERLINE2) || (vtth2 > vtth1))) {
406         vo_err_trace("dev(%d) vtth2(%u),vtth1(%u) illegal\n", dev, vtth2, vtth1);
407         vo_up_sem();
408         return HI_ERR_VO_ILLEGAL_PARAM;
409     }
410 
411     if (vo_drv_is_phy_dev_sd(dev) && ((vtth2 < VO_SD_MIN_VTTH_WATERLINE2) || (vtth2 > vtth1))) {
412         vo_err_trace("dev(%d) vtth2(%u),vtth1(%u) illegal\n", dev, vtth2, vtth1);
413         vo_up_sem();
414         return HI_ERR_VO_ILLEGAL_PARAM;
415     }
416 
417     ret = vou_drv_set_dev_vtth2(dev, *vtth);
418 
419     vo_up_sem();
420     return ret;
421 }
422 
vou_get_vtth2(hi_vo_dev dev,hi_u32 * vtth)423 hi_s32 vou_get_vtth2(hi_vo_dev dev, hi_u32 *vtth)
424 {
425     hi_vo_mod_param *vo_mod_param = HI_NULL;
426 
427     vo_check_dev_id_return(dev);
428     vo_check_null_ptr_return(vtth);
429 
430     if (vou_drv_is_support_save_buf_mode() == HI_FALSE) {
431         vo_err_trace("not support getting vtth2!\n");
432         return HI_ERR_VO_NOT_SUPPORT;
433     }
434 
435     vo_down_sem_return();
436 
437     if (dev >= VO_MAX_PHY_DEV_NUM) {
438         vo_err_trace("dev(%d) is not physical device!\n", dev);
439         vo_up_sem();
440         return HI_ERR_VO_INVALID_DEVID;
441     }
442 
443     vo_mod_param = vo_get_vo_mod_param();
444     if (vo_mod_param->save_buf_mode[dev] == HI_FALSE) {
445         vo_err_trace("save_buf_mode must be true\n");
446         vo_up_sem();
447         return HI_ERR_VO_NOT_PERMIT;
448     }
449 
450     if (!(vo_drv_is_phy_dev_hd(dev) || vo_drv_is_phy_dev_sd(dev))) {
451         vo_err_trace("invalid dev id %d! should set vtth for physic vo dev\n", dev);
452         vo_up_sem();
453         return HI_ERR_VO_INVALID_DEVID;
454     }
455 
456     vou_drv_get_dev_vtth2(dev, vtth);
457 
458     vo_up_sem();
459     return HI_SUCCESS;
460 }
461 
vou_set_user_intf_sync_info(hi_vo_dev dev,hi_vo_user_intfsync_info * user_info)462 hi_s32 vou_set_user_intf_sync_info(hi_vo_dev dev, hi_vo_user_intfsync_info *user_info)
463 {
464     hi_s32 ret;
465     vo_dev_info *dev_ctx = HI_NULL;
466     hi_u32 flags = 0;
467     vo_check_dev_id_return(dev);
468     vo_check_null_ptr_return(user_info);
469 
470     vo_down_sem_return();
471 
472     vo_dev_spin_lock(&flags);
473     vo_drv_set_all_crg_clk(HI_TRUE);
474     vo_dev_spin_unlock(&flags);
475 
476 #ifdef CONFIG_HI_VO_VIRTDEV_SUPPORT
477     if (vou_drv_is_virt_dev(dev)) {
478         vo_err_trace("dev:%d is a virtual device, not support!\n", dev);
479         vo_up_sem();
480         return HI_ERR_VO_NOT_PERMIT;
481     }
482 #endif
483 
484     dev_ctx = vo_get_dev_ctx(dev);
485     if (dev_ctx->config != HI_TRUE) {
486         vo_err_trace("vo device %d doesn't configured!\n", dev);
487         vo_up_sem();
488         return HI_ERR_VO_DEV_NOT_CONFIG;
489     }
490 
491     if (dev_ctx->vou_attr.intf_sync != VO_OUTPUT_USER) {
492         vo_err_trace("vo device %d only support this in user sync.\n", dev);
493         vo_up_sem();
494         return HI_ERR_VO_NOT_SUPPORT;
495     }
496 
497     if (dev_ctx->vo_enable == HI_TRUE) {
498         vo_err_trace("vo device %d has enabled!\n", dev);
499         vo_up_sem();
500         return HI_ERR_VO_DEV_HAS_ENABLED;
501     }
502 
503     ret = vo_drv_check_dev_user_sync_info(dev, user_info);
504     if (ret != HI_SUCCESS) {
505         vo_err_trace("VO%d's user sync info is illegal!\n", dev);
506         vo_up_sem();
507         return ret;
508     }
509 
510     vo_drv_set_dev_user_intf_sync_attr(dev, &user_info->user_intf_sync_attr);
511 
512     vo_drv_set_dev_div(dev, user_info->dev_div);
513 
514     vo_drv_set_hdmi_div(dev, user_info->pre_div);
515 
516     vo_drv_set_clk_reverse(user_info->clk_reverse);
517 
518     vou_drv_set_user_sync_info(dev, user_info);
519     (hi_void)memcpy_s(&dev_ctx->vo_user_sync_info, sizeof(hi_vo_user_intfsync_info),
520                       user_info, sizeof(hi_vo_user_intfsync_info));
521     vo_up_sem();
522     return HI_SUCCESS;
523 }
524 
vou_reset_dev_vars(hi_vo_dev dev)525 static hi_void vou_reset_dev_vars(hi_vo_dev dev)
526 {
527     vo_dev_info *dev_ctx = HI_NULL;
528     dev_ctx = vo_get_dev_ctx(dev);
529 
530     (hi_void)memset_s(&dev_ctx->debug_info, sizeof(vo_debug_info), 0, sizeof(vo_debug_info));
531 
532     return;
533 }
534 
vo_enable_clk(hi_void)535 static hi_void vo_enable_clk(hi_void)
536 {
537     vo_set_low_power_ctrl_clk_en(HI_TRUE);
538     vo_lpw_bus_reset(HI_FALSE);
539     vo_drv_set_all_crg_clk(HI_TRUE);
540 }
541 
vo_enable_check(hi_vo_dev dev)542 static hi_s32 vo_enable_check(hi_vo_dev dev)
543 {
544     vo_dev_info *dev_ctx = HI_NULL;
545     dev_ctx = vo_get_dev_ctx(dev);
546     if (dev_ctx->config != HI_TRUE) {
547         vo_err_trace("vo device %d doesn't configured!\n", dev);
548         return HI_ERR_VO_DEV_NOT_CONFIG;
549     }
550 
551     if (dev_ctx->vo_enable == HI_TRUE) {
552         vo_err_trace("vo device %d has enabled!\n", dev);
553         return HI_ERR_VO_DEV_HAS_ENABLED;
554     }
555 
556     return HI_SUCCESS;
557 }
558 
vo_do_enable(hi_vo_dev dev)559 static hi_s32 vo_do_enable(hi_vo_dev dev)
560 {
561     hi_s32 ret;
562 
563     ret = vou_drv_set_dev_clk(dev);
564     if (ret != HI_SUCCESS) {
565         return ret;
566     }
567 
568     vo_drv_open(dev);
569 
570     return HI_SUCCESS;
571 }
572 
vo_had_enable(hi_vo_dev dev)573 static hi_void vo_had_enable(hi_vo_dev dev)
574 {
575     vo_dev_info *dev_ctx = HI_NULL;
576     dev_ctx = vo_get_dev_ctx(dev);
577 
578     if (dev == HAL_DISP_CHANNEL_DHD0) {
579         vo_drv_v_set_v0_zme_coef(VO_RM_COEF_MODE_TYP);
580     }
581 
582     vo_drv_enable(dev);
583     dev_ctx->vo_enable = HI_TRUE;
584 }
585 
586 #ifdef CONFIG_HI_VO_VIRTDEV_SUPPORT
vo_enable_virt_dev(hi_vo_dev dev)587 static hi_s32 vo_enable_virt_dev(hi_vo_dev dev)
588 {
589     vo_dev_info *dev_ctx = HI_NULL;
590     dev_ctx = vo_get_dev_ctx(dev);
591     if (vou_drv_is_virt_dev(dev)) {
592         dev_ctx->vo_enable = HI_TRUE;
593         return HI_SUCCESS;
594     }
595     return HI_FAILURE;
596 }
597 #endif
598 
vou_enable(hi_vo_dev dev)599 hi_s32 vou_enable(hi_vo_dev dev)
600 {
601     hi_s32 ret;
602     hi_u32 flags = 0;
603 
604     vo_check_dev_id_return(dev);
605 
606     vo_down_sem_return();
607 
608 #ifdef CONFIG_HI_VO_VIRTDEV_SUPPORT
609     ret = vo_enable_virt_dev(dev);
610     if (ret == HI_SUCCESS) {
611         goto return_ret;
612     }
613 #endif
614 
615     vo_dev_spin_lock(&flags);
616     vo_enable_clk();
617     vo_dev_spin_unlock(&flags);
618 
619     ret = vo_enable_check(dev);
620     if (ret != HI_SUCCESS) {
621         goto return_ret;
622     }
623 
624     if (vou_drv_get_dev_enable(dev) == HI_TRUE) {
625         vo_info_trace("vo device %d has enabled in uboot!\n", dev);
626         vo_drv_dev_int_enable(dev, HI_TRUE);
627         ret = HI_SUCCESS;
628         goto load_detect;
629     }
630 
631     ret = vo_do_enable(dev);
632     if (ret != HI_SUCCESS) {
633         goto return_ret;
634     }
635 
636 load_detect:
637     vo_had_enable(dev);
638 
639 return_ret:
640     vo_up_sem();
641 
642     return ret;
643 }
644 
645 #ifdef CONFIG_HI_VO_WBC
vo_wbc_enable_check(hi_vo_dev dev)646 static hi_s32 vo_wbc_enable_check(hi_vo_dev dev)
647 {
648     return HI_SUCCESS;
649 }
650 #endif
651 
vo_layer_enable_check(hi_vo_dev dev)652 static hi_s32 vo_layer_enable_check(hi_vo_dev dev)
653 {
654     return HI_SUCCESS;
655 }
656 
vo_disable_check(hi_vo_dev dev)657 static hi_s32 vo_disable_check(hi_vo_dev dev)
658 {
659     hi_s32 ret;
660 
661     ret = vo_layer_enable_check(dev);
662     if (ret != HI_SUCCESS) {
663         return ret;
664     }
665 
666 #ifdef CONFIG_HI_VO_WBC
667     ret = vo_wbc_enable_check(dev);
668     if (ret != HI_SUCCESS) {
669         return ret;
670     }
671 #endif
672 
673     return HI_SUCCESS;
674 }
675 
vo_reset_vtth(hi_vo_dev dev)676 static hi_void vo_reset_vtth(hi_vo_dev dev)
677 {
678     hi_vo_mod_param *vo_mod_param = HI_NULL;
679 
680     if (!vou_drv_is_virt_dev(dev)) {
681         vou_drv_set_dev_default_vtth(dev);
682     }
683 
684     vo_mod_param = vo_get_vo_mod_param();
685     if ((dev < VO_MAX_PHY_DEV_NUM) && vo_mod_param->save_buf_mode[dev]) {
686         vou_drv_set_dev_default_vtth2(dev);
687     }
688 }
689 
vo_disable_clk(hi_void)690 static hi_void vo_disable_clk(hi_void)
691 {
692     hi_s32 i;
693     vo_dev_info *dev_ctx = HI_NULL;
694 
695     for (i = 0; i < VO_MAX_PHY_DEV_NUM; i++) {
696         dev_ctx = vo_get_dev_ctx(i);
697         if (dev_ctx->vo_enable || (vou_drv_get_dev_enable(i) == HI_TRUE)) {
698             break;
699         }
700     }
701 
702     if (i == VO_MAX_PHY_DEV_NUM) {
703         vo_set_low_power_ctrl_clk_en(HI_FALSE);
704         vo_drv_set_all_crg_clk(HI_FALSE);
705     }
706 }
707 
vou_disable(hi_vo_dev dev)708 hi_s32 vou_disable(hi_vo_dev dev)
709 {
710     hi_s32 ret;
711     hi_u32 flags = 0;
712     vo_dev_info *dev_ctx = HI_NULL;
713 
714     vo_check_dev_id_return(dev);
715 
716     vo_down_sem_return();
717 
718     vo_dev_spin_lock(&flags);
719     vo_drv_set_all_crg_clk(HI_TRUE);
720     vo_dev_spin_unlock(&flags);
721 
722     ret = vo_disable_check(dev);
723     if (ret != HI_SUCCESS) {
724         vo_up_sem();
725         return ret;
726     }
727 
728     if (!vou_drv_is_virt_dev(dev)) {
729         vo_drv_close(dev);
730     }
731 
732     vou_drv_int_clear(VOU_INTCLEAR_ALL);
733 
734     vo_drv_disable(dev);
735 
736     dev_ctx = vo_get_dev_ctx(dev);
737     dev_ctx->config = HI_FALSE;
738     dev_ctx->vo_enable = HI_FALSE;
739 
740     vou_reset_dev_vars(dev);
741 
742     vo_reset_vtth(dev);
743 
744     vo_dev_spin_lock(&flags);
745     vo_disable_clk();
746     vo_dev_spin_unlock(&flags);
747 
748     vo_up_sem();
749 
750     return HI_SUCCESS;
751 }
752 
753 #ifdef CONFIG_HI_VO_VIRTDEV_SUPPORT
vou_virt_dev_timer_func(unsigned long data)754 void vou_virt_dev_timer_func(unsigned long data)
755 {
756     return;
757 }
758 #endif
759 
vo_check_mod_param(const hi_vo_mod_param * mod_param)760 hi_s32 vo_check_mod_param(const hi_vo_mod_param *mod_param)
761 {
762     hi_u32 i = 0;
763 
764     vo_dev_info *dev_ctx = HI_NULL;
765 
766     if ((mod_param->transparent_transmit != HI_TRUE) && (mod_param->transparent_transmit != HI_FALSE)) {
767         vo_err_trace("the transparent_transmit %d is illegal!\n", mod_param->transparent_transmit);
768         return HI_ERR_VO_ILLEGAL_PARAM;
769     }
770 
771     if ((mod_param->exit_dev != HI_TRUE) && (mod_param->exit_dev != HI_FALSE)) {
772         vo_err_trace("the exit_dev %d is illegal!\n", mod_param->exit_dev);
773         return HI_ERR_VO_ILLEGAL_PARAM;
774     }
775 
776     if ((mod_param->wbc_bg_black_en != HI_TRUE) && (mod_param->wbc_bg_black_en != HI_FALSE)) {
777         vo_err_trace("the wbc_bg_black_en %d is illegal!\n", mod_param->wbc_bg_black_en);
778         return HI_ERR_VO_ILLEGAL_PARAM;
779     }
780 
781     if ((mod_param->dev_clk_ext_en != HI_TRUE) && (mod_param->dev_clk_ext_en != HI_FALSE)) {
782         vo_err_trace("the dev_clk_ext_en %d is illegal!\n", mod_param->dev_clk_ext_en);
783         return HI_ERR_VO_ILLEGAL_PARAM;
784     }
785 
786     for (i = 0; i < VO_MAX_PHY_DEV_NUM; i++) {
787         vo_down_sem_return();
788 
789         dev_ctx = vo_get_dev_ctx(i);
790         if (dev_ctx->vo_enable == HI_TRUE) {
791             vo_err_trace("vo device %u has enabled!\n", i);
792             vo_up_sem();
793             return HI_ERR_VO_DEV_HAS_ENABLED;
794         }
795 
796         vo_up_sem();
797 
798         if (vou_drv_is_support_save_buf_mode()) {
799             if ((mod_param->save_buf_mode[i] != HI_TRUE) && (mod_param->save_buf_mode[i] != HI_FALSE)) {
800                 vo_err_trace("the save_buf_mode[%u] %d is illegal!\n", i, mod_param->save_buf_mode[i]);
801                 return HI_ERR_VO_ILLEGAL_PARAM;
802             }
803         } else {
804             if (mod_param->save_buf_mode[i] != HI_FALSE) {
805                 vo_err_trace("the chip not support save buf mode, save_buf_mode[%u]:%d should be HI_FALSE!\n", i,
806                              mod_param->save_buf_mode[i]);
807                 return HI_ERR_VO_ILLEGAL_PARAM;
808             }
809         }
810     }
811     return HI_SUCCESS;
812 }
813 
vo_set_mod_param(const hi_vo_mod_param * mod_param)814 hi_s32 vo_set_mod_param(const hi_vo_mod_param *mod_param)
815 {
816     hi_u32 flags = 0;
817     hi_s32 ret;
818     hi_vo_mod_param *vo_mod_param = vo_get_vo_mod_param();
819 
820     vo_check_null_ptr_return(mod_param);
821 
822     ret = vo_check_mod_param(mod_param);
823     if (ret != HI_SUCCESS) {
824         return ret;
825     }
826 
827     vo_down_sem_return();
828 
829     vo_mod_param->transparent_transmit = mod_param->transparent_transmit;
830     vo_mod_param->exit_dev = mod_param->exit_dev;
831     vo_mod_param->wbc_bg_black_en = mod_param->wbc_bg_black_en;
832     vo_mod_param->dev_clk_ext_en = mod_param->dev_clk_ext_en;
833     (hi_void)memcpy_s(&vo_mod_param->save_buf_mode, sizeof(hi_bool) * VO_MAX_PHY_DEV_NUM,
834         &mod_param->save_buf_mode, sizeof(hi_bool) * VO_MAX_PHY_DEV_NUM);
835     vo_dev_spin_lock(&flags);
836     vo_drv_transparent_transmit_setting(vo_mod_param->transparent_transmit);
837     vo_dev_spin_unlock(&flags);
838 
839     vo_up_sem();
840 
841     return HI_SUCCESS;
842 }
843 
vo_get_mod_param(hi_vo_mod_param * mod_param)844 hi_s32 vo_get_mod_param(hi_vo_mod_param *mod_param)
845 {
846     vo_check_null_ptr_return(mod_param);
847 
848     vo_down_sem_return();
849     (hi_void)memcpy_s(mod_param, sizeof(hi_vo_mod_param), vo_get_vo_mod_param(), sizeof(hi_vo_mod_param));
850     vo_up_sem();
851 
852     return HI_SUCCESS;
853 }
854 
855 #ifdef __cplusplus
856 #if __cplusplus
857 }
858 #endif
859 #endif /* end of #ifdef __cplusplus */
860