11#! /bin/sh
22# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
33# SPDX-License-Identifier: BSD-3-Clause-Clear
4-
4+ # --- Robustly find and source init_env ---------------------------
55SCRIPT_DIR=" $( cd " $( dirname " $0 " ) " && pwd) "
66INIT_ENV=" "
77SEARCH=" $SCRIPT_DIR "
88while [ " $SEARCH " != " /" ]; do
99 if [ -f " $SEARCH /init_env" ]; then
10- INIT_ENV=" $SEARCH /init_env"
11- break
10+ INIT_ENV=" $SEARCH /init_env" ; break
1211 fi
1312 SEARCH=$( dirname " $SEARCH " )
1413done
14+ [ -z " $INIT_ENV " ] && echo " [ERROR] Could not find init_env (starting at $SCRIPT_DIR )" >&2 && exit 1
1515
16- if [ -z " $INIT_ENV " ]; then
17- echo " [ERROR] Could not find init_env (starting at $SCRIPT_DIR )" >&2
18- exit 1
19- fi
20-
21- if [ -z " $__INIT_ENV_LOADED " ]; then
22- # shellcheck disable=SC1090
23- . " $INIT_ENV "
24- fi
16+ # shellcheck disable=SC1090
17+ [ -z " $__INIT_ENV_LOADED " ] && . " $INIT_ENV "
2518# shellcheck disable=SC1090,SC1091
2619. " $TOOLS /functestlib.sh"
2720
2821TESTNAME=" Camera_RDI_FrameCapture"
2922RES_FILE=" ./$TESTNAME .res"
30- test_path=$( find_test_case_by_name " $TESTNAME " )
23+ test_path=" $( find_test_case_by_name " $TESTNAME " ) "
3124cd " $test_path " || exit 1
3225
3326print_usage () {
@@ -50,44 +43,153 @@ USER_FORMAT=""
5043FRAMES=10
5144while [ $# -gt 0 ]; do
5245 case " $1 " in
53- --format)
54- shift
55- USER_FORMAT=" $1 "
56- ;;
57- --frames)
58- shift
59- FRAMES=" $1 "
60- ;;
61- --help)
62- print_usage
63- exit 0
64- ;;
65- * )
66- log_error " Unknown argument: $1 "
67- print_usage
68- exit 1
69- ;;
46+ --format) shift ; USER_FORMAT=" $1 " ;;
47+ --frames) shift ; FRAMES=" $1 " ;;
48+ --help) print_usage; exit 0 ;;
49+ * ) log_error " Unknown argument: $1 " ; print_usage; exit 1 ;;
7050 esac
7151 shift
7252done
7353
74- # --------- Prechecks ---------
54+ # Helper: print planned media-ctl / yavta sequence for CI logs
55+ print_planned_commands () {
56+ media_node=" $1 "
57+ pixfmt=" $2 "
58+
59+ log_info " [CI] Planned sequence:"
60+ log_info " media-ctl -d $media_node --reset"
61+
62+ # media-ctl -V (show with possible TARGET_FORMAT substitution exactly like configure helper does)
63+ if [ -n " $MEDIA_CTL_V_LIST " ]; then
64+ printf ' %s\n' " $MEDIA_CTL_V_LIST " | while IFS= read -r vline; do
65+ [ -z " $vline " ] && continue
66+ vline_out=" $( printf ' %s' " $vline " | sed -E " s/fmt:[^/]+\/([0-9]+x[0-9]+)/fmt:${pixfmt} \/\1/g" ) "
67+ log_info " media-ctl -d $media_node -V '$vline_out '"
68+ done
69+ fi
70+ # media-ctl -l
71+ if [ -n " $MEDIA_CTL_L_LIST " ]; then
72+ printf ' %s\n' " $MEDIA_CTL_L_LIST " | while IFS= read -r lline; do
73+ [ -z " $lline " ] && continue
74+ log_info " media-ctl -d $media_node -l '$lline '"
75+ done
76+ fi
77+ # yavta control writes (pre)
78+ if [ -n " $YAVTA_CTRL_PRE_LIST " ]; then
79+ printf ' %s\n' " $YAVTA_CTRL_PRE_LIST " | while IFS= read -r ctrl; do
80+ [ -z " $ctrl " ] && continue
81+ dev=" $( printf ' %s' " $ctrl " | awk ' {print $1}' ) "
82+ reg=" $( printf ' %s' " $ctrl " | awk ' {print $2}' ) "
83+ val=" $( printf ' %s' " $ctrl " | awk ' {print $3}' ) "
84+ [ -n " $dev " ] && [ -n " $reg " ] && [ -n " $val " ] && \
85+ log_info " yavta --no-query -w '$reg $val ' $dev "
86+ done
87+ fi
88+ # main yavta capture (dimensions may be empty occasionally)
89+ size_arg=" "
90+ if [ -n " $YAVTA_W " ] && [ -n " $YAVTA_H " ]; then
91+ size_arg=" -s ${YAVTA_W} x${YAVTA_H} "
92+ fi
93+ if [ -n " $YAVTA_DEV " ]; then
94+ log_info " yavta -B capture-mplane -c -I -n $FRAMES -f $pixfmt $size_arg -F $YAVTA_DEV --capture=$FRAMES --file='frame-#.bin'"
95+ fi
96+ # yavta control writes (post)
97+ if [ -n " $YAVTA_CTRL_POST_LIST " ]; then
98+ printf ' %s\n' " $YAVTA_CTRL_POST_LIST " | while IFS= read -r ctrl; do
99+ [ -z " $ctrl " ] && continue
100+ dev=" $( printf ' %s' " $ctrl " | awk ' {print $1}' ) "
101+ reg=" $( printf ' %s' " $ctrl " | awk ' {print $2}' ) "
102+ val=" $( printf ' %s' " $ctrl " | awk ' {print $3}' ) "
103+ [ -n " $dev " ] && [ -n " $reg " ] && [ -n " $val " ] && \
104+ log_info " yavta --no-query -w '$reg $val ' $dev "
105+ done
106+ fi
107+ }
108+
109+ # --------- DT Precheck ---------
75110if ! dt_confirm_node_or_compatible " isp" " cam" " camss" ; then
76111 log_skip " $TESTNAME SKIP – No ISP/camera node/compatible found in DT"
77112 echo " $TESTNAME SKIP" > " $RES_FILE "
78113 exit 0
79114fi
80115
81- DRIVER_MOD=" qcom_camss"
82- DMESG_MODULES=' qcom_camss|camss|isp'
83- DMESG_EXCLUDE=' dummy regulator|supply [^ ]+ not found|using dummy regulator|Failed to create device link|reboot-mode.*-EEXIST|can.t register reboot mode'
116+ # --------- Kernel config sanity (MANDATORY bits only gate if totally absent) ---------
117+ log_info " [CONFIG] Expect at least: CONFIG_VIDEO_QCOM_CAMSS=y (or =m)"
118+ check_kernel_config " CONFIG_VIDEO_QCOM_CAMSS CONFIG_MEDIA_CONTROLLER CONFIG_V4L2_FWNODE" \
119+ || log_warn " [CONFIG] One or more options missing; will continue if CAMSS stack is otherwise present"
84120
85- if ! is_module_loaded " $DRIVER_MOD " ; then
86- log_skip " $TESTNAME SKIP – Driver module $DRIVER_MOD not loaded"
121+ # Optional visibility: print any CAMCC entries (name varies by tree)
122+ if ! check_kernel_config " CONFIG_QCOM_CAMCC_SC7280" ; then
123+ if command -v zgrep > /dev/null 2>&1 ; then
124+ CAMCC_SYMS=" $( zgrep -E ' ^CONFIG_.*CAMCC.*=(y|m)' /proc/config.gz 2> /dev/null || true) "
125+ else
126+ CAMCC_SYMS=" $( gzip -dc /proc/config.gz 2> /dev/null | grep -E ' ^CONFIG_.*CAMCC.*=(y|m)' || true) "
127+ fi
128+ if [ -n " $CAMCC_SYMS " ]; then
129+ printf ' %s\n' " $CAMCC_SYMS " | while IFS= read -r s; do
130+ [ -n " $s " ] && log_info " [CONFIG] $s "
131+ done
132+ fi
133+ fi
134+
135+ # --------- Broader readiness gate (module OR builtin OR nodes OR dmesg) ---------
136+ DMESG_CACHE=" $( dmesg 2> /dev/null || true) "
137+
138+ if [ -e /dev/media0 ] || [ -e /dev/video0 ]; then
139+ log_pass " [READY] Media/video nodes present:"
140+ for f in /dev/media* /dev/video* ; do
141+ [ -e " $f " ] || continue
142+ log_info " - $f "
143+ done
144+ elif is_module_loaded qcom_camss; then
145+ log_pass " [READY] qcom_camss module loaded"
146+ elif [ -d /sys/module/qcom_camss ]; then
147+ log_pass " [READY] qcom_camss present as builtin"
148+ elif printf ' %s\n' " $DMESG_CACHE " | grep -qiE ' qcom[-_]camss' ; then
149+ log_info " [READY] CAMSS messages found in dmesg (likely builtin)"
150+ else
151+ log_skip " Camera_RDI_FrameCapture SKIP – CAMSS driver not present (module or built-in)"
87152 echo " $TESTNAME SKIP" > " $RES_FILE "
88153 exit 0
89154fi
90155
156+ # --------- Module inventory (visibility only; no gating) ---------
157+ MODULES_LIST=" qcom_camss camcc_sc7280 videodev mc v4l2_fwnode v4l2_async videobuf2_common videobuf2_v4l2 videobuf2_dma_contig videobuf2_dma_sg videobuf2_memops"
158+
159+ present_mods=" "
160+ builtin_mods=" "
161+ missing_mods=" "
162+ for m in $MODULES_LIST ; do
163+ if is_module_loaded " $m " ; then
164+ present_mods=" $present_mods $m "
165+ elif [ -d " /sys/module/$m " ]; then
166+ builtin_mods=" $builtin_mods $m "
167+ else
168+ missing_mods=" $missing_mods $m "
169+ fi
170+ done
171+
172+ if [ -n " $present_mods " ]; then
173+ log_pass " [MODULES] Loaded:"
174+ for m in $present_mods ; do [ -n " $m " ] && log_info " - $m " ; done
175+ fi
176+ if [ -n " $builtin_mods " ]; then
177+ log_info " [MODULES] Built-in:"
178+ for m in $builtin_mods ; do [ -n " $m " ] && log_info " - $m " ; done
179+ fi
180+ if [ -n " $missing_mods " ]; then
181+ log_warn " [MODULES] Not found:"
182+ for m in $missing_mods ; do [ -n " $m " ] && log_info " - $m " ; done
183+ fi
184+
185+ # Sensor modules (best-effort)
186+ SENSOR_MODS=" $( awk ' {print $1}' /proc/modules 2> /dev/null | grep -E ' ^(imx|ov|gc|ar)[0-9]+' | tr ' \n' ' ' ) "
187+ [ -n " $SENSOR_MODS " ] && { log_info " [MODULES] Sensors:" ; for s in $SENSOR_MODS ; do log_info " - $s " ; done ; }
188+
189+ # --------- Dmesg probe errors (non-benign filter) ---------
190+ DRIVER_MOD=" qcom_camss"
191+ DMESG_MODULES=' qcom_camss|camss|isp'
192+ DMESG_EXCLUDE=' dummy regulator|supply [^ ]+ not found|using dummy regulator|Failed to create device link|reboot-mode.*-EEXIST|can.t register reboot mode'
91193if scan_dmesg_errors " $SCRIPT_DIR " " $DMESG_MODULES " " $DMESG_EXCLUDE " ; then
92194 log_skip " $TESTNAME SKIP – $DRIVER_MOD probe errors detected in dmesg"
93195 echo " $TESTNAME SKIP" > " $RES_FILE "
@@ -102,100 +204,101 @@ check_dependencies media-ctl yavta python3 v4l2-ctl || {
102204}
103205
104206# --------- Media Node Detection ---------
105- MEDIA_NODE=$( detect_media_node)
207+ MEDIA_NODE=" $( detect_media_node) "
106208if [ -z " $MEDIA_NODE " ]; then
107209 log_skip " $TESTNAME SKIP – Media node not found"
108210 echo " $TESTNAME SKIP" > " $RES_FILE "
109211 exit 0
110212fi
111213log_info " Detected media node: $MEDIA_NODE "
112214
113- # --------- Pipeline Detection ---------
114- TOPO_FILE=$( mktemp " /tmp/${TESTNAME} _topo.XXXXXX" )
115- TMP_PIPELINES_FILE=$( mktemp " /tmp/${TESTNAME} _blocks.XXXXXX" )
215+ # Light-touch global reset once
216+ media-ctl -d " $MEDIA_NODE " -r > /dev/null 2>&1 || true
217+ log_info " Media graph reset (-r) done on $MEDIA_NODE "
218+ sleep 0.2
219+
220+ # --------- Pipeline Detection (Python) ---------
221+ TOPO_FILE=" $( mktemp " /tmp/${TESTNAME} _topo.XXXXXX" ) "
222+ TMP_PIPELINES_FILE=" $( mktemp " /tmp/${TESTNAME} _blocks.XXXXXX" ) "
116223trap ' rm -f "$TOPO_FILE" "$TMP_PIPELINES_FILE"' EXIT
117224
118225media-ctl -p -d " $MEDIA_NODE " > " $TOPO_FILE " 2> /dev/null
119- PYTHON_PIPELINES=$( run_camera_pipeline_parser " $TOPO_FILE " )
226+ PYTHON_PIPELINES=" $( run_camera_pipeline_parser " $TOPO_FILE " ) "
120227if [ -z " $PYTHON_PIPELINES " ]; then
121228 log_skip " $TESTNAME SKIP – No valid pipelines found"
122229 echo " $TESTNAME SKIP" > " $RES_FILE "
123230 exit 0
124231fi
125-
126- printf " %s\n" " $PYTHON_PIPELINES " > " $TMP_PIPELINES_FILE "
232+ printf ' %s\n' " $PYTHON_PIPELINES " > " $TMP_PIPELINES_FILE "
127233
128234log_info " User format override: ${USER_FORMAT:- <none>} "
129235log_info " Frame count per pipeline: $FRAMES "
130236
131- # --------- Pipeline Processing ---------
237+ # --------- Pipeline Processing (core logic unchanged) ---------
132238PASS=0; FAIL=0; SKIP=0; COUNT=0
133239block=" "
134-
135240while IFS= read -r line || [ -n " $line " ]; do
136241 if [ " $line " = " --" ]; then
137242 COUNT=$(( COUNT+ 1 ))
138243 TMP=" /tmp/cam_block.$$ .$COUNT "
139- printf " %s\n" " $block " > " $TMP "
244+ printf ' %s\n' " $block " > " $TMP "
140245
141- # Parses block and sets SENSOR, VIDEO, YAVTA_DEV, FMT, etc
246+ # Parses block and sets SENSOR, VIDEO, YAVTA_DEV, YAVTA_FMT, MEDIA_CTL_* lists, etc.
142247 parse_pipeline_block " $TMP "
143248 rm -f " $TMP "
144249
145250 # -------- Multi-format support (POSIX style, no arrays) --------
146251 FORMATS_LIST=" $USER_FORMAT "
147- if [ -z " $FORMATS_LIST " ]; then
148- # No user override, use detected format for this pipeline only
149- FORMATS_LIST=" $YAVTA_FMT "
150- fi
252+ [ -z " $FORMATS_LIST " ] && FORMATS_LIST=" $YAVTA_FMT "
151253
152- OLD_IFS=" $IFS "
153- IFS=' ,'
254+ OLD_IFS=" $IFS " ; IFS=' ,'
154255 for FMT_OVERRIDE in $FORMATS_LIST ; do
155- FMT_OVERRIDE=$( printf ' %s' " $FMT_OVERRIDE " | sed ' s/^ *//;s/ *$//' )
156- TARGET_FORMAT=" $FMT_OVERRIDE "
157- [ -z " $TARGET_FORMAT " ] && TARGET_FORMAT=" $YAVTA_FMT "
256+ FMT_OVERRIDE=" $( printf ' %s' " $FMT_OVERRIDE " | sed ' s/^ *//;s/ *$//' ) "
257+ TARGET_FORMAT=" $FMT_OVERRIDE " ; [ -z " $TARGET_FORMAT " ] && TARGET_FORMAT=" $YAVTA_FMT "
158258
159- log_info " ----- Pipeline $COUNT : ${SENSOR:- unknown} $VIDEO $TARGET_FORMAT -----"
259+ # New banner: show pad mbus fmt and video pixfmt
260+ PAD_MBUS_FMT=" $( printf ' %s\n' " $MEDIA_CTL_V_LIST " | sed -n ' s/.*fmt:\([^/]]*\)\/.*/\1/p' | head -n1) "
261+ [ -z " $PAD_MBUS_FMT " ] && PAD_MBUS_FMT=" auto"
262+ log_info " ----- Pipeline $COUNT : ${SENSOR:- unknown} $VIDEO [pads:$PAD_MBUS_FMT ] [video:$TARGET_FORMAT ] -----"
160263
161264 if [ -z " $VIDEO " ] || [ " $VIDEO " = " None" ] || [ -z " $YAVTA_DEV " ]; then
162265 log_skip " $SENSOR : Invalid pipeline – skipping"
163266 SKIP=$(( SKIP+ 1 ))
164267 continue
165268 fi
166269
270+ # CI debug: print the exact commands we will run
271+ print_planned_commands " $MEDIA_NODE " " $TARGET_FORMAT "
272+
273+ # Configure & capture (original helpers)
167274 configure_pipeline_block " $MEDIA_NODE " " $TARGET_FORMAT "
168275 execute_capture_block " $FRAMES " " $TARGET_FORMAT "
169276 RET=$?
170277
278+ # Safety net retry
279+ if [ " $RET " -ne 0 ]; then
280+ log_warn " First attempt failed; resetting media graph and retrying once"
281+ log_info " media-ctl -d $MEDIA_NODE -r"
282+ media-ctl -d " $MEDIA_NODE " -r > /dev/null 2>&1 || true
283+ sleep 0.1
284+ print_planned_commands " $MEDIA_NODE " " $TARGET_FORMAT "
285+ configure_pipeline_block " $MEDIA_NODE " " $TARGET_FORMAT "
286+ execute_capture_block " $FRAMES " " $TARGET_FORMAT "
287+ RET=$?
288+ fi
289+
171290 case " $RET " in
172- 0)
173- log_pass " $SENSOR $VIDEO $TARGET_FORMAT PASS"
174- PASS=$(( PASS+ 1 ))
175- ;;
176- 1)
177- log_fail " $SENSOR $VIDEO $TARGET_FORMAT FAIL (capture failed)"
178- FAIL=$(( FAIL+ 1 ))
179- ;;
180- 2)
181- log_skip " $SENSOR $VIDEO $TARGET_FORMAT SKIP (unsupported format)"
182- SKIP=$(( SKIP+ 1 ))
183- ;;
184- 3)
185- log_skip " $SENSOR $VIDEO missing data – skipping"
186- SKIP=$(( SKIP+ 1 ))
187- ;;
291+ 0) log_pass " $SENSOR $VIDEO $TARGET_FORMAT PASS" ; PASS=$(( PASS+ 1 )) ;;
292+ 1) log_fail " $SENSOR $VIDEO $TARGET_FORMAT FAIL (capture failed)" ; FAIL=$(( FAIL+ 1 )) ;;
293+ 2) log_skip " $SENSOR $VIDEO $TARGET_FORMAT SKIP (unsupported format)" ; SKIP=$(( SKIP+ 1 )) ;;
294+ 3) log_skip " $SENSOR $VIDEO missing data – skipping" ; SKIP=$(( SKIP+ 1 )) ;;
188295 esac
189296 done
190297 IFS=" $OLD_IFS "
191298 block=" "
192299 else
193- if [ -z " $block " ]; then
194- block=" $line "
195- else
196- block=" $block
197- $line "
198- fi
300+ if [ -z " $block " ]; then block=" $line " ; else block=" $block
301+ $line " ; fi
199302 fi
200303done < " $TMP_PIPELINES_FILE "
201304
@@ -207,5 +310,4 @@ elif [ "$FAIL" -gt 0 ]; then
207310else
208311 echo " $TESTNAME SKIP" > " $RES_FILE "
209312fi
210-
211313exit 0
0 commit comments