OV5647 JT-ZERO-V2.0 raspberri pi zerro 22pin like camera with jetson orin nx. CSI data is not coming in

Jetson Orin NX / JP6.2.2 / OV5647: probe succeeds, /dev/video0 exists, VIDIOC_STREAMON succeeds, but no SOF / no NVCSI events / capture times out

Hi NVIDIA team,

I am trying to bring up an OV5647 MIPI CSI-2 camera on Jetson Orin NX and need help understanding why the Jetson software stack does not see CSI frame ingress, even though sensor-side
bring-up appears successful.

Goal

My goal is to get a working OV5647 raw capture path on:

  • Jetson Orin NX
  • CLB Developer Kit carrier board from makerobo
  • JetPack 6.2.2 / L4T R36.5
  • one OV5647 sensor
  • 2-lane CSI-2
  • one minimal 640x480 BG10 mode first

I am trying to solve this in a reproducible way and have documented everything in a public repo:

Camera photos used in the setup:

Current problem

Software-wise, the sensor probes and the video node appears, but the Jetson capture stack does not see any actual CSI frame ingress.

Current symptom:

  • probe succeeds
  • /dev/video0 exists
  • v4l2-ctl buffer setup succeeds
  • VIDIOC_STREAMON returned 0 (Success)
  • raw capture file stays 0 bytes
  • VI logs repeated timeout:
    • tegra-camrtc-capture-vi: uncorr_err: request timed out after 2500 ms
  • RTCPU/NVCSI trace shows:
    • no SOF
    • no EOF
    • no rtcpu_nvcsi_intr
    • no vi_frame_begin
    • no vi_frame_end

So from software point of view, it looks like sensor-side stream start works, but Jetson still does not observe frame ingress on the receiver side.

Platform and current reference configuration

Target:

  • SoM: Jetson Orin NX (p3767)
  • Live base carrier DT identity: p3768-0000
  • Carrier used physically: CLB Developer Kit / makerobo
  • JetPack: 6.2.2
  • L4T: R36.5
  • Kernel: 5.15.185-tegra

Current reference route under test:

  • cam_i2cmux/i2c@1/ov5647_c@36
  • tegra_sinterface = “serial_c”
  • port-index = 2
  • num_lanes = 2
  • bus-width = 2
  • lane_polarity = 0
  • discontinuous_clk = “yes”
  • cil_settletime = 0
  • mclk_khz = 24000
  • pix_clk_hz = 58333000
  • embedded_metadata_height = 0
  • reset GPIO present
  • no pwdn GPIO on this current route-C baseline

Current boot profile:

  • boot_profile=ov5647-dev

What is already confirmed working

Sensor / low-speed side

Confirmed:

  • sensor responds on I2C at 0x36
  • chip ID reads correctly as 0x5647
  • driver probe succeeds
  • /dev/video0, /dev/v4l-subdev0, /dev/v4l-subdev1 are created
  • media graph is linked as:
    • nv_ov5647 → nvcsi → vi-output

Stream command path

VIDIOC_STREAMON succeeds.

Sensor-side register readback confirms that the sensor really enters stream state:

  • 0x0100 = 0x01 after stream-on

Also, the sensor does not appear to silently fall out of stream during the timeout window.

I added lifecycle register dumps and observed:

Phase 0x0100 0x300d 0x4202 0x4800
after_stream_on 0x01 0x00 0x00 0x34
before_stream_off 0x01 0x00 0x00 0x34
after_stream_off 0x00 0x01 0x0f 0x25

This means:

  • sensor is still in stream state right before Jetson explicitly stops it
  • only after explicit stream-off does it return to standby/LP11 state

So software-wise, the sensor appears to stay in stream state correctly.

What Jetson software stack shows

I used RTCPU/NVCSI trace and additional clock/power-domain observation.

What I see during failed capture:

  • nvcsi and vi clocks do come up during the timeout window
  • but trace still shows:
    • no capture_event_sof
    • no capture_event_eof
    • no rtcpu_nvcsi_intr
    • no rtcpu_vinotify_error
    • no vi_frame_begin
    • no vi_frame_end

