C-PHY on E3653

Hello!

We are currently trying to bring-up the C-PHY interface from MAX96712 on the E3653. We already verified D-PHY interface which was working fine.

We have configured MAX96712 to output on 4 trios with 2.5Gbps.

As we follow Camera Design Guide we patched csi5_fops.c to to the lane swizzle (brick_config.lane_polarity[1] = NVCSI_CPHY_POLARITY_BCA;)

In Device Tree we changed from phy_mode = “DPHY”; to phy_mode = “CPHY”;

When we start a v4l2-ctl capture process, we see initialization works fine (also lane swizzle is applied) but we see only capture timeouts but no other events from NVCSI/VI. Even if we have applied e.g. wrong pixel clock hz configuration etc. we would expect to see at least some PHY_INTR0 errors.

We use the following Jetpack version: R36 (release), REVISION: 5.0, GCID: 43688277, BOARD: generic, EABI: aarch64, DATE: Fri Jan 16 03:50:45 UTC 2026

Do you have any tips or help?

hello hne_jet,

could you please share the tracing logs in single text file for reference.
besides.. could you please probe the MIPI signaling to confirm there’s sensor streaming output to CSI port.

Hello!

  1. Probing is really hard on this board. We confirmed with ADI FAE that on MAX96712 PHY0/1 and CSI2_TX1/2 counters are running which confirm that MAX96712 outputs data. Also Video Lock is set. As the board is very small, we need to find a way to probe. W

With: v4l2-ctl -d /dev/video0 --set-fmt-video=width=8192,height=1024,pixelformat=RG12 --set-ctrl bypass_mode=0 --stream-mmap --verbose

dmesg output

CPHY lane polarity is from patched tegra_camera driver

sensor 2-0030 is output from our own sensor video driver (sensor video driver is take-over from working D-PHY configuration)

MIPI Clock and Pixel clock is calculated to fit to C-PHY 2.5Gbps

[ 422.946378] t194-nvcsi 13e00000.host1x:nvcsi@15a00000: CPHY lane polarity set to ABC/BCA/ABC/BCA
[ 422.946736] sensor 2-0030: set_mode ModeIdx = 18
[ 422.946738] sensor 2-0030: mipi_clock = 2500312500
[ 422.946740] sensor 2-0030: pixel_clock = 833333333
[ 422.946741] sensor 2-0030: width = 8192
[ 422.946743] sensor 2-0030: height = 1024
[ 422.946744] sensor 2-0030: line_length = 8192
[ 422.946748] sensor 2-0030: start_streaming was called!
[ 425.467539] tegra-camrtc-capture-vi tegra-capture-vi: uncorr_err: request timed out after 2500 ms

tracing output

       <...>-12162   [000] .......   555.684380: tegra_channel_open: vi-output, sensor 2-0030
    v4l2-ctl-12162   [000] .......   555.718297: tegra_channel_set_power: sensor 2-0030 : 0x1
    v4l2-ctl-12162   [000] .......   555.718346: camera_common_s_power: status : 0x1
    v4l2-ctl-12162   [000] .......   555.718354: tegra_channel_set_power: 13e00000.host1x:nvcsi@15a00000- : 0x1
    v4l2-ctl-12162   [000] .......   555.718356: csi_s_power: enable : 0x1
    v4l2-ctl-12162   [000] .......   555.719209: tegra_channel_capture_setup: vnc_id 0 W 8192 H 1024 fmt c4

vi-output, Rada-12163 [004] … 555.730030: vi_task_submit: class_id:48 ch:0 syncpt_id:37 syncpt_thresh:0 pid:12163 tid:12163
vi-output, Rada-12163 [004] … 555.730046: vi_task_submit: class_id:48 ch:0 syncpt_id:37 syncpt_thresh:0 pid:12163 tid:12163
v4l2-ctl-12162 [001] … 555.730047: tegra_channel_set_stream: enable : 0x1
vi-output, Rada-12163 [004] … 555.730048: vi_task_submit: class_id:48 ch:0 syncpt_id:37 syncpt_thresh:0 pid:12163 tid:12163
vi-output, Rada-12163 [004] … 555.730050: vi_task_submit: class_id:48 ch:0 syncpt_id:37 syncpt_thresh:0 pid:12163 tid:12163
v4l2-ctl-12162 [001] … 555.734436: tegra_channel_set_stream: 13e00000.host1x:nvcsi@15a00000- : 0x1
v4l2-ctl-12162 [001] … 555.734444: csi_s_stream: enable : 0x1
v4l2-ctl-12162 [001] … 555.734773: tegra_channel_set_stream: sensor 2-0030 : 0x1

