Hello,
I got a problem get the streaming out of the ISX031 which is connected over GMSL.
The camera sensor is connected to a MAX96717 Serializer and the serializer is connected over a MAX9626a deserializer to CSI connector.
As I could see the drivers are loaded and the gmsl seems to be established, but the driver of the sensor won’t enter the s_stream.
What am I missing.
I’m using the Jetpack 6.2.1 with the 5.15.148-tegra kernel.
My devicetree:
// SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2023-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
/dts-v1/;
/plugin/;
include <dt-bindings/tegra234-p3767-0000-common.h>
include <dt-bindings/clock/tegra234-clock.h>
include <dt-bindings/gpio/tegra234-gpio.h>
define CAM0_PWDN TEGRA234_MAIN_GPIO(H, 6)
define CAM1_PWDN TEGRA234_MAIN_GPIO(AC, 0)
define CAM2_PWDN TEGRA234_AON_GPIO(CC, 1) // GPIO04
define CAM3_PWDN TEGRA234_AON_GPIO(EE, 2) // GPIO10
define CAMERA_I2C_MUX_BUS(x) (0x1E + x)
// CAM0_MCLK - Pin_116 - GPIO(P, 0)
// CAM1_MCLK - Pin_122 - GPIO(P, 1)
// CAM2_MCLK - GPIO02 - GPIO(Q, 5)
// CAM3_MCLK - GPIO11 - GPIO(Q, 6)
/ {
overlay-name = “MAX9296A → MAX96717 → ISX031 2-lane”;
jetson-header-name = “Jetson 24pin CSI Connector”;
compatible = JETSON_COMPATIBLE_P3768;
fragment-camera@0 {
target-path = "/";
__overlay__ {
tegra-capture-vi {
num-channels = <1>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
status = "okay";
reg = <0>;
dsboard_ornx_vi_in0: endpoint {
status = "okay";
port-index = <0>;
bus-width = <2>;
remote-endpoint = <&dsboard_ornx_csi_out0>;
};
};
};
};
bus@0 {
host1x@13e00000 {
nvcsi@15a00000 {
num-channels = <1>;
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
channel@0 {
status = "okay";
reg = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
status = "okay";
reg = <0>;
dsboard_ornx_csi_in0: endpoint@0 {
status = "okay";
port-index = <0>;
bus-width = <2>;
vc-id = <0>;
remote-endpoint = <&des0_out_ep>;
};
};
port@1 {
status = "okay";
reg = <1>;
dsboard_ornx_csi_out0: endpoint@1 {
status = "okay";
remote-endpoint = <&dsboard_ornx_vi_in0>;
};
};
};
};
};
};
i2c@3180000 {
pca9544a_70: pca9544a@70 {
status = "okay";
force_bus_start = <CAMERA_I2C_MUX_BUS(0)>;
i2c@0 {
reg = <0>;
i2c-mux,deselect-on-exit;
#address-cells = <1>;
#size-cells = <0>;
des0: deserializer@48 {
compatible = "maxim,max9296a";
reg = <0x48>; /* <-- adjust to your strap/address */
/* Required by the base maxim-deserializer.yaml */
#address-cells = <1>;
#size-cells = <0>;
maxim,tunnel-mode = <1>;
/* Enable link 0 to establish GMSL connection */
maxim,link-enable-mask = <0x01>;
maxim,him-enable; /* High immunity mode for better signal integrity */
/*
* max9296a binding limits this to maxItems=2.
* Values are example alias addresses.
*/
i2c-alias-pool = <0x60 0x61>;
ports {
#address-cells = <1>;
#size-cells = <0>;
/* Output port: deserializer -> SoC CSI receiver */
port@0 {
reg = <0>;
max9296_chan0_out: endpoint {
remote-endpoint = <&dsboard_ornx_csi_in0>;
clock-lanes = <0>;
data-lanes = <1 2>;
};
}; /* Input port: serializer -> deserializer */
port@1 {
reg = <1>;
max9296_chan0_in: endpoint {
remote-endpoint = <&ser0_out_ep>;
};
};
};
/*
* max9296a binding: i2c@0..1 with reg 0..1
* This creates “virtual” downstream I2C adapters per link.
*/
i2c-atr {
#address-cells = <1>;
#size-cells = <0>;
/* Link 0 downstream I2C */
des0_i2c0: i2c@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
/*
* Serializer on link0.
* (reg = serializer I2C address on the remote bus)
*/
ser0: serializer@40 {
compatible = "maxim,max96717";
reg = <0x40>; /* <-- adjust to your strap/address */
#address-cells = <1>;
#size-cells = <0>;
/* Required by maxim,max96717.yaml */
gpio-controller;
#gpio-cells = <2>;
/*
* max96717 binding limits this to maxItems=1.
* Used for aliasing access to devices behind the serializer.
*/
i2c-alias-pool = <0x30>;
/*
* max96717 binding allows only i2c@0 (reg max 0).
* Put your image sensor behind the serializer here.
*/
i2c-atr {
#address-cells = <1>;
#size-cells = <0>;
ser0_i2c0: i2c@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
/* Optional: example sensor placeholder */
sensor0: sensor@1a {
compatible = "sony,isx031";
reg = <0x1a>;
/* Add these required properties */
devnode = "video0";
physical_w = "15.0";
physical_h = "12.5";
sensor_model = "isx031";
use_sensor_mode_id = "true";
/* GMSL link configuration - REQUIRED for GMSL framework */
gmsl-link {
src-csi-port = "a"; /* Port at which sensor is connected to serializer */
dst-csi-port = "a"; /* Destination CSI port on Jetson (NVCSI) */
serdes-csi-link = "a"; /* GMSL link (link A) */
csi-mode = "1x2"; /* 1 sensor, 2 lanes */
st-vc = <0>; /* Source virtual channel ID */
vc-id = <0>; /* Destination virtual channel ID assigned by deserializer */
num-lanes = <2>; /* Number of CSI lanes */
streams = "yuv8"; /* Stream type */
};
/* Add mode configuration matching your ISX031 specs */
mode0 { /* ISX031_MODE_1920x1280_YUYV */
mclk_khz = "24000";
num_lanes = "2";
tegra_sinterface = "serial_a";
phy_mode = "DPHY";
discontinuous_clk = "no";
dpcm_enable = "false";
cil_settletime = "0";
vc_id = "0"; /* REQUIRED: Virtual channel ID for ARGUS */
active_w = "1920";
active_h = "1280";
mode_type = "yuv";
pixel_phase = "yuyv";
csi_pixel_bit_depth = "16";
readout_orientation = "0";
line_length = "2120";
inherent_gain = "1";
pix_clk_hz = "125000000";
serdes_pix_clk_hz = "300000000";
gain_factor = "10";
framerate_factor = "1000000";
exposure_factor = "1000000";
min_gain_val = "1"; /* dB */
max_gain_val = "480"; /* dB */
step_gain_val = "3"; /* 0.3 */
default_gain = "1";
min_hdr_ratio = "1";
max_hdr_ratio = "1";
min_framerate = "30000000"; /* 30.0 fps */
max_framerate = "30000000"; /* 30.0 fps */
step_framerate = "1";
default_framerate = "30000000"; /* 30.0 fps */
min_exp_time = "30"; /* us, 2 lines */
max_exp_time = "660000";
step_exp_time = "1";
default_exp_time = "33334"; /* us */
embedded_metadata_height = "0";
};
/* Example media graph endpoint from sensor -> serializer input */
port {
sensor0_out: endpoint {
remote-endpoint = <&ser0_in_ep>;
/* data-lanes/clock-lanes if CSI-2 sensor */
clock-lanes = <0>;
data-lanes = <1 2>;
};
};
};
};
};
/*
* Per maxim,max96717.yaml:
* - pipe reg must be 0
* - maxim,phy-id must be 0
*/
pipe@0 {
reg = <0>;
maxim,phy-id = <0>;
maxim,stream-id = <0>; /* allowed by base serializer schema */
};
/*
* Per maxim,max96717.yaml:
* - maxim,pipe-id must be 0
* - maxim,vc-id 0..15
*/
channel@0 {
reg = <0>;
maxim,pipe-id = <0>;
maxim,vc-id = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
/* Output port: serializer -> deserializer link */
port@0 {
reg = <0>;
ser0_out_ep: endpoint {
remote-endpoint = <&des0_link0_in_ep>;
};
};
/* Input port: sensor -> serializer */
port@1 {
reg = <1>;
ser0_in_ep: endpoint {
remote-endpoint = <&sensor0_out>;
};
};
};
};
};
};
/* Link 1 downstream I2C (unused in this minimal example) */
des0_i2c1: i2c@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
/* Add ser1 here if you use link 1 */
};
};
/*
* MAX9296A-specific constraints (from maxim,max9296a.yaml):
* - pipe reg 0..3
* - maxim,link-id 0..1
* - maxim,phy-id 0..1
*/
pipe@0 {
reg = <0>;
maxim,link-id = <0>;
maxim,phy-id = <0>;
maxim,stream-id = <0>;
};
/*
* MAX9296A channel constraints:
* - maxim,pipe-id 0..3
* - maxim,phy-id 0..1
* Base deserializer schema requires ports with port@0 + port@1.
*/
channel@0 {
reg = <0>;
maxim,pipe-id = <0>;
maxim,phy-id = <0>;
maxim,src-vc-id = <0>;
maxim,dst-vc-id = <0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
/* Output port: deserializer -> SoC CSI receiver */
port@0 {
reg = <0>;
des0_out_ep: endpoint {
remote-endpoint = <&dsboard_ornx_csi_in0>;
/* Typical CSI-2 properties if your endpoint schema expects them */
clock-lanes = <0>;
data-lanes = <1 2>;
};
};
/* Input port: serializer -> deserializer */
port@1 {
reg = <1>;
des0_link0_in_ep: endpoint {
remote-endpoint = <&ser0_out_ep>;
};
};
};
};
};
};
};
};
};
tegra-camera-platform {
compatible = "nvidia, tegra-camera-platform";
/**
* Physical settings to calculate max ISO BW
*
* num_csi_lanes = <>;
* Total number of CSI lanes when all cameras are active
*
* max_lane_speed = <>;
* Max lane speed in Kbit/s
*
* min_bits_per_pixel = <>;
* Min bits per pixel
*
* vi_peak_byte_per_pixel = <>;
* Max byte per pixel for the VI ISO case
*
* vi_bw_margin_pct = <>;
* Vi bandwidth margin in percentage
*
* max_pixel_rate = <>;
* Max pixel rate in Kpixel/s for the ISP ISO case
*
* isp_peak_byte_per_pixel = <>;
* Max byte per pixel for the ISP ISO case
*
* isp_bw_margin_pct = <>;
* Isp bandwidth margin in percentage
*/
num_csi_lanes = <8>;
max_lane_speed = <1500000>;
min_bits_per_pixel = <10>;
vi_peak_byte_per_pixel = <2>;
vi_bw_margin_pct = <25>;
max_pixel_rate = <7500000>;
isp_peak_byte_per_pixel = <5>;
isp_bw_margin_pct = <25>;
/**
* The general guideline for naming badge_info contains 3 parts, and is as follows,
* The first part is the camera_board_id for the module; if the module is in a FFD
* platform, then use the platform name for this part.
* The second part contains the position of the module, ex. "rear" or "front".
* The third part contains the last 6 characters of a part number which is found
* in the module's specsheet from the vendor.
*/
modules {
module0 {
status = "okay";
badge = "dsboard_ornx_bottomleft";
position = "bottomleft";
orientation = "1";
drivernode0 {
status = "okay";
pcl_id = "v4l2_sensor";
sysfs-device-tree = "/sys/firmware/devicetree/base/bus@0/i2c@3180000/pca9544a@70/i2c@0/deserializer@48/i2c-atr/i2c@0/serializer@40/i2c-atr/i2c@0/sensor@1a";
};
};
};
};
}; //__overlay__ ends
}; //fragment-camera@0 ends
fragment@1 {
target-path = "/bus@0/gpio@2200000";
__overlay__ {
camera-control-output-high {
gpio-hog;
output-high;
gpios = <CAM0_PWDN GPIO_ACTIVE_HIGH>;
label = "cam0-pwdn";
};
};
};
};
Here is the oputput of the media-ctl
This is the output after the command:
v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=5 --stream-to=/tmp/capture.raw
Hope sombody could help me with that and could tell me what am I missing.
Kind regards