So the capture stack is not idle, but it still does not see usable frame ingress.

What has already been tested

I tried multiple controlled software-side variants:

DT route variants

  • route A
  • route C
  • blind cross-route hybrid:
    • i2c@0 + serial_c + port-index=2
  • blind cross-route hybrid:
    • i2c@1 + serial_b + port-index=1

All of them produced the same class of failure:

  • VIDIOC_STREAMON success
  • zero-byte raw file
  • no SOF
  • no NVCSI intr
  • VI timeout

MCLK / timing side

  • corrected extperiph1 binding
  • tested mclk_khz=25000 intent
  • tested canonical route-C with mclk_khz=24000
  • runtime still enables 24000000
  • no change in failure signature

Sensor-side diagnostics

  • test pattern support added and read back successfully
  • key stream/MIPI registers dumped
  • sensor remains in stream state until explicit stop
  • no sign of stream-bit rollback during timeout

Why I am asking for help

At this point, the software evidence looks like this:

  • sensor-side initialization works
  • I2C works
  • chip ID works
  • /dev/video0 exists
  • VIDIOC_STREAMON succeeds
  • sensor registers indicate streaming is active
  • Jetson clocks for capture path come up
  • but Jetson software still sees no CSI frame ingress at all

I would like guidance from NVIDIA on what to check next in software.

Questions

  1. Given this exact signature:

    • VIDIOC_STREAMON success
    • repeated VI timeout
    • no SOF
    • no rtcpu_nvcsi_intr
    • no vi_frame_begin/end

    what is the most likely software-side issue in the Jetson camera stack?

  2. Is there any NVIDIA-specific requirement for OV5647 on Orin NX / R36.5 that I may still be missing in:

    • DT mode node
    • NVCSI/VI routing
    • tegra-camera-platform module description
    • metadata settings
    • pixel clock / timing fields
  3. Is embedded_metadata_height = 0 acceptable for this kind of raw OV5647 bring-up on Orin, or does NVIDIA expect a different value for proper capture path behavior?

  4. Is there any recommended official way to debug “sensor streams but Jetson sees no SOF” on R36.5 beyond the tracepoints I already used?

  5. If you want, I can provide any exact artifact from the repo:

    • current overlay
    • current driver
    • trace logs
    • dmesg logs
    • media graph
    • post-reboot state
    • specific reports

Useful repo links

Main repo:

Relevant reports:

Camera mapping / platform notes:

If needed, I can also attach the exact logs from the latest runtime test.

Thanks.

hello amburkoff,

just for confirmation,
there’re J20/CAM0 slot which utilize CSI-B, and J21/CAM1 slot utilize CSI-C/D.
you may double check you’ve correct camera hardware connections.

please refer to developer guide, you may review your Sensor Pixel Clock, which must be set correctly to avoid potential issues.
FYI, I usually using sensor CSI lane output rate for calculation, pixel_clk_hz = sensor data rate per lane (Mbps) * number of lanes / bits per pixel.

since there’s dtbo (i.e. overlay) for updating device tree settings,
you may try the commands below to dump device tree into dts formats for cross-checking.
i.e. $ sudo dtc -I fs -O dts /sys/firmware/devicetree/base > /tmp/123.dts

besides..
you may see-also forum thread, Topic 367486 to review device tree settings within tegra-camera-platform{}.

Hi Jerry,

Thanks. I followed your suggestions and completed the checks you mentioned.

  1. J20/CAM0 vs J21/CAM1 mapping

I understand your note:

  • J20 / CAM0 → CSI-B
  • J21 / CAM1 → CSI-C/D

On the software side I already tested all of these route combinations:

  • route A: cam_i2cmux/i2c@0 + serial_b + port-index=1
  • route C: cam_i2cmux/i2c@1 + serial_c + port-index=2
  • cross-check hybrid: i2c@0 + serial_c + port-index=2
  • cross-check hybrid: i2c@1 + serial_b + port-index=1