hello hne_jet,

here’re several of debug approaches..

  1. please double check VI driver for the brick_config.lane_polarity[]
    you may review the NVCSI_CIL_A_POLARITY_SWIZZLE_CTRL has configured correctly.

  2. is it possible to reduce the MAX96712 output data-rate, such as 1.0~1.5 Gsps/trio for testing?

  3. please give it a try to boost all the VI/CSI/ISP clocks. you may skip ISP clock settings for gathering frames via v4l2 IOCTL.
    for instance,

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

just an FYI,
let me share some VI tracing logs with a success image capture as an example
here must be one pair of CHANSEL_PXL_SOF/CHANSEL_PXL_EOF to indicate a frame has detected by VI engine.
afterwards, it’s ATOMP_FRAME_DONE to indicate it’s complete writing a frame to memory.

rtcpu_vinotify_event: tstamp:4058867917 cch:-1 vi:0 tag:CSIMUX_STREAM channel:0x00 frame:0 vi_tstamp:129874754944 data:0x0000000000000001
rtcpu_vinotify_event: tstamp:4059206674 cch:0 vi:0 tag:ATOMP_FS channel:0x00 frame:1 vi_tstamp:129891804896 data:0x0000000800000000
rtcpu_vinotify_event: tstamp:4059206818 cch:0 vi:0 tag:CHANSEL_PXL_SOF channel:0x23 frame:1 vi_tstamp:129891808928 data:0x0000000000000001
rtcpu_vinotify_event: tstamp:4059206976 cch:0 vi:0 tag:VIFALC_ACTIONLST channel:0x23 frame:1 vi_tstamp:129891815424 data:0x0000000008020001
rtcpu_vinotify_error: tstamp:4060164160 cch:0 vi:0 tag:CSIMUX_FRAME channel:0x00 frame:1 vi_tstamp:129925171392 data:0x00000000000000a0
rtcpu_vinotify_event: tstamp:4060166846 cch:0 vi:0 tag:CHANSEL_PXL_EOF channel:0x23 frame:1 vi_tstamp:129923836800 data:0x0000000004370002
rtcpu_vinotify_event: tstamp:4060167015 cch:0 vi:0 tag:ATOMP_FRAME_DONE channel:0x23 frame:1 vi_tstamp:129923837312 data:0x0000000000000000

besides..
please see-also similar discussion thread, Topic 368037 for reference.

Thank you for the hints.

Can I somehow check this register from the driver? I see the brick_config is then used in the csi5_send_control_message, so not entirely clear where the register is actual set.

Regarding speed: Yes, we already tried to reduce speed and boost clocks. We will setup probing next week.

The two mentioned registers in the other thread were already set to max value.

hello hne_jet,

you may give it a try to have register dumps to obtain more CSI details.
you may enable camera stream, and dump PH_WC and PF_CRC to examine the packet. please refer to TRM for details.
such as.. NVCSI_STREAM_0_PH_WC_0 and NVCSI_STREAM_0_PF_CRC_0.

here’re example to check the register from system level.
you should..
– check TRM for [3.1.2 System Address Map] for the base address for NVCSI,
for example, NVCSI 0x15a00000 0x15a4ffff SYSTEM, base=0x15a00000.
– please check the target register offset,
NVCSI_STREAM_0_PH_WC_0, Byte Offset= 0x101dc
– calculate the address of PH_WC,
0x15a00000+0x101dc = 0x15a101dc
– enable the camera stream and dump the PH_WC for its register values,
for example, $ sudo ./busybox devmem 0x15a101dc

BTW,
since there’s firewall settings. please see-also Topic 234321 to disable OEM firewall to access NVCSI registers.

Hello!

Thanks, we will check it out.

In the meanwhile we reduced output speed (3 Trios @ 1200) and now we get continous erros:

