• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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