All of them produced the same failure signature:

  • VIDIOC_STREAMON succeeds
  • raw output file stays 0 bytes
  • repeated uncorr_err: request timed out after 2500 ms
  • no SOF
  • no rtcpu_nvcsi_intr
  • no vi_frame_begin/end

So I did re-check the software-side route mapping space, and at least on the Jetson capture-stack side I do not see a route-specific difference.

  1. Sensor Pixel Clock review

I followed your recommendation and reviewed pix_clk_hz carefully.

I dumped the live device tree exactly as you suggested:

sudo dtc -I fs -O dts /sys/firmware/devicetree/base > /tmp/123.dts

Before the retest, live DT still showed:

  • pix_clk_hz = 58333000
  • mclk_khz = 24000
  • line_length = 1852
  • default_framerate = 60000000

At the same time, my runtime OV5647 register dumps for the active VGA mode showed:

  • HTS = 0x073c = 1852
  • VTS = 0x01f8 = 504
  • target fps = 60

So I corrected pix_clk_hz to match the actual programmed timing:

  • 1852 * 504 * 60 = 56004480

I then staged a controlled route-C retest that changed only:

  • pix_clk_hz = 56004480
  • directly dependent timing fields

and kept the rest unchanged:

  • serial_c
  • port-index = 2
  • num_lanes = 2
  • lane_polarity = 0
  • mclk_khz = 24000
  • discontinuous_clk = “yes”
  • cil_settletime = 0

Overlay source used for this test:

Stage report:

After reboot, I verified live DT actually changed to:

  • pix_clk_hz = 56004480
  • mclk_khz = 24000
  • tegra_sinterface = “serial_c”
  • num_lanes = 2

Live DT dump artifact:

Runtime retest report:

Result: no change in failure class.

Latest runtime result:

  • VIDIOC_STREAMON returned 0 (Success)
  • raw output still 0 bytes
  • repeated VI timeout still occurs
  • trace still shows:
    • capture_event_sof = 0
    • capture_event_eof = 0
    • rtcpu_nvcsi_intr = 0
    • vi_frame_begin = 0
    • vi_frame_end = 0

Latest trace/dmesg artifacts:

  1. tegra-camera-platform{} review

I also reviewed the tegra-camera-platform{} suggestion from the linked thread.

Current route-C baseline still uses:

  • sysfs-device-tree = “/sys/firmware/devicetree/base/bus@0/cam_i2cmux/i2c@1/ov5647_c@36”

and the active media graph is still the expected:

  • nv_ov5647 → nvcsi → vi-output

I also compared the route-C graph and capture-side fields against NVIDIA route-C reference overlays (imx219-C, imx477-C).

That audit is here:

My current understanding is that the main route-C capture-side fields already match the NVIDIA reference family:

  • serial_c
  • port-index = 2
  • bus-width = 2
  • num_lanes = 2
  • mclk_khz = 24000
  • cil_settletime = 0
  • lane_polarity = 0
  1. Additional sensor-side confirmation

To make sure this is not just a sensor-side stream-bit issue, I also added stream lifecycle register dumps.

The sensor still appears to remain in streaming state through the whole timeout window:

  • after stream_on: 0x0100 = 0x01
  • before stream_off: 0x0100 = 0x01
  • after explicit stream_off: 0x0100 = 0x00

That report is here:

So from software point of view I now have all of these at the same time:

  • sensor probe succeeds
  • /dev/video0 exists
  • VIDIOC_STREAMON succeeds
  • sensor register state indicates streaming is active
  • Jetson nvcsi/vi clocks come up during capture
  • but there is still no SOF, no rtcpu_nvcsi_intr, and no vi_frame_begin/end

Question

Since I completed the checks you suggested:

  • reviewed J20/J21 route mapping space in software
  • dumped live DT using dtc -I fs -O dts
  • corrected pix_clk_hz and retested
  • reviewed tegra-camera-platform{} and route-C reference structure

