JP7.2 / Thor SIPL GMSL YUV422 (UYVY) ICP timeout — V4L2 OK, SerDes gold aligned, passive mode still 0 frames

Hi Nvidia,

Need help for SIPL on Jetson Thor.

Platform

  • JetPack 7.2 / L4T R39.x, AGX Thor
  • Camera: Sensing ISX031C UYVY 1920×1536 @30fps
  • Serializer: MAX9295 @0x40
  • Deserializer: MAX96724_B @0x2E, Link B, i2c-12
  • CSI: csi-cd (PORT C / PP2), 4-lane D-PHY
  • HAL: Sensing patched libnvcamerahal.so + OEM UDDF module + OEM_FORCE_UYVY=1
  • JSON: inputFormat: "422", cfa: "uyvy", vcIdDst: 1, dphyRate: 800000, fsyncMode: osc_manual, desTxPort: 1

What works

  • V4L2 path works stably (v4l2-ctl UYVY 1920×1536, continuous frames).

  • V4L2 dmesg gold:

    tegra194-vi5 … VI capture setup complete (channel_id=0, csi_stream=2, vc=1)

    VI ch[35] 1920x1536 pixel format=VI_PIXFMT_FORMAT_T_U8_Y8__V8_Y8 fmt=19

    stream_id: PP 2, csi_port: PORT C

    Physical rate: 800000 Kbps

SIPL status

  • SetPlatformConfig / GetImageAttributes / Init / Start succeed with Sensing HAL + OEM_FORCE_UYVY=1.
  • SIPL RCE also shows UYVY 1920×1536 / CSI port CD / 800 Mbps.
  • Always Frame=0, continuous NOTIF_WARN_ICP_CAPTURE_TIMEOUT.
  • Note: nvsipl_query still prints Input Format: RAW12 | CFA: Unknown for JSON "422"/"uyvy"; runtime forced via OEM_FORCE_UYVY=1.

SerDes already ruled out

Aligned to live V4L2 gold (video lock + YUV DT + FSYNC free-run):

  • Des: 08A0=0x04, deskew 0x17, Link B 00F0=0x42 / 00F4=0x1F, DT 094D/094E=0x1E/0x5E, soft-BPP 090A=0xD0, rate 0415=0x39, lock 01DC/01FC
  • Ser: PIPE_X 0314=0xDE, osc_manual RX ID8 (02D5=0x48)
  • Passive -S: V4L2 first programs SerDes (lock + gold), then SIPL starts → still ICP timeout / 0 frames

Tried / failed

Attempt Result
Match dphyRate 800Mbps + des 0415=0x39 NVCSI=800M; still 0 frames
osc_manual free-run (no MFP2) Start OK; still timeout
-u disableSubframe no effect
Export Sensing HAL extension IMixedPipelineLayout::IsMixedYuvModule()=true immediate board hang/reboot
Mid-run I2C / KILL on stop often KASAN vi_capture_request_unpin → host unreachable

Core question

With SerDes proven by V4L2 and by passive mode, where should we look next on the SIPL Camera HAL → NVCSI/VI capture path for GMSL YUV422?

Specifically:

  1. For YUV422 packed UYVY on GMSL, is exporting IsMixedYuvModule required? Our export with patched HAL causes reboot — is there a supported JP7.2 path without that private UUID?
  2. Why does V4L2 log VI capture setup complete (channel_id=0, csi_stream=2, vc=1) while SIPL often only shows RCE VI ch[35] UYVY config, then ICP timeout (as if no MIPI packets arrive)?
  3. Is there a known PixPack / VC / stream binding issue for csi-cd + vcIdDst=1 + MAX96724 2x4 mode?
  4. Correct JSON tokens + HAL expectations for Thor GMSL YUV ICP (beyond forum note of "422" + "uyvy")?

We are looking for guidance on the remaining HAL/NVCSI/VI gap (not SerDes programming). Happy to provide full SIPL log + V4L2/SIPL dmesg side-by-side.

Thanks!