class:GLOBAL type:PHY_INTR0 phy:0 cil:0 st:0 vc:0 status:0x00000080

As far as I understand this would mean intr_cil_data_lane_ctrl_err1_a (NVCSI_PHY_1_CILA_INTR_0_STATUS_CILA_0)

We will further try to reduce speed to see if that changes something. Or is this error related to soemthing else?

hello hne_jet,

it shows LP sequence error.
normally, it should follow by LP11->LP01->LP00->LP11 sequence. it’s more like a hardware issue.

Ok, so could be an error in the lane mapping/swizzling.

Just to double check this before we look into hardware issue - this is excerpt from Orin AGX Datasheet - Table 5-5

The Trios are connected according to Mapping Option 2.

Device Tree is set to num_lanes=3 in video mode and in port configuration we set port_index=0 and bus_width=3.

In the csi5_stream_set_config in csi5_fops.c I added this code:

if (!is_cphy) {

    unsigned int index = 0;

    for (index = 0; index < NVCSI_BRICK_NUM_LANES; index++)

        brick_config.lane_polarity\[index\] = (lane_polarity >> index) & (0x1);

} else {

        brick_config.lane_polarity\[0\] = NVCSI_CPHY_POLARITY_ABC;

        brick_config.lane_polarity\[1\] = NVCSI_CPHY_POLARITY_BCA;

        brick_config.lane_polarity\[2\] = NVCSI_CPHY_POLARITY_ABC;

        brick_config.lane_polarity\[3\] = NVCSI_CPHY_POLARITY_ABC;

        brick_config.lane_swizzle = 0x1000;

    dev_info(csi->dev, "CPHY lane polarity set to ABC/BCA/ABC/ABC\\n");

} 

I set the lane_swizzle register here explicitly. Is this correct?

hello hne_jet,

this looks incorrect.
you may refer to camrtc-capture.h for the definition of NVCSI lane swizzles.
for instance,
please give it a try to set… brick_config.lane_swizzle = NVCSI_LANE_SWIZZLE_A0A1B0B1;

It seems the lane polarity is set correct, but seems not to fit the hardware yet. So maybe this is root cause.

With:

        brick_config.lane_polarity\[0\] = NVCSI_CPHY_POLARITY_ABC;

        brick_config.lane_polarity\[1\] = NVCSI_CPHY_POLARITY_BCA;

        brick_config.lane_polarity\[2\] = NVCSI_CPHY_POLARITY_ABC;

        brick_config.lane_polarity\[3\] = NVCSI_CPHY_POLARITY_ABC;



        brick_config.lane_swizzle = NVCSI_LANE_SWIZZLE_A0A1B0B1;

We get the above erros (class:GLOBAL type:PHY_INTR0 phy:0 cil:0 st:0 vc:0 status:0x00000080) → intr_cil_data_lane_ctrl_err1_a

With

        brick_config.lane_polarity\[0\] = NVCSI_CPHY_POLARITY_ABC;

        brick_config.lane_polarity\[1\] = NVCSI_CPHY_POLARITY_ABC;

        brick_config.lane_polarity\[2\] = NVCSI_CPHY_POLARITY_BCA;

        brick_config.lane_polarity\[3\] = NVCSI_CPHY_POLARITY_ABC;



        brick_config.lane_swizzle = NVCSI_LANE_SWIZZLE_A0A1B0B1;

the errors change to type:PHY_INTR0 phy:0 cil:1 st:0 vc:0 status:0x00000008 → intr_cil_data_lane_ctrl_err0_a

I don’t fully understand the reason behind the need for lane polarity change, but it seems to make a difference (Trio 0 → A0A/B/C → CSI0 D0P/N/CLK0P, Trio 1 → A1A/B/C → CSI0 CLK0N/D1P/D1N, Trio 2 → B0A/B/C → CSI1 D0P/D0N/CLK1P).

Hello!

Sorry, another update. We changed to num_lanes=2 on Device Tree and MAX96712.

Now we tried different polarity settings.