what would you recommend as the next software-side step?

In particular, could you please advise which of these is the most likely next issue to investigate on Jetson side:

  1. another DT field that is still wrong for OV5647 on Orin NX / R36.5
  2. a missing NVIDIA-specific requirement in tegra-camera-platform{}
  3. a sensor timing value that should be calculated differently than my current 56004480
  4. a recommended NVIDIA-side debug method for the case:
    • VIDIOC_STREAMON success
    • no SOF
    • no rtcpu_nvcsi_intr
    • no vi_frame_begin/end

If you want, I can also attach the exact latest:

  • live DTS dump
  • latest DT overlay source
  • latest trace directory
  • latest dmesg log
  • latest media graph dump

Thanks.

hello amburkoff,

please try follow the commands below to boost all the VI/CSI/ISP clocks.

sudo su
echo 1 > /sys/kernel/debug/bpmp/debug/clk/vi/mrq_rate_locked
echo 1 > /sys/kernel/debug/bpmp/debug/clk/isp/mrq_rate_locked
echo 1 > /sys/kernel/debug/bpmp/debug/clk/nvcsi/mrq_rate_locked
echo 1 > /sys/kernel/debug/bpmp/debug/clk/emc/mrq_rate_locked
cat /sys/kernel/debug/bpmp/debug/clk/vi/max_rate |tee /sys/kernel/debug/bpmp/debug/clk/vi/rate
cat /sys/kernel/debug/bpmp/debug/clk/isp/max_rate | tee /sys/kernel/debug/bpmp/debug/clk/isp/rate
cat /sys/kernel/debug/bpmp/debug/clk/nvcsi/max_rate | tee /sys/kernel/debug/bpmp/debug/clk/nvcsi/rate
cat /sys/kernel/debug/bpmp/debug/clk/emc/max_rate | tee /sys/kernel/debug/bpmp/debug/clk/emc/rate

may I know what’s your pipeline to test the camera stream?
please refer to Applications Using V4L2 IOCTL Directly, to use V4L2 IOCTL to verify basic camera functionality.
for instance,
$ v4l2-ctl -d /dev/video0 --list-formats-ext
$ v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=RG10 --set-ctrl bypass_mode=0 --stream-mmap --stream-count=100

Hi Jerry,

Thanks. I followed your latest suggestion and completed the exact runtime checks you recommended.

What I ran

  1. BPMP clock boost for VI / ISP / NVCSI / EMC
sudo su
echo 1 > /sys/kernel/debug/bpmp/debug/clk/vi/mrq_rate_locked
echo 1 > /sys/kernel/debug/bpmp/debug/clk/isp/mrq_rate_locked
echo 1 > /sys/kernel/debug/bpmp/debug/clk/nvcsi/mrq_rate_locked
echo 1 > /sys/kernel/debug/bpmp/debug/clk/emc/mrq_rate_locked
cat /sys/kernel/debug/bpmp/debug/clk/vi/max_rate | tee /sys/kernel/debug/bpmp/debug/clk/vi/rate
cat /sys/kernel/debug/bpmp/debug/clk/isp/max_rate | tee /sys/kernel/debug/bpmp/debug/clk/isp/rate
cat /sys/kernel/debug/bpmp/debug/clk/nvcsi/max_rate | tee /sys/kernel/debug/bpmp/debug/clk/nvcsi/rate
cat /sys/kernel/debug/bpmp/debug/clk/emc/max_rate | tee /sys/kernel/debug/bpmp/debug/clk/emc/rate

I wrapped this in a helper only to save before/after values and logs:

Observed clock results

  • vi: 115200000 → 832000000
  • isp: 115200000 → 1011200000
  • nvcsi: 10045312 → 642900000
  • emc: remained 2133000000 even though max_rate = 3199000000

So the clock boost clearly took effect for:

  • vi
  • isp
  • nvcsi