Is this your basis? If so you may want to git pull it; or clone it. Sensing updated its binaries 5 days ago. You could try the
`nvidia-jetson-camera-drivers/Jetson AGX Thor Devkit/TRD1_G2A/JetPack7.2/TRD1_G2A_AGX_THOR_SIPL_JP7.2_L4TR39.2/query/trd1_g2a/sgx_yuv_gmsl2.json’ for sipl query

git clone --filter=blob:none --no-checkout \
https://github.com/SENSING-Technology/nvidia-jetson-camera-drivers.git
cd nvidia-jetson-camera-drivers
git sparse-checkout init --cone
git sparse-checkout set   "Jetson AGX Thor Devkit/TRD1_G2A/JetPack7.2/TRD1_G2A_AGX_THOR_SIPL_JP7.2_L4TR39.2"
git checkout main

Thanks @whitesscott.

We compared the Sensing TRD you linked (TRD1_G2A … SIPL JP7.2 L4TR39.2). Our board already has the same md5 for libnvcamerahal.so, SGX YUV module, and sgx_yuv_gmsl2.json — reinstalling doesn’t help.

Our setup is OEM, not TRD reference: MAX96724_B @0x2E / csi-cd / Link B + MAX9295@0x40 + ISX031C UYVY 1920×1536 (not stock SGX_YUV / MAX96717).

We aligned OEM IMixedPipelineLayout to the SGX .so (UUID + vtable + IsMixedYuvModule()=true). Results:

  • MixedYuv only → no hang, but GetImageAttributes / AllocateBuffers fail
  • MixedYuv + OEM_FORCE_UYVY=1 → board hang/reboot
  • FORCE only (no MixedYuv) → Init/Start OK, VI/RCE UYVY + 800 Mbps, SerDes=V4L2 gold (incl. passive -S), still ICP_CAPTURE_TIMEOUT / 0 frames

Q: For OEM MAX9295+MAX96724, how should YUV ICP get past GetImageAttributes without FORCE, and why does FORCE+MixedYuv crash? With FORCE-only, what else is missing on HAL→NVCSI/VI when SerDes is already proven by V4L2?

Happy to share logs/dmesg.

Following returns reasonably good output that might be useful. I don’t have a isx031c to fully test. Using Sensings’s nvsipl_camera -v 4 logged CQueryAdapter: forcing sensor GW5 vc to YUV422/uyvy, followed by Mixed YUV output: sensor 0 (YUV422) → ICP UYVY passthrough.

cd "nvidia-jetson-camera-drivers/Jetson AGX Thor Devkit/TRD1_G2A/JetPack7.2/TRD1_G2A_AGX_THOR_SIPL_JP7.2_L4TR39.2"

sudo ./bin/nvsipl_camera \
    -H \
    -c SGX_YUV_GMSL2_8CH \
    -t ./query/trd1_g2a/sgx_yuv_gmsl2.json \
    -m "0x0000 0x0001" \
    -s -Z -012R \
    --mixed-yuv-output \
    -v 4

Following enables use of Sensings driver/*.so.

sudo unshare -m bash -c '
set -e

ROOT="'"$PWD"'"
TMP=$(mktemp -d)

trap "umount /usr/lib/nvsipl_drv 2>/dev/null || true; rm -rf \"$TMP\"" EXIT

cp -a /usr/lib/nvsipl_drv/. "$TMP/"
cp -a "$ROOT"/driver/*.so "$TMP/"

mount --bind "$TMP" /usr/lib/nvsipl_drv

exec "$ROOT/bin/nvsipl_camera" \
    -H \
    -c SGX_YUV_GMSL2_8CH \
    -t "$ROOT/query/trd1_g2a/sgx_yuv_gmsl2.json" \
    -m "0x0000 0x0001" \
    -s -Z -012R \
    --mixed-yuv-output \
    -v 4
'

Tested nvsipl_query --output-json, as below, both normally and inside a mount namespace overriding /usr/lib/nvsipl_drv with SENSING’s ./driver/*.so; the outputs were identical. nvsipl_query still reports GW5 as RAW12.

./bin/nvsipl_query \
    -t ./query/trd1_g2a/sgx_yuv_gmsl2.json \
    -c SGX_YUV_GMSL2_8CH

./bin/nvsipl_query \
    -t ./query/trd1_g2a/sgx_yuv_gmsl2.json \
    -m SGX_YUV_GMSL2_3M

./bin/nvsipl_query \
    -t ./query/trd1_g2a/sgx_yuv_gmsl2.json \
    --output-json
sudo unshare -m bash -c '
set -e

ROOT="'"$PWD"'"
TMP=$(mktemp -d)

trap "umount /usr/lib/nvsipl_drv 2>/dev/null || true; rm -rf \"$TMP\"" EXIT

# Start with the normal SIPL driver/query directory
cp -a /usr/lib/nvsipl_drv/. "$TMP/"

# Overlay SENSINGs local driver files
cp -a "$ROOT"/driver/*.so "$TMP/"

# Only this namespace sees the modified /usr/lib/nvsipl_drv
mount --bind "$TMP" /usr/lib/nvsipl_drv

exec "$ROOT/bin/nvsipl_query" \
    -t "$ROOT/query/trd1_g2a/sgx_yuv_gmsl2.json" \
    -m SGX_YUV_GMSL2_3M
'
Hi @whitesscott,

Thanks again for the Sensing TRD / `--mixed-yuv-output` notes.

we got ICP UYVY frames on our OEM path (ISX031C + MAX9295 + MAX96724 Link B / `csi-cd`). Main fixes were des VC remap to **VC0** (SIPL/VI listens vc=0; V4L2 gold was often VC1), plus keeping VIDEO_LOCK (`01FC=0x81`) / FSYNC through Start. Working with `OEM_FORCE_UYVY=1` only — MixedYuv UUID not needed.

after a good capture, can your Sensing `nvsipl_camera --mixed-yuv-output` run **Stop → Deinit → exit** without rebooting Thor?

On our side: `Stop`+drain is OK; `Deinit()` (or process `_exit` without Deinit) still causes a full reboot. Earlier we also saw `vi_capture_request_unpin` in `tegra_camera`. V4L2 streamoff/on is fine on the same VI.

If teardown is clean on your TRD setup, any ordering tips or known JP7.2/R39.2 VI patches would help. If not, is long-lived SIPL (no Deinit) the expected workaround for now?

Thanks!

Three things that may be relevant and could produce a Thor reboot.

  1. Calling Stop or Deinit from the signal handler. The API contract in NvSIPLCamera.hpp explicitly forbids it (Signal handler: No on both) and Deinit() is documented Async/Sync: Async. The reference sample handler only sets a quit flag and then re-arms every signal to SIG_IGN so a second Ctrl-C can’t skip cleanup — the comment in the source spells it out:
/usr/src/jetson_sipl_api/sipl/samples/camera/main.cpp
static void SigHandler(int signum) {
    LOG_WARN("Received signal: %u. Quitting\n", signum);
    signal(SIGINT,  SIG_IGN);
    signal(SIGTERM, SIG_IGN);
    signal(SIGQUIT, SIG_IGN);
    signal(SIGHUP,  SIG_IGN);
    bQuit = true;
    // Do NOT restore to SIG_DFL - a second Ctrl-C would kill the process
    // before upMaster->Stop() and upMaster->Deinit() can execute, 
    
    causing RCE FW crash.
}
  1. Ordering is Stop → drain → per-object Deinit →
    upMaster->Deinit() LAST.
    From samples/camera/main.cpp:3784-3900 the reference sequence is:
upMaster->Stop()
devblkNotify->Stop()   /   pipelineNotify->Stop()   /   frameCompletionQueue->Stop()
readers->Deinit()
composite->Deinit()
devblkNotify->Deinit() /   pipelineNotify->Deinit() /   frameCompletionQueue->Deinit()
eglRenderers delete    (before consumer Deinit — comment: "before upMaster->Deinit which tears down
SIPL's NvSciBuf pool")
consumers->Deinit()
profilers->Deinit()
frameFeeder->Deinit()
upMaster->Deinit()     <-- LAST
return 0;

Between Stop and Deinit the sample also spins the event queue with a 1 ms timeout until it sees two consecutive empty cycles — that’s the “let RCE finish flushing” window. If you Deinit before every notification handler has been Stop’d, a late frame-complete lands on a pool that’s already being torn down and you may get the unpin bug.

  1. Deinit() is Async and it is the call that unregisters NvSciBufs. The header comment: “Any registered images are automatically deregistered and can be safely destroyed.” If the process returns
    from main() before Deinit() has actually completed (or you _exit() from a handler), the kernel-side capture channel still holds pinned dmabuf handles → vi_capture_request_unpin KASAN on release. Wait for Deinit() to return NVSIPL_STATUS_OK and log it before you fall out of main.

The R39.2 UDDF release notes list “Resiliency: Runtime error recovery and automatic driver restart after transient failures are not yet supported” as a known limitation (Release Notes — NVIDIA Jetson Linux Developer Guide).

I would suggest consult with Sensing to get more information.

Thanks