1 /*
2 * Copyright (c) 2022 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <sys/ioctl.h>
22 #include <poll.h>
23 #include <sys/time.h>
24 #include <fcntl.h>
25 #include <errno.h>
26 #include <pthread.h>
27 #include <math.h>
28 #include <unistd.h>
29 #include <signal.h>
30 #include "sample_comm.h"
31 #include "hi_mipi_tx.h"
32
33 #ifdef __cplusplus
34 #if __cplusplus
35 extern "C" {
36 #endif
37 #endif /* End of #ifdef __cplusplus */
38
39 #define SAMPLE_VO_DEF_VALUE (-1)
40
41 combo_dev_cfg_t MIPI_TX_1920X1080_60_CONFIG = {
42 .devno = 0,
43 .lane_id = {0, 1, 2, 3},
44 .output_mode = OUTPUT_MODE_DSI_VIDEO,
45 .output_format = OUT_FORMAT_RGB_24_BIT,
46 .video_mode = BURST_MODE,
47 .sync_info = {
48 .vid_pkt_size = IMG_2M_WIDTH,
49 .vid_hsa_pixels = 44,
50 .vid_hbp_pixels = 148,
51 .vid_hline_pixels = 2200,
52 .vid_vsa_lines = 5,
53 .vid_vbp_lines = 36,
54 .vid_vfp_lines = 4,
55 .vid_active_lines = IMG_2M_HEIGHT,
56 .edpi_cmd_size = 0,
57 },
58 .phy_data_rate = 945,
59 .pixel_clk = 148500,
60 };
61
62 combo_dev_cfg_t MIPI_TX_1080X1920_60_CONFIG = {
63 .devno = 0,
64 .lane_id = {0, 1, 2, 3},
65 .output_mode = OUTPUT_MODE_DSI_VIDEO,
66 .output_format = OUT_FORMAT_RGB_24_BIT,
67 .video_mode = BURST_MODE,
68 .sync_info = {
69 .vid_pkt_size = IMG_2M_HEIGHT,
70 .vid_hsa_pixels = 8,
71 .vid_hbp_pixels = 20,
72 .vid_hline_pixels = 1238,
73 .vid_vsa_lines = 10,
74 .vid_vbp_lines = 26,
75 .vid_vfp_lines = 16,
76 .vid_active_lines = IMG_2M_WIDTH,
77 .edpi_cmd_size = 0,
78 },
79 .phy_data_rate = 945,
80 .pixel_clk = 148500,
81 };
82
SAMPLE_COMM_VO_GetWH(VO_INTF_SYNC_E enIntfSync,HI_U32 * pu32W,HI_U32 * pu32H,HI_U32 * pu32Frm)83 HI_S32 SAMPLE_COMM_VO_GetWH(VO_INTF_SYNC_E enIntfSync, HI_U32 *pu32W, HI_U32 *pu32H, HI_U32 *pu32Frm)
84 {
85 CHECK_NULL_PTR(pu32W);
86 CHECK_NULL_PTR(pu32H);
87 CHECK_NULL_PTR(pu32Frm);
88
89 switch (enIntfSync) {
90 case VO_OUTPUT_1080P25:
91 *pu32W = IMG_2M_WIDTH;
92 *pu32H = IMG_2M_HEIGHT;
93 *pu32Frm = FPS_25;
94 break;
95 case VO_OUTPUT_1080P30:
96 *pu32W = IMG_2M_WIDTH;
97 *pu32H = IMG_2M_HEIGHT;
98 *pu32Frm = FPS_30;
99 break;
100 case VO_OUTPUT_1080I50:
101 *pu32W = IMG_2M_WIDTH;
102 *pu32H = IMG_2M_HEIGHT;
103 *pu32Frm = FPS_50;
104 break;
105 case VO_OUTPUT_1080I60:
106 *pu32W = IMG_2M_WIDTH;
107 *pu32H = IMG_2M_HEIGHT;
108 *pu32Frm = FPS_60;
109 break;
110 case VO_OUTPUT_1080P50:
111 *pu32W = IMG_2M_WIDTH;
112 *pu32H = IMG_2M_HEIGHT;
113 *pu32Frm = FPS_50;
114 break;
115 case VO_OUTPUT_1080P60:
116 *pu32W = IMG_2M_WIDTH;
117 *pu32H = IMG_2M_HEIGHT;
118 *pu32Frm = FPS_60;
119 break;
120 case VO_OUTPUT_800x600_60:
121 *pu32W = 800; /* width 800 */
122 *pu32H = 600; /* height 600 */
123 *pu32Frm = FPS_60;
124 break;
125 case VO_OUTPUT_800x600_50:
126 *pu32W = 800; /* width 800 */
127 *pu32H = 600; /* height 600 */
128 *pu32Frm = FPS_50;
129 break;
130 case VO_OUTPUT_1080x1920_60:
131 *pu32W = IMG_2M_HEIGHT;
132 *pu32H = IMG_2M_WIDTH;
133 *pu32Frm = FPS_60;
134 case VO_OUTPUT_USER:
135 *pu32W = 720; /* width 720 */
136 *pu32H = 576; /* height 576 */
137 *pu32Frm = FPS_25;
138 break;
139 default:
140 SAMPLE_PRT("vo enIntfSync %d not support!\n", enIntfSync);
141 return HI_FAILURE;
142 }
143
144 return HI_SUCCESS;
145 }
146
SAMPLE_COMM_VO_StartDev(VO_DEV VoDev,VO_PUB_ATTR_S * pstPubAttr)147 HI_S32 SAMPLE_COMM_VO_StartDev(VO_DEV VoDev, VO_PUB_ATTR_S *pstPubAttr)
148 {
149 HI_S32 s32Ret;
150
151 CHECK_NULL_PTR(pstPubAttr);
152
153 s32Ret = HI_MPI_VO_SetPubAttr(VoDev, pstPubAttr);
154 if (s32Ret != HI_SUCCESS) {
155 SAMPLE_PRT("failed with %#x!\n", s32Ret);
156 return s32Ret;
157 }
158
159 s32Ret = HI_MPI_VO_Enable(VoDev);
160 if (s32Ret != HI_SUCCESS) {
161 SAMPLE_PRT("failed with %#x!\n", s32Ret);
162 return s32Ret;
163 }
164
165 return s32Ret;
166 }
167
SAMPLE_COMM_VO_StopDev(VO_DEV VoDev)168 HI_S32 SAMPLE_COMM_VO_StopDev(VO_DEV VoDev)
169 {
170 HI_S32 s32Ret;
171
172 s32Ret = HI_MPI_VO_Disable(VoDev);
173 if (s32Ret != HI_SUCCESS) {
174 SAMPLE_PRT("failed with %#x!\n", s32Ret);
175 return s32Ret;
176 }
177
178 return s32Ret;
179 }
180
SAMPLE_COMM_VO_StartLayer(VO_LAYER VoLayer,const VO_VIDEO_LAYER_ATTR_S * pstLayerAttr)181 HI_S32 SAMPLE_COMM_VO_StartLayer(VO_LAYER VoLayer, const VO_VIDEO_LAYER_ATTR_S *pstLayerAttr)
182 {
183 HI_S32 s32Ret;
184
185 CHECK_NULL_PTR(pstLayerAttr);
186
187 s32Ret = HI_MPI_VO_SetVideoLayerAttr(VoLayer, pstLayerAttr);
188 if (s32Ret != HI_SUCCESS) {
189 SAMPLE_PRT("failed with %#x!\n", s32Ret);
190 return s32Ret;
191 }
192
193 s32Ret = HI_MPI_VO_EnableVideoLayer(VoLayer);
194 if (s32Ret != HI_SUCCESS) {
195 SAMPLE_PRT("failed with %#x!\n", s32Ret);
196 return s32Ret;
197 }
198
199 return s32Ret;
200 }
201
SAMPLE_COMM_VO_StopLayer(VO_LAYER VoLayer)202 HI_S32 SAMPLE_COMM_VO_StopLayer(VO_LAYER VoLayer)
203 {
204 HI_S32 s32Ret;
205
206 s32Ret = HI_MPI_VO_DisableVideoLayer(VoLayer);
207 if (s32Ret != HI_SUCCESS) {
208 SAMPLE_PRT("failed with %#x!\n", s32Ret);
209 return s32Ret;
210 }
211
212 return s32Ret;
213 }
214
SAMPLE_COMM_VO_StartChn(VO_LAYER VoLayer,SAMPLE_VO_MODE_E enMode)215 HI_S32 SAMPLE_COMM_VO_StartChn(VO_LAYER VoLayer, SAMPLE_VO_MODE_E enMode)
216 {
217 HI_U32 i;
218 HI_S32 s32Ret = HI_FAILURE;
219 HI_U32 u32WndNum = 0;
220 HI_U32 u32Square = 0;
221 HI_U32 u32Width = 0;
222 HI_U32 u32Height = 0;
223 VO_CHN_ATTR_S stChnAttr;
224 VO_VIDEO_LAYER_ATTR_S stLayerAttr;
225
226 switch (enMode) {
227 case VO_MODE_1MUX:
228 u32WndNum = 1; /* wndnum: 1 */
229 u32Square = 1; /* square: 1 */
230 break;
231 case VO_MODE_2MUX:
232 u32WndNum = 2; /* wndnum: 2 */
233 u32Square = 2; /* square: 2 */
234 break;
235 case VO_MODE_4MUX:
236 u32WndNum = 4; /* wndnum: 4 */
237 u32Square = 2; /* square: 2 */
238 break;
239 default:
240 SAMPLE_PRT("enMode is invalid!\n");
241 return s32Ret;
242 }
243
244 s32Ret = HI_MPI_VO_GetVideoLayerAttr(VoLayer, &stLayerAttr);
245 if (s32Ret != HI_SUCCESS) {
246 SAMPLE_PRT("failed with %#x!\n", s32Ret);
247 return s32Ret;
248 }
249 u32Width = stLayerAttr.stImageSize.u32Width;
250 u32Height = stLayerAttr.stImageSize.u32Height;
251 SAMPLE_PRT("u32Width:%d, u32Height:%d, u32Square:%d\n", u32Width, u32Height, u32Square);
252 for (i = 0; i < u32WndNum; i++) {
253 stChnAttr.stRect.s32X = HI_ALIGN_DOWN((u32Width / u32Square) * (i % u32Square), 2); /* 2 align */
254 stChnAttr.stRect.s32Y = HI_ALIGN_DOWN((u32Height / u32Square) * (i / u32Square), 2); /* 2 align */
255 stChnAttr.stRect.u32Width = HI_ALIGN_DOWN(u32Width / u32Square, 2); /* 2 align */
256 stChnAttr.stRect.u32Height = HI_ALIGN_DOWN(u32Height / u32Square, 2); /* 2 align */
257 stChnAttr.u32Priority = 0;
258 stChnAttr.bDeflicker = HI_FALSE;
259 s32Ret = HI_MPI_VO_SetChnAttr(VoLayer, i, &stChnAttr);
260 if (s32Ret != HI_SUCCESS) {
261 printf("%s(%d):failed with %#x!\n", __FUNCTION__, __LINE__, s32Ret);
262 return s32Ret;
263 }
264
265 s32Ret = HI_MPI_VO_EnableChn(VoLayer, i);
266 if (s32Ret != HI_SUCCESS) {
267 SAMPLE_PRT("failed with %#x!\n", s32Ret);
268 return s32Ret;
269 }
270 }
271
272 return HI_SUCCESS;
273 }
274
SAMPLE_COMM_VO_StopChn(VO_LAYER VoLayer,SAMPLE_VO_MODE_E enMode)275 HI_S32 SAMPLE_COMM_VO_StopChn(VO_LAYER VoLayer, SAMPLE_VO_MODE_E enMode)
276 {
277 HI_U32 i;
278 HI_S32 s32Ret = HI_FAILURE;
279 HI_U32 u32WndNum = 0;
280
281 switch (enMode) {
282 case VO_MODE_1MUX: {
283 u32WndNum = 1; /* wndnum: 1 */
284 break;
285 }
286 case VO_MODE_2MUX: {
287 u32WndNum = 2; /* wndnum: 2 */
288 break;
289 }
290 case VO_MODE_4MUX: {
291 u32WndNum = 4; /* wndnum: 4 */
292 break;
293 }
294 default:
295 SAMPLE_PRT("enMode is invalid!\n");
296 return s32Ret;
297 }
298
299 for (i = 0; i < u32WndNum; i++) {
300 s32Ret = HI_MPI_VO_DisableChn(VoLayer, i);
301 if (s32Ret != HI_SUCCESS) {
302 SAMPLE_PRT("failed with %#x!\n", s32Ret);
303 return s32Ret;
304 }
305 }
306
307 return s32Ret;
308 }
309
310 #ifdef CONFIG_HI_HDMI_SUPPORT
SAMPLE_COMM_VO_HdmiConvertSync(VO_INTF_SYNC_E enIntfSync,HI_HDMI_VIDEO_FMT_E * penVideoFmt)311 static HI_S32 SAMPLE_COMM_VO_HdmiConvertSync(VO_INTF_SYNC_E enIntfSync, HI_HDMI_VIDEO_FMT_E *penVideoFmt)
312 {
313 CHECK_NULL_PTR(penVideoFmt);
314
315 switch (enIntfSync) {
316 case VO_OUTPUT_1080P25:
317 *penVideoFmt = HI_HDMI_VIDEO_FMT_1080P_25;
318 break;
319 case VO_OUTPUT_1080P30:
320 *penVideoFmt = HI_HDMI_VIDEO_FMT_1080P_30;
321 break;
322 case VO_OUTPUT_1080I50:
323 *penVideoFmt = HI_HDMI_VIDEO_FMT_1080i_50;
324 break;
325 case VO_OUTPUT_1080I60:
326 *penVideoFmt = HI_HDMI_VIDEO_FMT_1080i_60;
327 break;
328 case VO_OUTPUT_1080P50:
329 *penVideoFmt = HI_HDMI_VIDEO_FMT_1080P_50;
330 break;
331 case VO_OUTPUT_1080P60:
332 *penVideoFmt = HI_HDMI_VIDEO_FMT_1080P_60;
333 break;
334 default:
335 *penVideoFmt = HI_HDMI_VIDEO_FMT_1080P_60;
336 break;
337 }
338
339 return HI_SUCCESS;
340 }
341
SAMPLE_COMM_VO_HdmiStart(VO_INTF_SYNC_E enIntfSync)342 HI_S32 SAMPLE_COMM_VO_HdmiStart(VO_INTF_SYNC_E enIntfSync)
343 {
344 HI_S32 s32Ret;
345 HI_HDMI_ATTR_S stAttr;
346 HI_HDMI_VIDEO_FMT_E enVideoFmt;
347 HI_HDMI_ID_E enHdmiId = HI_HDMI_ID_0;
348
349 s32Ret = SAMPLE_COMM_VO_HdmiConvertSync(enIntfSync, &enVideoFmt);
350 if (s32Ret != HI_SUCCESS) {
351 return s32Ret;
352 }
353
354 CHECK_RET(HI_MPI_HDMI_Init(), "HI_MPI_HDMI_Init");
355 CHECK_RET(HI_MPI_HDMI_Open(enHdmiId), "HI_MPI_HDMI_Open");
356 CHECK_RET(HI_MPI_HDMI_GetAttr(enHdmiId, &stAttr), "HI_MPI_HDMI_GetAttr");
357 stAttr.bEnableHdmi = HI_TRUE;
358 stAttr.bEnableVideo = HI_TRUE;
359 stAttr.enVideoFmt = enVideoFmt;
360 stAttr.enVidOutMode = HI_HDMI_VIDEO_MODE_YCBCR444;
361 stAttr.enDeepColorMode = HI_HDMI_DEEP_COLOR_24BIT;
362 stAttr.bxvYCCMode = HI_FALSE;
363 stAttr.enOutCscQuantization = HDMI_QUANTIZATION_LIMITED_RANGE;
364
365 stAttr.bEnableAudio = HI_FALSE;
366 stAttr.enSoundIntf = HI_HDMI_SND_INTERFACE_I2S;
367 stAttr.bIsMultiChannel = HI_FALSE;
368
369 stAttr.enBitDepth = HI_HDMI_BIT_DEPTH_16;
370
371 stAttr.bEnableAviInfoFrame = HI_TRUE;
372 stAttr.bEnableAudInfoFrame = HI_TRUE;
373 stAttr.bEnableSpdInfoFrame = HI_FALSE;
374 stAttr.bEnableMpegInfoFrame = HI_FALSE;
375
376 stAttr.bDebugFlag = HI_FALSE;
377 stAttr.bHDCPEnable = HI_FALSE;
378
379 stAttr.b3DEnable = HI_FALSE;
380 stAttr.enDefaultMode = HI_HDMI_FORCE_HDMI;
381
382 CHECK_RET(HI_MPI_HDMI_SetAttr(enHdmiId, &stAttr), "HI_MPI_HDMI_SetAttr");
383 CHECK_RET(HI_MPI_HDMI_Start(enHdmiId), "HI_MPI_HDMI_Start");
384
385 return HI_SUCCESS;
386 }
387
388 /*
389 * Name : SAMPLE_COMM_VO_HdmiStartByDyRg
390 * Desc : Another function to start hdmi, according to video's dynamic range.
391 */
SAMPLE_COMM_VO_HdmiStartByDyRg(VO_INTF_SYNC_E enIntfSync,DYNAMIC_RANGE_E enDyRg)392 HI_S32 SAMPLE_COMM_VO_HdmiStartByDyRg(VO_INTF_SYNC_E enIntfSync, DYNAMIC_RANGE_E enDyRg)
393 {
394 HI_S32 s32Ret;
395 HI_HDMI_ATTR_S stAttr;
396 HI_HDMI_VIDEO_FMT_E enVideoFmt;
397 HI_HDMI_ID_E enHdmiId = HI_HDMI_ID_0;
398
399 s32Ret = SAMPLE_COMM_VO_HdmiConvertSync(enIntfSync, &enVideoFmt);
400 if (s32Ret != HI_SUCCESS) {
401 return s32Ret;
402 }
403
404 CHECK_RET(HI_MPI_HDMI_Init(), "HI_MPI_HDMI_Init");
405 CHECK_RET(HI_MPI_HDMI_Open(enHdmiId), "HI_MPI_HDMI_Open");
406 CHECK_RET(HI_MPI_HDMI_GetAttr(enHdmiId, &stAttr), "HI_MPI_HDMI_GetAttr");
407 stAttr.bEnableHdmi = HI_TRUE;
408 stAttr.bEnableVideo = HI_TRUE;
409 stAttr.enVideoFmt = enVideoFmt;
410 stAttr.enVidOutMode = HI_HDMI_VIDEO_MODE_YCBCR444;
411 switch (enDyRg) {
412 case DYNAMIC_RANGE_SDR8:
413 stAttr.enDeepColorMode = HI_HDMI_DEEP_COLOR_24BIT;
414 break;
415 case DYNAMIC_RANGE_HDR10:
416 stAttr.enVidOutMode = HI_HDMI_VIDEO_MODE_YCBCR422;
417 break;
418 default:
419 stAttr.enDeepColorMode = HI_HDMI_DEEP_COLOR_24BIT;
420 break;
421 }
422 stAttr.bxvYCCMode = HI_FALSE;
423 stAttr.enOutCscQuantization = HDMI_QUANTIZATION_LIMITED_RANGE;
424
425 stAttr.bEnableAudio = HI_TRUE;
426 stAttr.enSoundIntf = HI_HDMI_SND_INTERFACE_I2S;
427 stAttr.bIsMultiChannel = HI_FALSE;
428
429 stAttr.enBitDepth = HI_HDMI_BIT_DEPTH_16;
430
431 stAttr.bEnableAviInfoFrame = HI_TRUE;
432 stAttr.bEnableAudInfoFrame = HI_TRUE;
433 stAttr.bEnableSpdInfoFrame = HI_FALSE;
434 stAttr.bEnableMpegInfoFrame = HI_FALSE;
435
436 stAttr.bDebugFlag = HI_FALSE;
437 stAttr.bHDCPEnable = HI_FALSE;
438
439 stAttr.b3DEnable = HI_FALSE;
440 stAttr.enDefaultMode = HI_HDMI_FORCE_HDMI;
441
442 CHECK_RET(HI_MPI_HDMI_SetAttr(enHdmiId, &stAttr), "HI_MPI_HDMI_SetAttr");
443 CHECK_RET(HI_MPI_HDMI_Start(enHdmiId), "HI_MPI_HDMI_Start");
444
445 return HI_SUCCESS;
446 }
447
SAMPLE_COMM_VO_HdmiStop(HI_VOID)448 HI_S32 SAMPLE_COMM_VO_HdmiStop(HI_VOID)
449 {
450 HI_HDMI_ID_E enHdmiId = HI_HDMI_ID_0;
451
452 HI_MPI_HDMI_Stop(enHdmiId);
453 HI_MPI_HDMI_Close(enHdmiId);
454 HI_MPI_HDMI_DeInit();
455
456 return HI_SUCCESS;
457 }
458 #endif
459
460 static void SAMPLE_COMM_VO_StartMipiTx(VO_INTF_SYNC_E enVoIntfSync);
461
462 /*
463 * Name : SAMPLE_COMM_VO_GetDefConfig
464 * Desc : An instance of SAMPLE_VO_CONFIG_S, which allows you to use vo immediately.
465 */
SAMPLE_COMM_VO_GetDefConfig(SAMPLE_VO_CONFIG_S * pstVoConfig)466 HI_S32 SAMPLE_COMM_VO_GetDefConfig(SAMPLE_VO_CONFIG_S *pstVoConfig)
467 {
468 RECT_S stDefDispRect = { 0, 0, IMG_2M_WIDTH, IMG_2M_HEIGHT };
469 SIZE_S stDefImageSize = { IMG_2M_WIDTH, IMG_2M_HEIGHT };
470 HI_U32 u32ChipId = 0;
471
472 CHECK_NULL_PTR(pstVoConfig);
473
474 pstVoConfig->VoDev = SAMPLE_VO_DEV_UHD;
475
476 HI_MPI_SYS_GetChipId(&u32ChipId);
477
478 if (HI3516C_V500 == u32ChipId) {
479 pstVoConfig->enVoIntfType = VO_INTF_BT1120;
480 } else {
481 #ifdef CONFIG_HI_HDMI_SUPPORT
482 pstVoConfig->enVoIntfType = VO_INTF_HDMI;
483 pstVoConfig->enIntfSync = VO_OUTPUT_1080P30;
484 #else
485 pstVoConfig->enVoIntfType = VO_INTF_LCD_6BIT;
486 pstVoConfig->enIntfSync = VO_OUTPUT_320x240_50;
487 #endif
488 }
489 pstVoConfig->u32BgColor = COLOR_RGB_BLUE;
490 pstVoConfig->enPixFormat = PIXEL_FORMAT_YVU_SEMIPLANAR_420;
491 pstVoConfig->stDispRect = stDefDispRect;
492 pstVoConfig->stImageSize = stDefImageSize;
493 pstVoConfig->enVoPartMode = VO_PART_MODE_SINGLE;
494 pstVoConfig->u32DisBufLen = 3; /* dis buffler len: 3 */
495 pstVoConfig->enDstDynamicRange = DYNAMIC_RANGE_SDR8;
496 pstVoConfig->enVoMode = VO_MODE_1MUX;
497
498 return HI_SUCCESS;
499 }
SAMPLE_COMM_VO_StartVO(SAMPLE_VO_CONFIG_S * pstVoConfig)500 HI_S32 SAMPLE_COMM_VO_StartVO(SAMPLE_VO_CONFIG_S *pstVoConfig)
501 {
502 RECT_S stDefDispRect = { 0, 0, IMG_2M_WIDTH, IMG_2M_HEIGHT };
503 SIZE_S stDefImageSize = { IMG_2M_WIDTH, IMG_2M_HEIGHT };
504 VO_DEV VoDev = 0;
505 VO_LAYER VoLayer = 0;
506 SAMPLE_VO_MODE_E enVoMode = 0;
507 VO_INTF_TYPE_E enVoIntfType = VO_INTF_HDMI;
508 VO_INTF_SYNC_E enIntfSync = VO_OUTPUT_1080P30;
509 DYNAMIC_RANGE_E enDstDyRg = DYNAMIC_RANGE_SDR8;
510 VO_PART_MODE_E enVoPartMode = VO_PART_MODE_SINGLE;
511 VO_PUB_ATTR_S stVoPubAttr = { 0 };
512 VO_VIDEO_LAYER_ATTR_S stLayerAttr = { 0 };
513 VO_CSC_S stVideoCSC = { 0 };
514 HI_S32 s32Ret;
515
516 CHECK_NULL_PTR(pstVoConfig);
517
518 VoDev = pstVoConfig->VoDev;
519 VoLayer = pstVoConfig->VoDev;
520 enVoMode = pstVoConfig->enVoMode;
521 enVoIntfType = pstVoConfig->enVoIntfType;
522 enIntfSync = pstVoConfig->enIntfSync;
523 enDstDyRg = pstVoConfig->enDstDynamicRange;
524 enVoPartMode = pstVoConfig->enVoPartMode;
525
526 /* Set and start VO device VoDev. */
527 #ifdef CONFIG_HI_HDMI_SUPPORT
528 stVoPubAttr.enIntfType = enVoIntfType;
529 stVoPubAttr.enIntfSync = enIntfSync;
530 #else
531 stVoPubAttr.enIntfType = VO_INTF_LCD_6BIT;
532 stVoPubAttr.enIntfSync = VO_OUTPUT_240x320_50;
533 #endif
534 stVoPubAttr.u32BgColor = pstVoConfig->u32BgColor;
535 s32Ret = SAMPLE_COMM_VO_StartDev(VoDev, &stVoPubAttr);
536 if (s32Ret != HI_SUCCESS) {
537 SAMPLE_PRT("SAMPLE_COMM_VO_StartDev failed!\n");
538 return s32Ret;
539 }
540
541 /* Set and start layer VoDev */
542 s32Ret = SAMPLE_COMM_VO_GetWH(stVoPubAttr.enIntfSync, &stLayerAttr.stDispRect.u32Width,
543 &stLayerAttr.stDispRect.u32Height, &stLayerAttr.u32DispFrmRt);
544 if (s32Ret != HI_SUCCESS) {
545 SAMPLE_PRT("SAMPLE_COMM_VO_GetWH failed!\n");
546 SAMPLE_COMM_VO_StopDev(VoDev);
547 return s32Ret;
548 }
549 stLayerAttr.bClusterMode = HI_FALSE;
550 stLayerAttr.bDoubleFrame = HI_FALSE;
551 stLayerAttr.enPixFormat = pstVoConfig->enPixFormat;
552
553 stLayerAttr.stDispRect.s32X = 0;
554 stLayerAttr.stDispRect.s32Y = 0;
555
556 if (memcmp(&pstVoConfig->stDispRect, &stDefDispRect, sizeof(RECT_S)) != 0) {
557 (HI_VOID)memcpy_s(&stLayerAttr.stDispRect, sizeof(RECT_S), &pstVoConfig->stDispRect, sizeof(RECT_S));
558 }
559 if (memcmp(&pstVoConfig->stImageSize, &stDefImageSize, sizeof(SIZE_S)) != 0) {
560 (HI_VOID)memcpy_s(&stLayerAttr.stImageSize, sizeof(SIZE_S), &pstVoConfig->stImageSize, sizeof(SIZE_S));
561 }
562 #ifdef CONFIG_HI_HDMI_SUPPORT
563 stLayerAttr.stImageSize.u32Width = stLayerAttr.stDispRect.u32Width;
564 stLayerAttr.stImageSize.u32Height = stLayerAttr.stDispRect.u32Height;
565 #else
566 stLayerAttr.stImageSize.u32Width = stLayerAttr.stDispRect.u32Width = 240; /* width: 240 */
567 stLayerAttr.stImageSize.u32Height = stLayerAttr.stDispRect.u32Height = 320; /* height: 320 */
568 #endif
569 stLayerAttr.enDstDynamicRange = pstVoConfig->enDstDynamicRange;
570 if (pstVoConfig->u32DisBufLen) {
571 s32Ret = HI_MPI_VO_SetDisplayBufLen(VoLayer, pstVoConfig->u32DisBufLen);
572 if (s32Ret != HI_SUCCESS) {
573 SAMPLE_PRT("HI_MPI_VO_SetDisplayBufLen failed with %#x!\n", s32Ret);
574 SAMPLE_COMM_VO_StopDev(VoDev);
575 return s32Ret;
576 }
577 }
578 if (enVoPartMode == VO_PART_MODE_MULTI) {
579 s32Ret = HI_MPI_VO_SetVideoLayerPartitionMode(VoLayer, enVoPartMode);
580 if (s32Ret != HI_SUCCESS) {
581 SAMPLE_PRT("HI_MPI_VO_SetVideoLayerPartitionMode failed!\n");
582 SAMPLE_COMM_VO_StopDev(VoDev);
583 return s32Ret;
584 }
585 }
586
587 s32Ret = SAMPLE_COMM_VO_StartLayer(VoLayer, &stLayerAttr);
588 if (s32Ret != HI_SUCCESS) {
589 SAMPLE_PRT("SAMPLE_COMM_VO_Start video layer failed!\n");
590 SAMPLE_COMM_VO_StopDev(VoDev);
591 return s32Ret;
592 }
593
594 if (VO_INTF_MIPI == enVoIntfType) {
595 s32Ret = HI_MPI_VO_GetVideoLayerCSC(VoLayer, &stVideoCSC);
596 if (s32Ret != HI_SUCCESS) {
597 SAMPLE_PRT("HI_MPI_VO_GetVideoLayerCSC failed!\n");
598 SAMPLE_COMM_VO_StopDev(VoDev);
599 return s32Ret;
600 }
601 stVideoCSC.enCscMatrix = VO_CSC_MATRIX_BT709_TO_RGB_PC;
602 s32Ret = HI_MPI_VO_SetVideoLayerCSC(VoLayer, &stVideoCSC);
603 if (s32Ret != HI_SUCCESS) {
604 SAMPLE_PRT("HI_MPI_VO_SetVideoLayerCSC failed!\n");
605 SAMPLE_COMM_VO_StopDev(VoDev);
606 return s32Ret;
607 }
608 }
609 s32Ret = SAMPLE_COMM_VO_StartChn(VoLayer, enVoMode);
610 if (s32Ret != HI_SUCCESS) {
611 SAMPLE_PRT("SAMPLE_COMM_VO_StartChn failed!\n");
612 SAMPLE_COMM_VO_StopLayer(VoLayer);
613 SAMPLE_COMM_VO_StopDev(VoDev);
614 return s32Ret;
615 }
616
617 #ifdef CONFIG_HI_HDMI_SUPPORT
618 if (VO_INTF_HDMI & enVoIntfType) {
619 SAMPLE_COMM_VO_HdmiStartByDyRg(enIntfSync, enDstDyRg);
620 }
621 #endif
622 if (VO_INTF_MIPI & enVoIntfType) {
623 SAMPLE_COMM_VO_StartMipiTx(enIntfSync);
624 }
625
626 return HI_SUCCESS;
627 }
628
SAMPLE_COMM_VO_StopVO(SAMPLE_VO_CONFIG_S * pstVoConfig)629 HI_S32 SAMPLE_COMM_VO_StopVO(SAMPLE_VO_CONFIG_S *pstVoConfig)
630 {
631 VO_DEV VoDev = 0;
632 VO_LAYER VoLayer = 0;
633 SAMPLE_VO_MODE_E enVoMode = VO_MODE_BUTT;
634
635 CHECK_NULL_PTR(pstVoConfig);
636
637 VoDev = pstVoConfig->VoDev;
638 VoLayer = pstVoConfig->VoDev;
639 enVoMode = pstVoConfig->enVoMode;
640
641 #ifdef CONFIG_HI_HDMI_SUPPORT
642 if (VO_INTF_HDMI & pstVoConfig->enVoIntfType) {
643 SAMPLE_COMM_VO_HdmiStop();
644 }
645 #endif
646
647 SAMPLE_COMM_VO_StopChn(VoLayer, enVoMode);
648 SAMPLE_COMM_VO_StopLayer(VoLayer);
649 SAMPLE_COMM_VO_StopDev(VoDev);
650
651 return HI_SUCCESS;
652 }
653
SAMPLE_COMM_VO_StartLayerChn(SAMPLE_COMM_VO_LAYER_CONFIG_S * pstVoLayerConfig)654 HI_S32 SAMPLE_COMM_VO_StartLayerChn(SAMPLE_COMM_VO_LAYER_CONFIG_S *pstVoLayerConfig)
655 {
656 RECT_S stDefDispRect = { 0, 0, IMG_2M_WIDTH, IMG_2M_HEIGHT };
657 SIZE_S stDefImageSize = { IMG_2M_WIDTH, IMG_2M_HEIGHT };
658 VO_LAYER VoLayer = 0;
659 VO_INTF_SYNC_E enIntfSync = VO_OUTPUT_1080P30;
660 SAMPLE_VO_MODE_E enVoMode = VO_MODE_BUTT;
661 HI_S32 s32Ret;
662 VO_VIDEO_LAYER_ATTR_S stLayerAttr;
663 HI_U32 u32Frmt, u32Width, u32Height;
664
665 CHECK_NULL_PTR(pstVoLayerConfig);
666
667 VoLayer = pstVoLayerConfig->VoLayer;
668 enIntfSync = pstVoLayerConfig->enIntfSync;
669 enVoMode = pstVoLayerConfig->enVoMode;
670
671 /* start vo layer. */
672 s32Ret = SAMPLE_COMM_VO_GetWH(enIntfSync, &u32Width, &u32Height, &u32Frmt);
673 if (s32Ret != HI_SUCCESS) {
674 printf("Can not get synchronization information!\n");
675 return HI_FAILURE;
676 }
677
678 stLayerAttr.stDispRect.s32X = 0;
679 stLayerAttr.stDispRect.s32Y = 0;
680 stLayerAttr.stDispRect.u32Width = u32Width;
681 stLayerAttr.stDispRect.u32Height = u32Height;
682 stLayerAttr.stImageSize.u32Width = u32Width;
683 stLayerAttr.stImageSize.u32Height = u32Height;
684 stLayerAttr.u32DispFrmRt = u32Frmt;
685 stLayerAttr.bDoubleFrame = HI_FALSE;
686 stLayerAttr.bClusterMode = HI_FALSE;
687 stLayerAttr.enDstDynamicRange = DYNAMIC_RANGE_SDR8;
688 stLayerAttr.enPixFormat = pstVoLayerConfig->enPixFormat;
689 stLayerAttr.stDispRect.s32X = 0;
690 stLayerAttr.stDispRect.s32Y = 0;
691 if (memcmp(&pstVoLayerConfig->stDispRect, &stDefDispRect, sizeof(RECT_S)) != 0) {
692 stLayerAttr.stDispRect = pstVoLayerConfig->stDispRect;
693 }
694 stLayerAttr.stImageSize.u32Width = stLayerAttr.stDispRect.u32Width;
695 stLayerAttr.stImageSize.u32Height = stLayerAttr.stDispRect.u32Height;
696 stLayerAttr.stImageSize.u32Width = stLayerAttr.stDispRect.u32Width;
697 stLayerAttr.stImageSize.u32Height = stLayerAttr.stDispRect.u32Height;
698 if (memcmp(&pstVoLayerConfig->stImageSize, &stDefImageSize, sizeof(SIZE_S)) != 0) {
699 stLayerAttr.stImageSize = pstVoLayerConfig->stImageSize;
700 }
701 stLayerAttr.enDstDynamicRange = pstVoLayerConfig->enDstDynamicRange;
702 if (pstVoLayerConfig->u32DisBufLen) {
703 s32Ret = HI_MPI_VO_SetDisplayBufLen(VoLayer, pstVoLayerConfig->u32DisBufLen);
704 if (s32Ret != HI_SUCCESS) {
705 SAMPLE_PRT("HI_MPI_VO_SetDisplayBufLen failed with %#x!\n", s32Ret);
706 return s32Ret;
707 }
708 }
709
710 s32Ret = SAMPLE_COMM_VO_StartLayer(VoLayer, &stLayerAttr);
711 if (s32Ret != HI_SUCCESS) {
712 SAMPLE_PRT("SAMPLE_COMM_VO_Start video layer failed!\n");
713 return s32Ret;
714 }
715
716 /* start vo channels. */
717 s32Ret = SAMPLE_COMM_VO_StartChn(VoLayer, enVoMode);
718 if (s32Ret != HI_SUCCESS) {
719 SAMPLE_PRT("SAMPLE_COMM_VO_StartChn failed!\n");
720 SAMPLE_COMM_VO_StopLayer(VoLayer);
721 return s32Ret;
722 }
723 return s32Ret;
724 }
725
SAMPLE_COMM_VO_StopLayerChn(SAMPLE_COMM_VO_LAYER_CONFIG_S * pstVoLayerConfig)726 HI_S32 SAMPLE_COMM_VO_StopLayerChn(SAMPLE_COMM_VO_LAYER_CONFIG_S *pstVoLayerConfig)
727 {
728 VO_LAYER VoLayer = 0;
729 SAMPLE_VO_MODE_E enVoMode = VO_MODE_BUTT;
730
731 CHECK_NULL_PTR(pstVoLayerConfig);
732
733 VoLayer = pstVoLayerConfig->VoLayer;
734 enVoMode = pstVoLayerConfig->enVoMode;
735
736 SAMPLE_COMM_VO_StopChn(VoLayer, enVoMode);
737 SAMPLE_COMM_VO_StopLayer(VoLayer);
738
739 return HI_SUCCESS;
740 }
741
SAMPLE_COMM_VO_Exit(void)742 HI_VOID SAMPLE_COMM_VO_Exit(void)
743 {
744 HI_S32 i = 0, j = 0;
745
746 for (i = 0; i < VO_MAX_LAYER_NUM; i++) {
747 for (j = 0; j < VO_MAX_CHN_NUM; j++) {
748 HI_MPI_VO_DisableChn(i, j);
749 }
750 }
751
752 for (i = 0; i < VO_MAX_LAYER_NUM; i++) {
753 HI_MPI_VO_DisableVideoLayer(i);
754 }
755
756 for (i = 0; i < VO_MAX_DEV_NUM; i++) {
757 HI_MPI_VO_Disable(i);
758 }
759 }
760
SAMPLE_PRIVATE_VO_InitScreen1080x1920(HI_S32 fd)761 static HI_VOID SAMPLE_PRIVATE_VO_InitScreen1080x1920(HI_S32 fd)
762 {
763 HI_S32 s32Ret;
764 cmd_info_t cmd_info;
765
766 cmd_info.devno = 0;
767 cmd_info.cmd_size = 0xeeff; /* cmd size: 0xeeff */
768 cmd_info.data_type = 0x23; /* data type: 0x23 */
769 cmd_info.cmd = NULL;
770 s32Ret = ioctl(fd, HI_MIPI_TX_SET_CMD, &cmd_info);
771 if (s32Ret != HI_SUCCESS) {
772 SAMPLE_PRT("MIPI_TX SET CMD failed\n");
773 close(fd);
774 return;
775 }
776
777 usleep(1000); /* sleep 1000 us */
778
779 cmd_info.devno = 0;
780 cmd_info.cmd_size = 0x4018; /* cmd size: 0x4018 */
781 cmd_info.data_type = 0x23; /* data type: 0x23 */
782 cmd_info.cmd = NULL;
783 s32Ret = ioctl(fd, HI_MIPI_TX_SET_CMD, &cmd_info);
784 if (s32Ret != HI_SUCCESS) {
785 SAMPLE_PRT("MIPI_TX SET CMD failed\n");
786 close(fd);
787 return;
788 }
789
790 usleep(10000); /* sleep 10000 us */
791
792 cmd_info.devno = 0;
793 cmd_info.cmd_size = 0x18; /* cmd size: 0x18 */
794 cmd_info.data_type = 0x23; /* data type: 0x23 */
795 cmd_info.cmd = NULL;
796 s32Ret = ioctl(fd, HI_MIPI_TX_SET_CMD, &cmd_info);
797 if (s32Ret != HI_SUCCESS) {
798 SAMPLE_PRT("MIPI_TX SET CMD failed\n");
799 close(fd);
800 return;
801 }
802
803 usleep(20000); /* sleep 20000 us */
804
805 cmd_info.devno = 0;
806 cmd_info.cmd_size = 0xff; /* cmd size: 0xff */
807 cmd_info.data_type = 0x23; /* data type: 0x23 */
808 cmd_info.cmd = NULL;
809 s32Ret = ioctl(fd, HI_MIPI_TX_SET_CMD, &cmd_info);
810 if (s32Ret != HI_SUCCESS) {
811 SAMPLE_PRT("MIPI_TX SET CMD failed\n");
812 close(fd);
813 return;
814 }
815
816 usleep(10000); /* sleep 10000 us */
817
818 cmd_info.devno = 0;
819 cmd_info.cmd_size = 0x1fb; /* cmd size: 0x1fb */
820 cmd_info.data_type = 0x23; /* data type: 0x23 */
821 cmd_info.cmd = NULL;
822 s32Ret = ioctl(fd, HI_MIPI_TX_SET_CMD, &cmd_info);
823 if (s32Ret != HI_SUCCESS) {
824 SAMPLE_PRT("MIPI_TX SET CMD failed\n");
825 close(fd);
826 return;
827 }
828
829 usleep(10000); /* sleep 10000 us */
830
831 cmd_info.devno = 0;
832 cmd_info.cmd_size = 0x135; /* cmd size: 0x135 */
833 cmd_info.data_type = 0x23; /* data type: 0x23 */
834 cmd_info.cmd = NULL;
835 s32Ret = ioctl(fd, HI_MIPI_TX_SET_CMD, &cmd_info);
836 if (s32Ret != HI_SUCCESS) {
837 SAMPLE_PRT("MIPI_TX SET CMD failed\n");
838 close(fd);
839 return;
840 }
841
842 usleep(10000); /* sleep 10000 us */
843
844 cmd_info.devno = 0;
845 cmd_info.cmd_size = 0xff51; /* cmd size: 0xff51 */
846 cmd_info.data_type = 0x23; /* data type: 0x23 */
847 cmd_info.cmd = NULL;
848 s32Ret = ioctl(fd, HI_MIPI_TX_SET_CMD, &cmd_info);
849 if (s32Ret != HI_SUCCESS) {
850 SAMPLE_PRT("MIPI_TX SET CMD failed\n");
851 close(fd);
852 return;
853 }
854
855 usleep(1000); /* sleep 1000 us */
856
857 cmd_info.devno = 0;
858 cmd_info.cmd_size = 0x2c53; /* cmd size: 0x2c53 */
859 cmd_info.data_type = 0x23; /* data type: 0x23 */
860 cmd_info.cmd = NULL;
861 s32Ret = ioctl(fd, HI_MIPI_TX_SET_CMD, &cmd_info);
862 if (s32Ret != HI_SUCCESS) {
863 SAMPLE_PRT("MIPI_TX SET CMD failed\n");
864 close(fd);
865 return;
866 }
867
868 usleep(1000); /* sleep 1000 us */
869
870 cmd_info.devno = 0;
871 cmd_info.cmd_size = 0x155; /* cmd size: 0x155 */
872 cmd_info.data_type = 0x23; /* data type: 0x23 */
873 cmd_info.cmd = NULL;
874 s32Ret = ioctl(fd, HI_MIPI_TX_SET_CMD, &cmd_info);
875 if (s32Ret != HI_SUCCESS) {
876 SAMPLE_PRT("MIPI_TX SET CMD failed\n");
877 close(fd);
878 return;
879 }
880
881 usleep(1000); /* sleep 1000 us */
882
883 cmd_info.devno = 0;
884 cmd_info.cmd_size = 0x24d3; /* cmd size: 0x24d3 */
885 cmd_info.data_type = 0x23; /* data type: 0x23 */
886 cmd_info.cmd = NULL;
887 s32Ret = ioctl(fd, HI_MIPI_TX_SET_CMD, &cmd_info);
888 if (s32Ret != HI_SUCCESS) {
889 SAMPLE_PRT("MIPI_TX SET CMD failed\n");
890 close(fd);
891 return;
892 }
893
894 usleep(10000); /* sleep 10000 us */
895
896 cmd_info.devno = 0;
897 cmd_info.cmd_size = 0x10d4; /* cmd size: 0x10d4 */
898 cmd_info.data_type = 0x23; /* data type: 0x23 */
899 cmd_info.cmd = NULL;
900 s32Ret = ioctl(fd, HI_MIPI_TX_SET_CMD, &cmd_info);
901 if (s32Ret != HI_SUCCESS) {
902 SAMPLE_PRT("MIPI_TX SET CMD failed\n");
903 close(fd);
904 return;
905 }
906
907 usleep(10000); /* sleep 10000 us */
908
909 cmd_info.devno = 0;
910 cmd_info.cmd_size = 0x11; /* cmd size: 0x11 */
911 cmd_info.data_type = 0x05; /* data type: 0x05 */
912 cmd_info.cmd = NULL;
913 s32Ret = ioctl(fd, HI_MIPI_TX_SET_CMD, &cmd_info);
914 if (s32Ret != HI_SUCCESS) {
915 SAMPLE_PRT("MIPI_TX SET CMD failed\n");
916 close(fd);
917 return;
918 }
919
920 usleep(200000); /* sleep 200000 us */
921
922 cmd_info.devno = 0;
923 cmd_info.cmd_size = 0x29; /* cmd size: 0x29 */
924 cmd_info.data_type = 0x05; /* data type: 0x05 */
925 cmd_info.cmd = NULL;
926 s32Ret = ioctl(fd, HI_MIPI_TX_SET_CMD, &cmd_info);
927 if (s32Ret != HI_SUCCESS) {
928 SAMPLE_PRT("MIPI_TX SET CMD failed\n");
929 close(fd);
930 return;
931 }
932 }
933
SAMPLE_PRIVATE_VO_InitMipiTxScreen(VO_INTF_SYNC_E enVoIntfSync,HI_S32 fd)934 static void SAMPLE_PRIVATE_VO_InitMipiTxScreen(VO_INTF_SYNC_E enVoIntfSync, HI_S32 fd)
935 {
936 SAMPLE_PRT("%s,%d,Init 1080p screen.\n", __FUNCTION__, __LINE__);
937 SAMPLE_PRIVATE_VO_InitScreen1080x1920(fd);
938 }
939
SAMPLE_COMM_VO_StartMipiTx(VO_INTF_SYNC_E enVoIntfSync)940 void SAMPLE_COMM_VO_StartMipiTx(VO_INTF_SYNC_E enVoIntfSync)
941 {
942 HI_S32 fd;
943 HI_S32 s32Ret;
944 combo_dev_cfg_t *pstMipiTxConfig = HI_NULL;
945
946 fd = open("/dev/hi_mipi_tx", O_RDWR);
947 if (fd < 0) {
948 SAMPLE_PRT("open hi_mipi_tx dev failed\n");
949 return;
950 }
951
952 switch (enVoIntfSync) {
953 case VO_OUTPUT_1080P60:
954 pstMipiTxConfig = &MIPI_TX_1920X1080_60_CONFIG;
955 break;
956 case VO_OUTPUT_1080x1920_60:
957 pstMipiTxConfig = &MIPI_TX_1080X1920_60_CONFIG;
958 break;
959 default:
960 pstMipiTxConfig = &MIPI_TX_1080X1920_60_CONFIG;
961 break;
962 }
963
964 s32Ret = ioctl(fd, HI_MIPI_TX_SET_DEV_CFG, pstMipiTxConfig);
965 if (s32Ret != HI_SUCCESS) {
966 SAMPLE_PRT("MIPI_TX SET_DEV_CONFIG failed\n");
967 close(fd);
968 return;
969 }
970
971 SAMPLE_PRIVATE_VO_InitMipiTxScreen(enVoIntfSync, fd);
972
973 usleep(10000); /* sleep 10000 us to enable mipitx */
974 s32Ret = ioctl(fd, HI_MIPI_TX_ENABLE);
975 if (s32Ret != HI_SUCCESS) {
976 SAMPLE_PRT("MIPI_TX enable failed\n");
977 }
978
979 close(fd);
980 fd = HI_INVALID_VALUE;
981 return;
982 }
983 #ifdef __cplusplus
984 #if __cplusplus
985 }
986 #endif
987 #endif /* End of #ifdef __cplusplus */
988