but not for emc.

  1. Direct V4L2 IOCTL test

You asked what pipeline I use for stream testing.

I have been testing with direct v4l2-ctl already, but usually inside an RTCPU/NVCSI trace wrapper.

To follow your suggestion more closely, I also ran a separate direct v4l2-ctl stream test outside the trace wrapper:

The direct helper first records:

  • v4l2-ctl --list-devices
  • v4l2-ctl --list-formats-ext
  • v4l2-ctl --list-ctrls
  • v4l2-ctl --all

Then it runs direct streaming.

Current advertised mode on this driver is still only:

  • BG10
  • 640x480
  • 30 fps

Pre-state artifact:

So I did NOT run 1920x1080 RG10, because the current driver/DT implementation does not advertise that mode yet. I used the currently implemented and enumerated mode instead.

Direct V4L2 command path used

Equivalent direct command is:

v4l2-ctl -d /dev/video0
–set-fmt-video=width=640,height=480,pixelformat=BG10
–set-ctrl sensor_mode=0
–set-ctrl bypass_mode=0
–stream-mmap
–stream-count=100
–verbose

Direct V4L2 runtime artifacts:

Result

The direct V4L2 path still gives the same failure signature:

  • VIDIOC_REQBUFS success
  • VIDIOC_QUERYBUF success
  • VIDIOC_QBUF success
  • VIDIOC_STREAMON returned 0 (Success)
  • capture rc = 124
  • raw output file remains 0 bytes
  • repeated VI timeout:
    • tegra-camrtc-capture-vi: uncorr_err: request timed out after 2500 ms

What this means

This new test seems to rule out several software-side possibilities:

  1. It is not explained by low default receiver clocks for:
  • vi
  • isp
  • nvcsi

because those were successfully forced to max rate.

  1. It is not explained by our RTCPU trace wrapper itself,
    because the direct v4l2-ctl path reproduces the same result.
  2. It is not explained by omitting bypass_mode=0,
    because the direct test explicitly sets bypass_mode=0.
  3. It is not explained by the previously wrong pix_clk_hz,
    because I also already completed a separate controlled retest after correcting:
  • pix_clk_hz: 58333000 → 56004480

Those artifacts are here:

Current direct V4L2 inventory

From the latest pre-state:

  • –list-formats-ext shows only:
    • BG10
    • 640x480
    • 30.000 fps
  • bypass_mode control exists and is writable
  • media graph still looks correct:
    • vi-output, nv_ov5647 9-0036
    • linked to NVCSI

Question

Given all of the above, could you please advise what to check next on Jetson side?

At this point I have already tested:

  • route A
  • route C
  • cross-route software permutations
  • corrected mclk_khz=24000
  • corrected pix_clk_hz=56004480
  • direct V4L2 IOCTL test
  • bypass_mode=0
  • boosted vi/isp/nvcsi clocks

but the result is still always:

  • VIDIOC_STREAMON success
  • zero-byte output
  • repeated VI timeout
  • no observable frame ingress

Specific questions:

  1. Is the fact that emc did not rise to max_rate still important here, even though vi/isp/nvcsi did rise?
  2. Is there another NVIDIA-recommended software-side debug step for the exact case:
  • VIDIOC_STREAMON success
  • repeated uncorr_err
  • no frame data
  1. Since the current driver only advertises BG10 640x480, would you like me to keep debugging this exact minimal mode only, or do you want me to implement another mode first before more
    testing?
  2. Is there any Jetson-specific requirement in:
  • tegra-camera-platform{}
  • mode timing fields
  • endpoint binding
  • metadata settings

that you would still consider suspicious, despite the negative pix_clk_hz and boosted-clock retests?

For convenience, I also wrote a compact report for this exact NVIDIA-requested test:

Thanks.

is it possible to probe the MIPI signaling to ensure there’re high-speed data on the CSI channel?

The problem was with invalid image settings resolution settings. Now the image comes from the driver. Thanks for your help.