vBackcarMainTask
目录
xBCModulesInit 初始化videoin
xVideoinHwInit 初始创建mipi 初始化线程
vis_init 初始化g_vis_ctrl 配置mipi 初始化参数
xVideoinFillParam获取sensor驱动配置的分辨率
xVideoinHwGetInfo 配置分辨率
vendor/autochips/proprietary/tinysys/viss/os/drivers/videoin/videoin_drv_if/source/videoin_drv_if.c
xVideoinHwStart start viss 初始化mipi 获取分辨率分配buffer
xVideoinVisStart 初始化Reqbuf
vis_start 初始化mipi
__vis_mipi_config 配置mipi csirx_info 注册中断回调函数
中断处理函数
将mipi数据挂到exter_done_list
vVideoinRenderTask 获取camera数据
xVideoinTransferReadyBuffer 获取camera mipi的新数据给display buff
vis_buffer_dequeue 获取camera数据
xVideoinRequestEmptyBuffer 获取display的buf enqueue 到camera
enqueue buff vis_buffer_queue
__vis_mipi_buffer_request 获取empty buf
__vis_dp_buf_request_handler获取 exter_todo_list 上的 empty buf
分配garbagebuff 获取dma 物理地址获取mipi数据
vBackcarMainTaskvendor/autochips/proprietary/tinysys/viss/os/drivers/backcar/bc_main.cvBackcarMainTask
xBCModulesInit 初始化videoin
732 static BaseType_t xBCModulesInit( )
733 {
734 BC_DBG("enter\r\n");
735
736 #if ENABLE_UI_FUNC
737 /* ui init must come after xBCReadResourceInfo() & xBCReadAppSetting() */
738 if( pdPASS != xBCUIInit() )
739 {
740 BC_ERR("init backcar ui fail\r\n");
741 return pdFAIL;
742 }
743 #endif
744
745 #if ENABLE_VIDEO_FUNC
746 /* video init must come after xBCReadAppSetting() */
747 if( pdPASS != xBCVideoInit() )
748 {
749 BC_ERR("init backcar video fail\r\n");
750 #if ENABLE_UI_FUNC
751 xBCUIDeinit();
752 #endif
753 return pdFAIL;
754 }
755 #endif
756
757 xBCStatus = eBCStatusInit;
758
759 BC_DBG("leave\r\n");
760 return pdPASS;
761 }
vendor/autochips/proprietary/tinysys/viss/os/drivers/backcar/bc_video.c
xBCVideoInit
xVideoinHwInit 初始创建mipi 初始化线程
xVideoinHwGetInfo 配置分辨率
xVideoinHwStart初始化mipi 获取分辨率分配buff
//=======================================Public Interface for Backcar Framework========================
929 BaseType_t xBCVideoInit()
930 {
931 VideoinDataInfo_t xHwDataInfo;
932
933 BC_INFO("enter. videoin viss time: %dms\n", get_current_time_ms());
934
935 if( eVideoStatusIdle != xVideoStatus )
936 {
937 BC_ERR("can not init video at other state but Idle state. State = %d\n", xVideoStatus);
938 return pdPASS;
939 }
940
941 xVideoMutex = xSemaphoreCreateMutex();
942 if( NULL == xVideoMutex )
943 {
944 BC_ERR("xVideoMutex create fail\r\n");
945 goto error_1;
946 }
947
948 if( pdPASS != xTaskCreate( vVideoSignalTask,
949 "VideoSignalTask",
950 vdoTASK_STACK_DEPTH,
951 NULL,
952 vdoTASK_PRIORITY,
953 &xSignalTaskHandle ) )
954 {
955 BC_ERR("VideoSignalTask create fail\r\n");
956 goto error_2;
957 }
958
959 if( NULL == xSignalEventQueue )
960 {
961 xSignalEventQueue = xQueueCreate( videoQUEUE_LENGTH, sizeof( VideoSignalType_t ) );
962 if( NULL == xSignalEventQueue )
963 {
964 BC_ERR("xSignalEventQueue create fail\r\n");
965 goto error_2;
966 }
967 }
968
969 memset( &xHwInitParam, 0x0, sizeof( xHwInitParam ) );
970 xHwInitParam.ulRVCSolution = xBCAppSetting.xRvcSolution;
971 xHwInitParam.xDataPath = xBCAppSetting.xVdoDataPath;
972 xHwInitParam.xChanId = xBCAppSetting.xVdoChanId;
973 xHwInitParam.xVIPEnable = xBCAppSetting.xVdoVIPEnable;
974 xHwInitParam.xIsBt656 = xBCAppSetting.xVdoIsBt656;
975 xHwInitParam.xFmtDetectEnable = xBCAppSetting.xVdoFmtDetectEnable;
976 xHwInitParam.xDefaultFmt = xBCAppSetting.xVdoDefaultFmt;
977 xHwInitParam.pxEnqBufFunc = xVideoBufferEnqCallback;
978 xHwInitParam.pxDeqBufFunc = xVideoBufferDeqCallback;
979 xHwInitParam.ulDispBufCnt = videoDISP_BUF_CNT;初始创建mipi 初始化线程
980 if( pdPASS != xVideoinHwInit( xHwInitParam ) )
981 {
982 BC_ERR("video hardware init failed.\n");
983 goto error_2;
984 }
985 // 配置分辨率
986 if( pdPASS != xVideoinHwGetInfo( &xHwDataInfo ) )
987 {
988 BC_ERR("video hardware init failed.\n");
989 goto error_3;
990 }
991
992 if( pdPASS != xVideoSurfaceInit( xHwDataInfo ) )
993 {
994 BC_ERR("video surface init failed.\n");
995 goto error_3;
996 }
997
998 if( pdPASS != xVideoinHwStart() )
999 {
1000 BC_ERR("video hardware start failed.\n");
1001 goto error_4;
1002 }
1003 xRealSignal = pdTRUE;
1004 /** Video source set must come after video hw start */
1005 if( pdPASS != xVideoSourceSet() )
1006 {
1007 BC_ERR("video source set failed.\n");
1008 goto error_5;
1009 }
1010
1011 xVideoStatus = eVideoStatusInit;
1012 BC_INFO("leave. videoin viss time: %dms\n", get_current_time_ms());
1013 return pdPASS;
1014
1015 error_5:
1016 xRealSignal = pdFALSE;
1017 if( pdPASS != xVideoinHwStop() )
1018 {
1019 BC_ERR("video hardware stop failed.\n");
1020 }
1021 error_4:
1022 if( pdPASS != xVideoSurfaceDeinit() )
1023 {
1024 BC_ERR("video surface deinit failed.\n");
1025 }
1026 error_3:
1027 if( pdPASS != xVideoinHwDeinit() )
1028 {
1029 BC_ERR("video hardware deinit failed.\n");
1030 }
1031 error_2:
1032 if( NULL != xSignalEventQueue )
1033 {
1034 vQueueDelete( xSignalEventQueue );
1035 xSignalEventQueue = NULL;
1036 }
1037 1038 if( NULL != xSignalTaskHandle )
1039 {
1040 vTaskDelete( xSignalTaskHandle );
1041 xSignalTaskHandle = NULL;
1042 }
1043 1044 if( NULL != xVideoMutex)
1045 {
1046 vSemaphoreDelete( xVideoMutex );
1047 xVideoMutex = NULL;
1048 }
1049 error_1:
1050 BC_DBG("leave with error\r\n");
1051 return pdFAIL;
1052 }
xVideoinHwInit 初始创建mipi 初始化线程
975 BaseType_t xVideoinHwInit( VideoinInitParam_t xInitParam )
976 {
977
978 vss_printk(VSS_LOG_INFO, "enter, Video DataPath(%d), ChanId(%d)\n", xInitParam.xDataPath, xInitParam.xChanId);
979
980 if( ( NULL == xInitParam.pxDeqBufFunc ) || ( NULL == xInitParam.pxEnqBufFunc ) )
981 {
982 vss_printk(VSS_LOG_ERR, "Render Buffer Func Callback is null\n");
983 goto error;
984 }
985 //初始化videoinfo
986 memset( &xVideoinInfo, 0, sizeof( VideoinInfo_t ) );
987 xVideoinInfo.ulRVCSolution = xInitParam.ulRVCSolution;
988 xVideoinInfo.xVIPEnable = xInitParam.xVIPEnable;
989 xVideoinInfo.xRenderStart = pdFALSE;
990 xVideoinInfo.xSignalStatus = VIDEOIN_SIGNAL_NONE;
991 xVideoinInfo.pxEnqBuffFunc = xInitParam.pxEnqBufFunc;
992 xVideoinInfo.pxDeqBuffFunc = xInitParam.pxDeqBufFunc;
993 xVideoinInfo.ulFatalExcCnt = 0;
994 xVideoinInfo.ulGeneralExcCnt = 0;
995 xVideoinInfo.xSensorCtrlInfo.mode_bt656 = xInitParam.xIsBt656;
996 xVideoinInfo.xSensorCtrlInfo.sctrl_ch_detect_format = xInitParam.xFmtDetectEnable;
997 xVideoinInfo.xSensorCtrlInfo.sctrl_ch_format = xInitParam.xDefaultFmt;
998 xVideoinInfo.ulDispBufCnt = xInitParam.ulDispBufCnt;
999 xVideoinInfo.xOutParam.is_vip_enable = xInitParam.xVIPEnable;
1000 xVideoinInfo.xOutParam.data_fmt= vdoOUT_DATA_FMT;
1001 xVideoinInfo.xOutParam.buf_out_mode = 0;
1002 xVideoinInfo.xOutParam.out_stream_num = 1;
1003 xVideoinInfo.ulHue = 4;
1004 xVideoinInfo.ulBrightness = 80;
1005 xVideoinInfo.ulContrast = 115;
1006 xVideoinInfo.ulSaturation = 130;
1007
1008 switch( xInitParam.xDataPath )
1009 {
1010 case eVideoinDataPathBT656:
1011 xVideoinInfo.xDataPath = BT656;
1012 if( xInitParam.xVIPEnable )
1013 smmu_avin_init(SMMU_VIN1_INIT|SMMU_VIN2_INIT, STREAM_ID_INPUT1_BT656);
1014 else
1015 smmu_avin_init(SMMU_VIN1_INIT, STREAM_ID_INPUT1_BT656);
1016 break;
1017 case eVideoinDataPathMipi1:
1018 xVideoinInfo.xDataPath = MIPI_1;
1019 if( xInitParam.xVIPEnable )
1020 smmu_avin_init(SMMU_VIN1_INIT|SMMU_VIN2_INIT, STREAM_ID_INPUT1_MIPI1_PORT1);
1021 else
1022 smmu_avin_init(SMMU_VIN1_INIT, STREAM_ID_INPUT1_MIPI1_PORT1);
1023 break;
1024 case eVideoinDataPathMipi2:
1025 xVideoinInfo.xDataPath = MIPI_2;
1026 if( xInitParam.xVIPEnable )//初始化smmu
1027 smmu_avin_init(SMMU_VIN1_INIT|SMMU_VIN2_INIT, STREAM_ID_INPUT1_MIPI2_PORT1);
1028 else
1029 smmu_avin_init(SMMU_VIN1_INIT, STREAM_ID_INPUT1_MIPI2_PORT1);
1030 break;
1031 default:
1032 vss_printk(VSS_LOG_ERR, "videoin hw data path(%d) error\n", xInitParam.xDataPath);
1033 goto error;
1034 }
1035 //初始化channel id
1036 switch( xInitParam.xChanId )
1037 {
1038 case eVideoinChannelId0:
1039 xVideoinInfo.xChanId = CHANNEL_ID_0;
1040 xVideoinInfo.xSensorChanId = VIDEOIN_TYPE_CH0;
1041 break;
1042 case eVideoinChannelId1:
1043 xVideoinInfo.xChanId = CHANNEL_ID_1;
1044 xVideoinInfo.xSensorChanId = VIDEOIN_TYPE_CH1;
1045 break;
1046 case eVideoinChannelId2:
1047 xVideoinInfo.xChanId = CHANNEL_ID_2;
1048 xVideoinInfo.xSensorChanId = VIDEOIN_TYPE_CH2;
1049 break;
1050 case eVideoinChannelId3:
1051 xVideoinInfo.xChanId = CHANNEL_ID_3;
1052 xVideoinInfo.xSensorChanId = VIDEOIN_TYPE_CH3;
1053 break;
1054 default:
1055 vss_printk(VSS_LOG_ERR, "videoin hw channel id(%d) error\n", xInitParam.xChanId);
1056 goto error;
1057 }
1058
1059 #if READY_FOR_SENSOR_DRIVER
1060 if( pdPASS != xVideoinSensorInit() )
1061 {
1062 vss_printk(VSS_LOG_ERR, "videoin sensor init failed\r\n");
1063 goto error;
1064 }
1065 #endif
1066 // 初始创建mipi 初始化线程
1067 if( 0 != vis_init( xVideoinInfo.xDataPath, xVideoinInfo.xChanId ) )
1068 {
1069 vss_printk(VSS_LOG_ERR, "vis init failed\r\n");
1070 goto error;
1071 }
1072 vis_rvc_solution_set(xVideoinInfo.ulRVCSolution);
1073 //获取sensor配置的分辨率
1074 if( pdPASS != xVideoinFillParam() )
1075 {
1076 vss_printk(VSS_LOG_ERR, "videoin fill param failed\r\n");
1077 goto error;
1078 }
1079
1080 if( pdTRUE == xVideoinInfo.xOutParam.is_vip_enable )
1081 {
1082 if( pdPASS != xVideoinAllocVIPBuffer( xVideoinInfo.xInParam.width, xVideoinInfo.xInParam.height ) )
1083 {
1084 vss_printk(VSS_LOG_ERR, "alloc inter buffer failed\r\n");
1085 goto error;
1086 }
1087 }
1088
1089
1090 if( pdPASS != xVideoinAllocGarbageBuffer( xVideoinInfo.xInParam.width, xVideoinInfo.xInParam.height ) )
1091 {
1092 vss_printk(VSS_LOG_ERR, "alloc garbage buffer failed\r\n");
1093 goto error;
1094 }
1095
1096 xVideoinHwStartSemphr = xSemaphoreCreateBinary();
1097 if( NULL == xVideoinHwStartSemphr )
1098 {
1099 vss_printk(VSS_LOG_ERR, "Could not create Videoin Start Semaphore Handle\r\n");
1100 goto error;
1101 }
1102
1103 xVideoinMutex = xSemaphoreCreateMutex();
1104 if( NULL == xVideoinMutex )
1105 {
1106 vss_printk(VSS_LOG_ERR, "Could not create Videoin Mutex Handle\r\n");
1107 goto error;
1108 }
1109
1110 if( NULL == xExceptionQueue )
1111 {
1112 xExceptionQueue = xQueueCreate( videoinEXC_QUEUE_LENGTH, sizeof( ExceptionType_t ) );
1113 if( NULL == xExceptionQueue )
1114 {
1115 vss_printk(VSS_LOG_ERR, "Could not create exception queue \r\n");
1116 goto error;
1117 }
1118 }
1119
1120 if( pdPASS != xTaskCreate( vVideoinExceptionHandleTask,
1121 "VideoinExceptionHandleTask",
1122 videoinTASK_STACK_DEPTH,
1123 NULL,
1124 videoinTASK_PRIORITY,
1125 &xVideoinExcTaskHandle1126 ) )
1127 {
1128 vss_printk(VSS_LOG_ERR, "Could not create Videoin Exception Handle Task\r\n");
1129 goto error;
1130 }
1131
1132 if( pdPASS != xTaskCreate( vVideoinRenderTask,
1133 "VideoinRenderTask",
1134 videoinTASK_STACK_DEPTH,
1135 NULL,
1136 videoinTASK_PRIORITY,
1137 &xVideoinRenderTaskHandle ) )
1138 {
1139 vss_printk(VSS_LOG_ERR, "Could not create Videoin Render Task\r\n");
1140 goto error;
1141 }
1142
1143 vss_printk(VSS_LOG_INFO, "leave\n");
1144 return pdPASS;
1145
1146 error:
1147 xVideoinHwDeinit();
1148 vss_printk(VSS_LOG_INFO, "leave with error\n");
1149 return pdFAIL;
1150 }
vis_init 初始化g_vis_ctrl 配置mipi 初始化参数
int vis_init(enum user_data_path dp, enum channel_id ch_id)
{int i;vss_printk(VSS_LOG_INFO, "enter\n");memset(&g_vis_ctrl, 0, sizeof(struct vis_ctrl));g_vis_ctrl.user_dp = dp;switch (g_vis_ctrl.user_dp) {case MIPI_1:g_vis_ctrl.dp= DP_MIPI_1;break;case MIPI_2://配置datapath为mipi2g_vis_ctrl.dp = DP_MIPI_2;break;case BT656:g_vis_ctrl.dp = DP_656;break;default:vss_printk(VSS_LOG_WARNING, "Unsupported data path(%u)!\n", g_vis_ctrl.user_dp);return -VSS_INVALID_PARAM;}g_vis_ctrl.ch_id = ch_id;g_vis_ctrl.port_id = DMA_PORT_1;g_vis_ctrl.pfn_notify = NULL;g_vis_ctrl.is_tpg_enable = false;g_vis_ctrl.type = COLOR_BAR_480I60;g_vis_ctrl.dp_need_drop = DP_NEED_DROP_FRAME_CNT;g_vis_ctrl.dp_already_drop = 0;g_vis_ctrl.vip_need_drop = VIP_NEED_DROP_FRAME_CNT;g_vis_ctrl.vip_already_drop = 0;g_vis_ctrl.buf_flow_log_lvl = VSS_LOG_DEBUG;vListInitialise(&g_vis_ctrl.exter_todo_list.list);vListInitialise(&g_vis_ctrl.exter_done_list.list);vListInitialise(&g_vis_ctrl.inter_todo_list.list);vListInitialise(&g_vis_ctrl.inter_done_list.list);g_vis_ctrl.exter_done_list_wq = xSemaphoreCreateBinary();g_vis_ctrl.exter_todo_list.insert_idx = 0;g_vis_ctrl.exter_done_list.insert_idx = 0;g_vis_ctrl.inter_todo_list.insert_idx = 0;g_vis_ctrl.inter_done_list.insert_idx = 0;for (i = 0; i < (int)FRAME_BUFFERS_CNT; i++) {vListInitialiseItem(&g_vis_ctrl.exter_todo_list.bufs[i].list_node);listSET_LIST_ITEM_OWNER(&g_vis_ctrl.exter_todo_list.bufs[i].list_node, &g_vis_ctrl.exter_todo_list.bufs[i]);vListInitialiseItem(&g_vis_ctrl.exter_done_list.bufs[i].list_node);listSET_LIST_ITEM_OWNER(&g_vis_ctrl.exter_done_list.bufs[i].list_node, &g_vis_ctrl.exter_done_list.bufs[i]);vListInitialiseItem(&g_vis_ctrl.inter_todo_list.bufs[i].list_node);listSET_LIST_ITEM_OWNER(&g_vis_ctrl.inter_todo_list.bufs[i].list_node, &g_vis_ctrl.inter_todo_list.bufs[i]);vListInitialiseItem(&g_vis_ctrl.inter_done_list.bufs[i].list_node);listSET_LIST_ITEM_OWNER(&g_vis_ctrl.inter_done_list.bufs[i].list_node, &g_vis_ctrl.inter_done_list.bufs[i]);}__vis_request_irq();vss_printk(VSS_LOG_INFO, "leave\n");return VSS_NO_ERROR;
}
xVideoinFillParam获取sensor驱动配置的分辨率
842 static BaseType_t xVideoinFillParam()
843 {
844 struct sensor_out_params xSensorOutParams;
845
846 memset( &xSensorOutParams, 0, sizeof( xSensorOutParams ) );
847 //获取sensor驱动配置的分辨率
848 if( 0 != sensor_drv_get_info( xVideoinInfo.xDataPath, xVideoinInfo.xSensorChanId, &xSensorOutParams))
849 {
850 vss_printk(VSS_LOG_WARNING, "sensor_drv_get_info return default setting\n");
851 }
852
853 xVideoinInfo.xInParam = xSensorOutParams.vis_in_param;
854 xVideoinInfo.xInParam.ch_num = 1;
855 for( int ch = CHANNEL_ID_0; ch < CHANNEL_ID_MAX; ch++ )
856 {
857 if( ch == xVideoinInfo.xChanId )
858 xVideoinInfo.xInParam.ch_enable[ch] = true;
859 else
860 xVideoinInfo.xInParam.ch_enable[ch] = false;
861 }
862 vss_printk(VSS_LOG_INFO, "sensor info width(%d), height(%d), interlace(%d)\n",
863 xVideoinInfo.xInParam.width, xVideoinInfo.xInParam.height, xVideoinInfo.xInParam.is_interlace);
864
865 if( xVideoinInfo.xOutParam.is_vip_enable && xVideoinInfo.xInParam.is_interlace ) {
866 if( NTSC == xVideoinInfo.xInParam.fmt ) {
867 xVideoinInfo.xOutParam.width = g_format_list[NTSC].width;
868 xVideoinInfo.xOutParam.height = g_format_list[NTSC].height * 2;
869 } else if( PAL == xVideoinInfo.xInParam.fmt ) {
870 xVideoinInfo.xOutParam.width = g_format_list[PAL].width;
871 xVideoinInfo.xOutParam.height = g_format_list[NTSC].height * 2;
872 } else {
873 vss_printk(VSS_LOG_WARNING, "format is not Ntsc nor Pal. use sensor input w and h*2 as default output\n");
874 xVideoinInfo.xOutParam.width = xVideoinInfo.xInParam.width;
875 xVideoinInfo.xOutParam.height = xVideoinInfo.xInParam.height * 2; //because of VIP-DI process
876 }
877 } else {
878 xVideoinInfo.xOutParam.width = xVideoinInfo.xInParam.width; //use in param h/w as default
879 xVideoinInfo.xOutParam.height = xVideoinInfo.xInParam.height;
880 }
881
882 dma_line_size_get_by_alignstride(xVideoinInfo.xOutParam.line_stride[MOP_1],
883 xVideoinInfo.xOutParam.width, xVideoinInfo.xOutParam.data_fmt);
884
885 return pdPASS;
886 }
xVideoinHwGetInfo 配置分辨率
vendor/autochips/proprietary/tinysys/viss/os/drivers/videoin/videoin_drv_if/source/videoin_drv_if.c
1223 BaseType_t xVideoinHwGetInfo( VideoinDataInfo_t *xDataInfo )
1224 {
1225 vss_printk(VSS_LOG_INFO, "enter\n");
1226
1227 if( ( 0 == xVideoinInfo.xOutParam.width )
1228 || ( 0 == xVideoinInfo.xOutParam.height )
1229 || ( vdoOUT_DATA_FMT != xVideoinInfo.xOutParam.data_fmt ) )
1230 {
1231 vss_printk(VSS_LOG_ERR, "param is invalid. w(%d), h(%d), fmt(%d)\n",
1232 xVideoinInfo.xOutParam.width, xVideoinInfo.xOutParam.height, xVideoinInfo.xOutParam.data_fmt);
1233 return pdFAIL;
1234 }
1235
1236 xDataInfo->xDataFmt = xVideoinInfo.xOutParam.data_fmt;
1237 xDataInfo->ulHeight = xVideoinInfo.xOutParam.height;
1238 xDataInfo->ulWidth = xVideoinInfo.xOutParam.width;
1239
1240 vss_printk(VSS_LOG_INFO, "leave\n");
1241 return pdPASS;
1242 }
xVideoinHwStart start viss 初始化mipi 获取分辨率分配buffer
BaseType_t xVideoinHwStart()
{vss_printk(VSS_LOG_INFO, "enter, status(%d)\n", xVideoinInfo.xStatus);xSemaphoreTake( xVideoinMutex, portMAX_DELAY );if( eVideoinStatusStarted == xVideoinInfo.xStatus ){vss_printk(VSS_LOG_INFO, "no need to start Videoin with xStatus(%d)\n", xVideoinInfo.xStatus);xSemaphoreGive( xVideoinMutex );return pdPASS;}if( pdPASS != xVideoinVisStart() ){vss_printk(VSS_LOG_ERR, "xVideoinVisStart error\n");goto error;}#if READY_FOR_SENSOR_DRIVERif( 0 != sensor_drv_start( xVideoinInfo.xDataPath, xVideoinInfo.xSensorChanId ) ){vss_printk(VSS_LOG_ERR, "sensor_drv_start failed\n");goto error;}
#endif/* fix mipi size error prob. move rpp_start out of mipi_start and call after sensor_start*/if (MIPI_2 == xVideoinInfo.xDataPath || MIPI_1 == xVideoinInfo.xDataPath) {mipi_rpp_start(xVideoinInfo.xDataPath);}xVideoinInfo.xRenderStart = pdTRUE;xVideoinInfo.xStatus = eVideoinStatusStarted;xVideoinHwSetHue( xVideoinInfo.ulHue );xVideoinHwSetBrightness( xVideoinInfo.ulBrightness );xVideoinHwSetSaturation( xVideoinInfo.ulSaturation );xVideoinHwSetContrast( xVideoinInfo.ulContrast );xSemaphoreGive( xVideoinMutex );xSemaphoreGive( xVideoinHwStartSemphr );vss_printk(VSS_LOG_INFO, "leave\n");return pdPASS;error:vss_printk(VSS_LOG_ERR, "leave with error\n");xSemaphoreGive( xVideoinMutex );return pdFAIL;
}
xVideoinVisStart 初始化Reqbuf
//======================================Private Interface For Exception Handle End===============================
692
693 static BaseType_t xVideoinVisStart()
694 {
695 int idx = 0;
696 vss_printk(VSS_LOG_INFO, "enter\n");
697
698 if( 0 != vis_notify_register( vVideoinVisNotify ) )
699 {
700 vss_printk(VSS_LOG_ERR, "vis register notify failed\n");
701 return pdFAIL;
702 }
703
704 #if READY_FOR_SENSOR_DRIVER
705 if( 0 != vis_tpg_set( COLOR_BAR_480I60, false ) )
706 #else
707 if( 0 != vis_tpg_set( COLOR_BAR_480I60, true ) )
708 #endif
709 {
710 vss_printk(VSS_LOG_ERR, "vis tpg set failed\n");
711 return pdFAIL;
712 }
713
714 for( idx = 0; idx < VIS_SRC_BUF_CNT; idx++ )
715 {
716 if( pdPASS != xVideoinRequestEmptyBuffer() )
717 {
718 vss_printk(VSS_LOG_INFO, " deq empty buffer failed. idx(%d)\n", idx);
719 }
720 }
721
722 if( xVideoinInfo.xOutParam.is_vip_enable )
723 {
724 if( 0 != vis_inter_buffer_prepare( &xVideoinInfo.xInterBuf ) )
725 {
726 vss_printk(VSS_LOG_ERR, "vis inter buffer prepare failed\n");
727 return pdFAIL;
728 }
729 }
730
731 if( 0 != vis_start( &xVideoinInfo.xInParam, &xVideoinInfo.xOutParam, false ) )
732 {
733 vss_printk(VSS_LOG_ERR, "vis start failed\n");
734 return pdFAIL;
735 }
736
737 vss_printk(VSS_LOG_INFO, "leave\n");
738 return pdPASS;
739 }
vis_start 初始化mipi
vendor/autochips/proprietary/tinysys/viss/os/drivers/videoin/vis/source/vis_if.c
1039 int vis_start(struct dev_param *pdev, struct out_param *pout, bool is_restart)1040 {
1041 int ret = VSS_NO_ERROR;
1042 vss_printk(VSS_LOG_INFO, "enter\n");
1043
1044 if (0 == g_vis_ctrl.garbage_buf.y_pa) {
1045 vss_printk(VSS_LOG_ERR, "garbage buf not set yet, can not start\n");
1046 return -VSS_INVALIDE_OPS;
1047 }
1048
1049 if (!is_restart)
1050 __vis_clock_enable();
1051
1052 switch (g_vis_ctrl.dp) {
1053 case DP_MIPI_1:
1054 case DP_MIPI_2:
1055 mipi_init(g_vis_ctrl.dp);
1056 break;
1057 case DP_656:
1058 dp656_init();
1059 break;
1060 default:
1061 vss_printk(VSS_LOG_WARNING, "Unsupported data path(%u)!\n", g_vis_ctrl.dp);
1062 return -VSS_INVALID_PARAM;
1063 }
1064
1065 memcpy(&g_vis_ctrl.out_para, pout, sizeof(struct out_param));
1066 memcpy(&g_vis_ctrl.in_para, pdev, sizeof(struct dev_param));
1067 vss_printk(VSS_LOG_INFO, " user_dp(%d) ch_id(%u)", g_vis_ctrl.dp, g_vis_ctrl.ch_id);
1068 vss_printk(VSS_LOG_INFO, " dev param: width(%u), height(%u), iterlacing(%u), chnum(%u) is_bt656(%d)",
1069 pdev->width, pdev->height, pdev->is_interlace, pdev- >ch_num, pdev->is_bt656);
1070 vss_printk(VSS_LOG_INFO, "out param: width(%u), height(%u), format(%u), store mode(%u), vip enable(%d)",
1071 pout->width, pout->height, pout->data_fmt, pout- >buf_out_mode, pout->is_vip_enable);
1072
1073 if( pdev->drop_frames > g_vis_ctrl.dp_need_drop)
1074 g_vis_ctrl.dp_need_drop = pdev->drop_frames;
1075
1076 switch (g_vis_ctrl.dp) {
1077 case DP_MIPI_1:
1078 case DP_MIPI_2:
1079 ret = __vis_mipi_config(pdev, pout);
1080 if (VSS_NO_ERROR != ret) {
1081 vss_printk(VSS_LOG_ERR, "vis mipi config failed\n");
1082 return ret;
1083 }
1084 ret = mipi_start(g_vis_ctrl.dp);
1085 if (VSS_NO_ERROR != ret) {
1086 vss_printk(VSS_LOG_ERR, "vis mipi start failed\n");
1087 return ret;
1088 }
1089 break;
1090 case DP_656:
1091 ret = __vis_dp656_config(pdev, pout);
1092 if (VSS_NO_ERROR != ret) {
1093 vss_printk(VSS_LOG_ERR, "vis dp656 config failed\n");
1094 return ret;
1095 }
1096 ret = dp656_start();
1097 if (VSS_NO_ERROR != ret) {
1098 vss_printk(VSS_LOG_ERR, "vis dp656 start failed\n");
1099 return ret;
1100 }
1101 break;
1102 default:
1103 vss_printk(VSS_LOG_WARNING, "Unsupported data path(%u)!\n", g_vis_ctrl.dp);
1104 ret = -VSS_INVALID_PARAM;
1105 break;
1106 }
1107
1108 vss_printk(VSS_LOG_INFO, "leave\n");
1109 return ret;
1110
1111 }
__vis_mipi_config 配置mipi csirx_info 注册中断回调函数
367 static int __vis_mipi_config(struct dev_param *pdev, struct out_param *pout)
368 {
369 int ret = VSS_NO_ERROR;
370 struct mipi_comm_param comm_param;
371 struct mipi_channel_param channel_param;
372 struct vip_param _vip_param;
373 struct sensor_info *s_info = NULL;
374
375 vss_printk(VSS_LOG_WARNING, "xVideoinInfo.xOutParam.is_vip_enable = (%d)\n", g_vis_ctrl.out_para.is_vip_enable);
376
377 if (pout->out_stream_num != 1) {
378 vss_printk(VSS_LOG_ERR, "Multi streams(%d) is not surpport yet\n", pout->out_stream_num);
379 return VSS_INVALIDE_OPS;
380 }
381
382 /**1. get mipi common setting*/
383 memset(&comm_param, 0, sizeof(struct mipi_comm_param));
384 comm_param.tpg_enable = g_vis_ctrl.is_tpg_enable;
385 comm_param.tpg_type = g_vis_ctrl.type;
386 if (comm_param.tpg_enable) {
387 vss_printk(VSS_LOG_INFO, "Mipi tpg is enbaled, type(%u).\n", comm_param.tpg_type);
388 } else {
389 vss_printk(VSS_LOG_INFO, "Mipi tpg is disabled.\n");
390 }//配置mipi csirx_info
391 memcpy(&comm_param.csirx_info, pdev->crx_info, sizeof(struct csirx_info));
392 ret = mipi_comm_config(g_vis_ctrl.dp, &comm_param);
393 if (ret) {
394 vss_printk(VSS_LOG_ERR, "mipi_comm_config err ret(%d).",ret);
395 return ret;
396 }//注册中断回调函数
397 ret = mipi_callback_register(__vis_mipi_buffer_done_handler, __vis_mipi_buffer_request, __vis_exc_notify_handler, g_vis_ctrl.dp);
398 if (ret) {
399 vss_printk(VSS_LOG_ERR, "mipi_callback_register err ret(%d).",ret);
400 return ret;
401 }
402
403 /**2. get mipi channel & sensor setting*/
404 memset(&channel_param, 0, sizeof(struct mipi_channel_param));
405 s_info = &channel_param.sensor_info;
406 s_info->acq_property.bt656_mode = pdev->is_bt656 ? 0b1 : 0b0;
407 s_info->acq_property.first_field = pdev->is_top_first ? 0b1 : 0b0;
408 s_info->acq_property.channel_number = pdev->ch_num - 1;
409 s_info->acq_property.ileave_format = pdev->interleave_mode;
410 s_info->acq_property.data_width = 0b0;
411 s_info->acq_property.field_polarity = pdev->field_polority;
412 s_info->acq_property.hsync_polarity = pdev->sensor_hsync_polority;
413 s_info->acq_property.vsync_polarity = pdev->sensor_vsync_polority;
414 s_info->acq_property.vid_eavsav_en = pdev->is_chid_in_saveav ? 0b1 : 0b0;
415 s_info->acq_property.vdet_eavsav_en = pdev->is_vdet_enable ? 0b1 : 0b0;
416 s_info->height = pdev->height;
417 s_info->width = pdev->width;
418 s_info->h_offs = pdev->h_offs;
419 s_info->v_offs = pdev->v_offs;
420 //配置数据类型和port
421 channel_param.src_fmt = pdev->data_format;
422 channel_param.mop_num = MOP_1;
423 channel_param.out1_buf_num = FRAME_BUFFERS_CNT;
424 channel_param.out1_buf_mode = pout->buf_out_mode;
425 if (g_vis_ctrl.out_para.is_vip_enable) {
426 channel_param.out1_width = pdev->width;
427 channel_param.out1_height = pdev->height;
428 channel_param.out1_format = VIS_YUYV;
429 channel_param.module_flag.nr_2d_enable = 0b0;
430 vis_dma_line_size_get(&channel_param.line_stride[MOP_1][0],
431channel_param.out1_width,
432 BUFS_SINGEL_CHANNEL,
433 VIS_UYVY);
434 } else {
435 channel_param.out1_width = pout->width;
436 channel_param.out1_height = pout->height;
437 channel_param.out1_format = pout->data_fmt;
438 channel_param.module_flag.nr_2d_enable = 0b0; //may cause OVERFLOW exception, disable for now
439 memcpy(&channel_param.line_stride[MOP_1][0],&pout->line_stride[MOP_1] [0],sizeof(pout->line_stride[MOP_1]));
440 }
441 channel_param.module_flag.gamma_enable = 0b1;
442 channel_param.module_flag.cproc_enable = 0b1;
443 channel_param.module_flag.sharpness_enable = 0b0; //may cause OVERFLOW exception, disable for now
444
445 ret = mipi_ch_config(g_vis_ctrl.dp, g_vis_ctrl.ch_id, &channel_param);
446 if (ret) {
447 vss_printk(VSS_LOG_ERR, "mipi_ch_config err ret(%d).",ret);
448 return ret;
449 }
450
451 /**4. config vip (if vip is enable) */
452 if (g_vis_ctrl.out_para.is_vip_enable) {
453 memset(&_vip_param, 0, sizeof(_vip_param));
454 _vip_param.is_progressive = !pdev->is_interlace;
455 _vip_param.in_fmt = VIS_YUYV;
456 _vip_param.in_height = pdev->height; //dscale is excuted in vip dp
457 _vip_param.in_width = pdev->width;
458 _vip_param.out_height = pout->height;
459 _vip_param.out_width = pout->width;
460 _vip_param.dsl1_out_fmt = pout->data_fmt;
461 _vip_param.nr2d_en = MODE_ACTIVE;
462 _vip_param.nr3d_en = MODE_ACTIVE;
463 _vip_param.out_stream_num = pout->out_stream_num;
464 _vip_param.in_mode = BUFS_SINGEL_CHANNEL;
465 _vip_param.avdif21_out_mode = pout->buf_out_mode;
466 memcpy(&_vip_param.line_size1[0], &pout->line_stride[MOP_1][0], sizeof(pout->line_stride[MOP_1]));
467 ret = vip_init();
468 if (ret) {
469 vss_printk(VSS_LOG_ERR, "vip_init err ret(%d).",ret);
470 return ret;
471 }
472 ret = vip_config(&_vip_param);
473 if (ret) {
474 vss_printk(VSS_LOG_ERR, "vip_config err ret(%d).",ret);
475 return ret;
476 }
477 vip_cb_register(__vis_vip_buffer_done_handler);
478 }
479
480 return ret;
481 }
中断处理函数
static int __vis_mipi_buffer_done_handler(enum data_path dp,enum mop_id port_id,enum channel_id ch_id,struct buf_info *buf)
{if (dp != g_vis_ctrl.dp) {vss_printk(VSS_LOG_ERR, "dp is not correct, cur dp(%d), right dp(%d)", dp, g_vis_ctrl.dp);return -VSS_INVALID_PARAM;}if (ch_id != g_vis_ctrl.ch_id) {vss_printk(VSS_LOG_ERR, "ch_id is not correct, cur ch_id(%d), right ch_id(%d)", ch_id, g_vis_ctrl.ch_id);return -VSS_INVALID_PARAM;}if (port_id != g_vis_ctrl.port_id) {vss_printk(VSS_LOG_ERR, "dp is not correct, cur port_id(%d), right port_id(%d)", port_id, g_vis_ctrl.port_id);return -VSS_INVALID_PARAM;}if (VSS_NO_ERROR != __vis_dp_buf_done_handler(buf)) {vss_printk(g_vis_ctrl.buf_flow_log_lvl, "buffer done process failed");return -VSS_ERROR_MAX;}return VSS_NO_ERROR;
}
将mipi数据挂到exter_done_list
134 static int __vis_dp_buf_done_handler(struct buf_info *buf)
135 {
136 struct buf_info *psrcbuf = NULL;
137 struct buf_info *pdstbuf = NULL;
138 BaseType_t xHigherPriorityTaskWoken = pdFALSE;
139
140 if ((NULL == buf) || (0 == buf->y_pa)) {
141 vss_printk(VSS_LOG_ERR, "buf is null or buf addr is 0\n");
142 return -VSS_INVALID_PARAM;
143 }
144
145 vss_printk(g_vis_ctrl.buf_flow_log_lvl, "done buf y_pa(0x%08x%08x), idx(%ld)\n", ul2ui(buf->y_pa), buf->buf_idx);
146
147 if (buf->y_pa == g_vis_ctrl.garbage_buf.y_pa) {
148 vss_printk(g_vis_ctrl.buf_flow_log_lvl, "garbage buffer done, do nothing!\n");
149 return VSS_NO_ERROR;
150 }
151
152 if (g_vis_ctrl.dp_already_drop < g_vis_ctrl.dp_need_drop) {
153 if (g_vis_ctrl.out_para.is_vip_enable) {
154 __vis_buf_list_push(&g_vis_ctrl.inter_todo_list, *buf, true);
155 } else {
156 __vis_buf_list_push(&g_vis_ctrl.exter_todo_list, *buf, true);
157 }
158 g_vis_ctrl.dp_already_drop++;
159 vss_printk(VSS_LOG_INFO, "drop frames cnt(%d)!\n", g_vis_ctrl.dp_already_drop);
160 return VSS_NO_ERROR;
161 }
162
163 if (g_vis_ctrl.out_para.is_vip_enable) {
164 /** deq a extern todo buf to vip process*/
165 pdstbuf = __vis_buf_list_pop(&g_vis_ctrl.exter_todo_list, true);
166 if (NULL == pdstbuf) {
167 vss_printk(g_vis_ctrl.buf_flow_log_lvl, "vip dst buf get failed, give back this done buffer to todo_list\n");
168 __vis_buf_list_push(&g_vis_ctrl.inter_todo_list, *buf, true);
169 return -VSS_ERROR_MAX;
170 }
171 /** add this done buf to inter done list*/
172 __vis_buf_list_push(&g_vis_ctrl.inter_done_list, *buf, true);
173 /** deq a intern done buf to vip process*/
174 psrcbuf = __vis_buf_list_pop(&g_vis_ctrl.inter_done_list, true);
175 if (NULL == psrcbuf) {
176 vss_printk(g_vis_ctrl.buf_flow_log_lvl, "vip src buf get failed, give back exter todo buffer to todo_list\n");
177 __vis_buf_list_push(&g_vis_ctrl.exter_todo_list, *pdstbuf, true);
178 return -VSS_ERROR_MAX;
179 }
180 pdstbuf->y_addr = pdstbuf->y_va_vip;
181 pdstbuf->cb_addr = pdstbuf->cb_va_vip;
182 pdstbuf->cr_addr = pdstbuf->cr_va_vip;
183 psrcbuf->y_addr = psrcbuf->y_va_vip;
184 psrcbuf->cb_addr = psrcbuf->cb_va_vip;
185 psrcbuf->cr_addr = psrcbuf->cr_va_vip;
186 vss_printk(g_vis_ctrl.buf_flow_log_lvl, "vip process: src y_pa(0x%08x%08x), idx(%ld); dst y_pa(0x%08x%08x), idx(%ld)\n",
187 ul2ui(psrcbuf->y_pa), psrcbuf->buf_idx, ul2ui(pdstbuf- >y_pa), pdstbuf->buf_idx);
188 vip_frame_process_async(psrcbuf, pdstbuf, NULL, 0);
189 } else {
190 /**1. add this done buf to exter done list*/
191 __vis_buf_list_push(&g_vis_ctrl.exter_done_list, *buf, true);
192
193 /**2. wake up exter_done_list_wq */
194 xSemaphoreGiveFromISR(g_vis_ctrl.exter_done_list_wq, &xHigherPriorityTaskWoken);
195 //portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
196
197 /**3. notify buffer done throw callback*/
198 if (NULL != g_vis_ctrl.pfn_notify) {
199 g_vis_ctrl.pfn_notify(BUFFER_DONE_EVENT, NULL, NULL);
200 }
201 }
202
203 return VSS_NO_ERROR;
204 }
vVideoinRenderTask 获取camera数据
void vVideoinRenderTask( void *pvParameters )
{uint32_t ulRenderBlkCnt = 0;vss_printk(VSS_LOG_INFO, "enter\n");(void)pvParameters;for( ; ; ){if( xVideoinInfo.xStatus != eVideoinStatusStarted ){xSemaphoreTake( xVideoinHwStartSemphr, portMAX_DELAY );}if( pdFALSE == xVideoinInfo.xRenderStart ){xVideoinInfo.xIsRenderStopped = pdTRUE;vTaskDelay(pdMS_TO_TICKS(50));continue;}if( VIDEOIN_SIGNAL_READY != xVideoinInfo.xSignalStatus ){if( ulRenderBlkCnt <= xVideoinInfo.ulDispBufCnt ) {xVideoinRenderBlackFrame( pdTRUE );ulRenderBlkCnt++;} else {xVideoinRenderBlackFrame( pdFALSE );}vTaskDelay(pdMS_TO_TICKS(100));continue;}ulRenderBlkCnt = 0;//Step1: deq ready buffer from vis to displayif( pdPASS != xVideoinTransferReadyBuffer() ){vss_printk(VSS_LOG_DEBUG, " enq ready buffer from vis to display failed\n");}//Step2: deq empty buffer from display to visif( pdPASS != xVideoinRequestEmptyBuffer() ){vss_printk(VSS_LOG_DEBUG, " deq empty buffer from display to vis failed\n");}}vTaskDelete(NULL);
}
xVideoinTransferReadyBuffer 获取camera mipi的新数据给display buff
static BaseType_t xVideoinTransferReadyBuffer()
{CapturePriv_t xPrivData;PortBuffer_t xVisBuf;uint32_t ulWaitTime = 200; //msif( NULL == xVideoinInfo.pxEnqBuffFunc ){vss_printk(VSS_LOG_ERR, " enq buffer callback is null\n");return pdFAIL;}memset( &xPrivData, 0, sizeof( CapturePriv_t ) );memset( &xVisBuf, 0, sizeof( PortBuffer_t ) );if( vis_buffer_dequeue( &xVisBuf, ulWaitTime ) ){vss_printk(VSS_LOG_DEBUG, "vis_deq_buffer error\n");return pdFAIL;}#if VDO_DEBUG_BUFFER_FLOWvss_printk(VSS_LOG_INFO, "y_pa(0x%08x%08x), y_va_vdo(0x%08lx), y_va_vip(0x%08lx).\r\n",ul2ui(xVisBuf.y_pa), xVisBuf.y_va_vdo, xVisBuf.y_va_vip);
#endifswitch( xVisBuf.plane_cnt ){case 1:xPrivData.xYCAddr.y = xVisBuf.y_pa;break;case 2:xPrivData.xYCAddr.y = xVisBuf.y_pa;xPrivData.xYCAddr.c = xVisBuf.cb_pa;break;default:vss_printk(VSS_LOG_ERR, " plane count(%d) is invalid for now\n", xVisBuf.plane_cnt);return pdFAIL;}xPrivData.ulPlaneCnt = xVisBuf.plane_cnt;xPrivData.ulBufWidth = xVideoinInfo.xOutParam.width;xPrivData.ulBufHeight = xVideoinInfo.xOutParam.height;xPrivData.xSignalStatus = eSignalNone;//将camera 数据enqueue到display的 queueif( pdPASS != xVideoinInfo.pxEnqBuffFunc( &xPrivData ) ){vss_printk(VSS_LOG_DEBUG, " enq ready buffer to display failed, que this buffer back to vis\n");if( vis_buffer_queue( &xVisBuf ) ){vss_printk(VSS_LOG_DEBUG, "vis_que_buffer error\n");}return pdFAIL;}return pdPASS;
}
vis_buffer_dequeue 获取camera数据
//from vis to display to transfer done buffer
int vis_buffer_dequeue(struct port_buffer *user_buf, int wait_time_ms)
{struct buf_info *pbuf = NULL;if (NULL == user_buf) {vss_printk(VSS_LOG_ERR, "user_buf is null\n");return -VSS_INVALID_PARAM;}/** if empty, should wait **/vss_printk(g_vis_ctrl.buf_flow_log_lvl, "done list cnt(%ld)\n", listCURRENT_LIST_LENGTH(&g_vis_ctrl.exter_done_list.list));vss_printk(g_vis_ctrl.buf_flow_log_lvl, "todo list cnt(%ld)\n", listCURRENT_LIST_LENGTH(&g_vis_ctrl.exter_todo_list.list));if (listCURRENT_LIST_LENGTH(&g_vis_ctrl.exter_done_list.list) <= (UBaseType_t)0) {xSemaphoreTake(g_vis_ctrl.exter_done_list_wq, pdMS_TO_TICKS(wait_time_ms));if (listCURRENT_LIST_LENGTH(&g_vis_ctrl.exter_done_list.list) <= (UBaseType_t)0) {//vss_printk(VSS_LOG_ERR, "buffer done list is still empty after (%d)ms wait\n", wait_time_ms);//g_vis_ctrl.buf_flow_log_lvl = VSS_LOG_INFO;//vis_dump_debug_info(); //FIXME: vis_dump_debug_info is not work //well, register value is always zeroreturn -VSS_NO_FREE_BUF;}}pbuf = __vis_buf_list_pop(&g_vis_ctrl.exter_done_list, false);if (NULL == pbuf) {vss_printk(VSS_LOG_ERR, "buf list pop failed\n");return -VSS_ERROR_MAX;}user_buf->plane_cnt = pbuf->plane_cnt;user_buf->auser = pbuf->auser;switch (user_buf->plane_cnt) {case 1:user_buf->y_pa = pbuf->y_pa;user_buf->y_va_vdo = pbuf->y_va_vdo;user_buf->y_va_vip = pbuf->y_va_vip;break;case 2:user_buf->y_pa = pbuf->y_pa;user_buf->y_va_vdo = pbuf->y_va_vdo;user_buf->y_va_vip = pbuf->y_va_vip;user_buf->cb_pa = pbuf->cb_pa;user_buf->cb_va_vdo = pbuf->cb_va_vdo;user_buf->cb_va_vip = pbuf->cb_va_vip;break;default:return -1;}return VSS_NO_ERROR;
}
xVideoinRequestEmptyBuffer 获取display的buf enqueue 到camera
static BaseType_t xVideoinRequestEmptyBuffer()
{CapturePriv_t xPrivData;PortBuffer_t xVisBuf;if( NULL == xVideoinInfo.pxDeqBuffFunc ){vss_printk(VSS_LOG_ERR, " deq buffer callback is null\n");return pdFAIL;}memset( &xPrivData, 0, sizeof( CapturePriv_t ) );memset( &xVisBuf, 0, sizeof( PortBuffer_t ) );//从display 中获取empty bufif( pdPASS != xVideoinInfo.pxDeqBuffFunc( &xPrivData ) ){vss_printk(VSS_LOG_DEBUG, " deq empty buffer from display failed\n");return pdFAIL;}switch( xPrivData.ulPlaneCnt ){case 1:xVisBuf.plane_cnt = xPrivData.ulPlaneCnt;xVisBuf.y_pa = xPrivData.xYCAddr.y;xVisBuf.y_va_vdo = smmu_avin_pa2va( xPrivData.xYCAddr.y );xVisBuf.y_va_vip = smmu_avin_vip_pa2va( xPrivData.xYCAddr.y );break;case 2:xVisBuf.plane_cnt = xPrivData.ulPlaneCnt;xVisBuf.y_pa = xPrivData.xYCAddr.y;xVisBuf.y_va_vdo = smmu_avin_pa2va( xPrivData.xYCAddr.y );xVisBuf.y_va_vip = smmu_avin_vip_pa2va( xPrivData.xYCAddr.y );xVisBuf.cb_pa = xPrivData.xYCAddr.c;xVisBuf.cb_va_vdo = smmu_avin_pa2va( xPrivData.xYCAddr.c );xVisBuf.cb_va_vip = smmu_avin_vip_pa2va( xPrivData.xYCAddr.c );break;default:vss_printk(VSS_LOG_ERR, " plane count(%ld) is invalid for now\n", xPrivData.ulPlaneCnt);return pdFAIL;}#if VDO_DEBUG_BUFFER_FLOWvss_printk(VSS_LOG_INFO, "y_pa(0x%08x%08x), y_va_vdo(0x%08lx), y_va_vip(0x%08lx).\r\n",ul2ui(xVisBuf.y_pa), xVisBuf.y_va_vdo, xVisBuf.y_va_vip);
#endifif( vis_buffer_queue( &xVisBuf ) ){vss_printk(VSS_LOG_DEBUG, "vis_que_buffer error\n");return pdFAIL;}return pdPASS;
}
enqueue buff vis_buffer_queue
//from display to vis to request empty buffer
int vis_buffer_queue(struct port_buffer *user_buf)
{struct buf_info buf;if ((NULL == user_buf) || (0 == user_buf->y_pa)) {vss_printk(VSS_LOG_ERR, "user_buf is null or buf addr is 0\n");return -VSS_INVALID_PARAM;}memset(&buf, 0, sizeof(buf));buf.plane_cnt = user_buf->plane_cnt;buf.auser = user_buf->auser;switch (buf.plane_cnt) {case 1:buf.y_pa = user_buf->y_pa;buf.y_va_vdo = user_buf->y_va_vdo;buf.y_va_vip = user_buf->y_va_vip;break;case 2:buf.y_pa = user_buf->y_pa;buf.y_va_vdo = user_buf->y_va_vdo;buf.y_va_vip = user_buf->y_va_vip;buf.cb_pa = user_buf->cb_pa;buf.cb_va_vdo = user_buf->cb_va_vdo;buf.cb_va_vip = user_buf->cb_va_vip;break;default:vss_printk(VSS_LOG_ERR, "plane cnt is invalid\n");return -1;}vss_printk(g_vis_ctrl.buf_flow_log_lvl, "done list cnt(%ld)\n", listCURRENT_LIST_LENGTH(&g_vis_ctrl.exter_done_list.list));vss_printk(g_vis_ctrl.buf_flow_log_lvl, "todo list cnt(%ld)\n", listCURRENT_LIST_LENGTH(&g_vis_ctrl.exter_todo_list.list));if (VSS_NO_ERROR != __vis_buf_list_push(&g_vis_ctrl.exter_todo_list, buf, false)) {vss_printk(VSS_LOG_ERR, "buf list push failed\n");return -VSS_ERROR_MAX;}return VSS_NO_ERROR;
}
__vis_mipi_buffer_request 获取empty buf
static struct buf_info * __vis_mipi_buffer_request (enum data_path dp,enum mop_id port_id,enum channel_id ch_id)
{if (dp != g_vis_ctrl.dp) {vss_printk(VSS_LOG_ERR, "dp is not correct, cur dp(%d), right dp(%d)", dp, g_vis_ctrl.dp);return NULL;}if (ch_id != g_vis_ctrl.ch_id) {vss_printk(VSS_LOG_ERR, "ch_id is not correct, cur ch_id(%d), right ch_id(%d)", ch_id, g_vis_ctrl.ch_id);return NULL;}if (port_id != g_vis_ctrl.port_id) {vss_printk(VSS_LOG_ERR, "dp is not correct, cur port_id(%d), right port_id(%d)", port_id, g_vis_ctrl.port_id);return NULL;}return __vis_dp_buf_request_handler();
}
__vis_dp_buf_request_handler获取 exter_todo_list 上的 empty buf
static struct buf_info * __vis_dp_buf_request_handler()
{struct buf_info *pbuf = NULL;if (g_vis_ctrl.out_para.is_vip_enable) {pbuf = __vis_buf_list_pop(&g_vis_ctrl.inter_todo_list, true);} else {pbuf = __vis_buf_list_pop(&g_vis_ctrl.exter_todo_list, true);}//如果是第一帧数据,使用garbage_buf获取camera数据if (NULL == pbuf) {pbuf = &g_vis_ctrl.garbage_buf;vss_printk(g_vis_ctrl.buf_flow_log_lvl, "buf request failed, use garbage buf y_pa(0x%08x%08x)\n", ul2ui(pbuf->y_pa));}pbuf->y_addr = pbuf->y_va_vdo;pbuf->cb_addr = pbuf->cb_va_vdo;pbuf->cr_addr = pbuf->cr_va_vdo;vss_printk(g_vis_ctrl.buf_flow_log_lvl, "request buf y_pa(0x%08x%08x), idx(%ld)\n", ul2ui(pbuf->y_pa), pbuf->buf_idx);return pbuf;
}
分配garbagebuff 获取dma 物理地址获取mipi数据
static BaseType_t xVideoinAllocGarbageBuffer( uint32_t ulWidth, uint32_t ulHeight )
{uint32_t ulBufSize = 0;uint64_t ulBufAddr = 0;PortBuffer_t *pxGarbageBuf = &xVideoinInfo.xGarbageBuf;vss_printk(VSS_LOG_INFO, "enter, width(%ld), height(%ld)\n",ulWidth, ulHeight);if( ( 0 == ulWidth ) || ( 0 == ulHeight ) ){vss_printk(VSS_LOG_ERR, "param is invalid.\n");return pdFAIL;}if( 0 != pxGarbageBuf->y_pa ){vss_printk(VSS_LOG_INFO, "garbage buffer already allocted, free buffer first.\n");vVideoinFreeGarbageBuffer();}//allocate garbage bufulBufSize = ulWidth * ulHeight * YUV_422_FMT;if( 0 != pvRsvAlloc( ulBufSize, &ulBufAddr, RT_ALLOC_BACKCAR ) ){vss_printk(VSS_LOG_ERR, "malloc garbage plane 1 memory error\n");goto error;}pxGarbageBuf->y_pa = ulBufAddr;pxGarbageBuf->y_va_vdo = smmu_avin_pa2va( pxGarbageBuf->y_pa );pxGarbageBuf->y_va_vip = smmu_avin_vip_pa2va( pxGarbageBuf->y_pa );vss_printk(VSS_LOG_INFO, "GarbageBuf: y_pa(0x%08x%08x), y_va_vdo(0x%08lx), y_va_vip(0x%08lx).\n",ul2ui(pxGarbageBuf->y_pa), pxGarbageBuf->y_va_vdo, pxGarbageBuf->y_va_vip);pxGarbageBuf->cb_pa = pxGarbageBuf->y_pa + ulWidth * ulHeight;pxGarbageBuf->cb_va_vdo = smmu_avin_pa2va( pxGarbageBuf->cb_pa );pxGarbageBuf->cb_va_vip = smmu_avin_vip_pa2va( pxGarbageBuf->cb_pa );vss_printk(VSS_LOG_INFO, "GarbageBuf: cb_pa(0x%08x%08x), cb_va_vdo(0x%08lx), cb_va_vip(0x%08lx).\n",ul2ui(pxGarbageBuf->cb_pa), pxGarbageBuf->cb_va_vdo, pxGarbageBuf->cb_va_vip);pxGarbageBuf->plane_cnt = 1; //the garbage plane_cnt is useless because it's format is uncertain.//garbage buffer prepareif( 0 != vis_garbage_buffer_prepare( pxGarbageBuf ) ){vss_printk(VSS_LOG_ERR, "vis inter buffer prepare failed\n");goto error;}vss_printk(VSS_LOG_INFO, "leave\n");return pdPASS;error:vVideoinFreeGarbageBuffer();vss_printk(VSS_LOG_INFO, "leave with error\n");return pdFAIL;
}
int vis_garbage_buffer_prepare(struct port_buffer *buf)
{int ret = VSS_NO_ERROR;vss_printk(VSS_LOG_INFO, "enter\n");memset(&g_vis_ctrl.garbage_buf, 0x0, sizeof(struct buf_info));g_vis_ctrl.garbage_buf.auser = buf->auser;g_vis_ctrl.garbage_buf.plane_cnt = buf->plane_cnt;g_vis_ctrl.garbage_buf.ch_id = g_vis_ctrl.ch_id;switch (buf->plane_cnt) {case 1:g_vis_ctrl.garbage_buf.y_pa = buf->y_pa;g_vis_ctrl.garbage_buf.y_va_vdo = buf->y_va_vdo;g_vis_ctrl.garbage_buf.y_va_vip = buf->y_va_vip;break;case 2:g_vis_ctrl.garbage_buf.y_pa = buf->y_pa;g_vis_ctrl.garbage_buf.y_va_vdo = buf->y_va_vdo;g_vis_ctrl.garbage_buf.y_va_vip = buf->y_va_vip;g_vis_ctrl.garbage_buf.cb_pa = buf->cb_pa;g_vis_ctrl.garbage_buf.cb_va_vdo = buf->cb_va_vdo;g_vis_ctrl.garbage_buf.cb_va_vip = buf->cb_va_vip;break;default:return -1;}vss_printk(VSS_LOG_INFO, "leave\n");return ret;
}