We get different output but still no data.

 kworker/2:1-79      [002] .......   447.253159: rtcpu_vinotify_event: tstamp:14734015077 cch:0 vi:0 tag:VIFALC_TDSTATE channel:0x23 frame:0 vi_tstamp:471472946304 data:0x359d580010000000
 kworker/2:1-79      [002] .......   447.253160: rtcpu_vinotify_event: tstamp:14734015221 cch:0 vi:0 tag:VIFALC_TDSTATE channel:0x23 frame:0 vi_tstamp:471472988384 data:0x0000000031000001
 kworker/2:1-79      [002] .......   447.253160: rtcpu_vinotify_event: tstamp:14734015374 cch:0 vi:0 tag:VIFALC_TDSTATE channel:0x23 frame:0 vi_tstamp:471473006560 data:0x359d550010000000
 kworker/2:1-79      [002] .......   447.253161: rtcpu_vinotify_event: tstamp:14734015505 cch:0 vi:0 tag:VIFALC_ACTIONLST channel:0x23 frame:0 vi_tstamp:471473026880 data:0x0000000007020001
 kworker/2:1-79      [002] .......   447.253162: rtcpu_vinotify_event: tstamp:14734015656 cch:0 vi:0 tag:VIFALC_TDSTATE channel:0x23 frame:0 vi_tstamp:471473069248 data:0x0000000031000002
 kworker/2:1-79      [002] .......   447.253164: rtcpu_nvcsi_intr: tstamp:14734112729 class:GLOBAL type:PHY_INTR0 phy:0 cil:0 st:0 vc:0 status:0x60000000

PHY_INTR0 = 0x60000000 would mean edge_delay_cal_done_trio1/0 → Is this expected or not? Does this mean Orin saw a valid state on CPHY trio?

But still no data yet …

We currently program MAX96712 output speed to 2C → which should mean 1200 MHz*2,28 = 2 736 mbit/s

With the formula Mbit*Lanes / bpp this should yield in our case (RAW12, 2 Trios) now 456000000 for serdes_pix_clk_hz/pix_clk_hz, correct?

hello hne_jet,

that’s correct, it means CPHY calibration has done.
may I double check your lane_polarity settings for lane-0 and lane-1?

FYI,
since there’s no other tracing logs. it means VI has not receive a frame.
you should expect it following with CHANSEL_PXL_SOF/CHANSEL_PXL_EOF for a validate frame, and then ATOMP_FRAME_DONE to indicate a frame has written to memory correctly.

let’s double check your sensor pixel clock rate.
you may review your clock rate with CPHY factor.. 16/7 instead of using approximate 2.28.
so.. your data rate should be.. 1200 Mhz * 16 / 7 ~= 2742857143 bits/s/trio.
serdes_pix_clk_hz = 2742857143 * 2 (trio) / 12 (Raw12) ~= 457142857 Hz, which is higher than your settings.
please try update your sensor pixel clock rate for verification.

Hello!

I changed to the suggested 457142857 Hz. But I still see no data.

Regarding polartiy:

With lane[0] = ABC and lane[1] = BCA I only get type:PHY_INTR0 phy:0 cil:0 st:0 vc:0 status:0x00000080 no matter polarity setting on MAX96712.

With lane[0] = ABC and lane[1]= ABC I can get the CPHY calibration done flag by also adjusting lane polarity on MAX96712.

Btw, we again cross-checked the sensor yesterday with D-PHY. D-PHY reception on Orin from MAX96712 is working fine with 2.5 GBit/s @ 4 lanes (so just to confirm that sensor is working and video pipe configuration of MAX96712 is fine).

hello hne_jet,

you should follow the schematic for setting lane_polarity.
please see-also three-trio IMX318 as an example.
$public_sources/kernel_src/hardware/nvidia/t23x/nv-public/overlay/tegra234-camera-e3331-a00.dtsi
it should be..
– Trio 0: ABC → ABC
– Trio 1: ABC → BCA
– Trio 2: ABC → ABC
then, here’s the lane_polarity configuration..
brick_config.lane_polarity[0] = NVCSI_CPHY_POLARITY_ABC; /* A0 */
brick_config.lane_polarity[1] = NVCSI_CPHY_POLARITY_BCA; /* A1 */
brick_config.lane_polarity[2] = NVCSI_CPHY_POLARITY_ABC; /* B0 */
brick_config.lane_polarity[3] = NVCSI_CPHY_POLARITY_ABC; /* unused */