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