Re: [PATCH v10 00/22] media: i2c: add Maxim GMSL2/3 serializer and deserializer drivers

From: Jagan Teki

Date: Thu May 07 2026 - 07:52:02 EST


On Tue, 7 Apr 2026 at 01:47, Dumitru Ceclan via B4 Relay
<devnull+dumitru.ceclan.analog.com@xxxxxxxxxx> wrote:
>
> This series adds new drivers for multiple Maxim GMSL2 and GMSL3 devices,
> replacing the few GMSL2 drivers already in upstream, and introducing a
> common framework that can be used to implement such GMSL chips, which
> avoids code duplication while also adding support for previously
> unsupported features.
>
> While the normally acceptable and polite way would be to extend the
> current mainline drivers, the choice was made here to add a totally new
> set of drivers. The current drivers support only a small subset of the
> possible features, and only a few devices, so the end result after
> extending them would in any case be essentially fully rewritten, new
> drivers.
>
> This series depends on support for internal pads, for which a patch has
> been added.
>
> The previous version is at:
> v9: https://lore.kernel.org/r/20260311-gmsl2-3_serdes-v9-0-41499f09004f@xxxxxxxxxx
>
> Since the previous series, Cosmin has left Analog Devices.
> Because included changes from previous version are trivial, his sign-off
> and tags were retained.
>
> The following deserializers are supported:
> * MAX96712 (already exists in staging)
> * MAX96714 (already exists)
> * MAX96714F (already exists)
> * MAX96714R (GMSL2)
> * MAX96716 (GMSL2)
> * MAX96724 (already exists as part of existing MAX96712 driver)
> * MAX96724F (GMSL2)
> * MAX96724R (GMSL2)
> * MAX9296A (GMSL2)
> * MAX96792A (GMSL3)
>
> The following serializers are supported:
> * MAX96717 (already exists)
> * MAX9295A (GMSL2)
> * MAX96793 (GMSL3)
>
> The following list enumerates new features that are supported by the
> common framework and their respective chip-specific drivers:
> * Full Streams API support. Most deserializers have support for more
> than one link, and more than one PHY. Streams support allows
> configuration of routing between these links and PHYs.
>
> * .get_frame_desc() support. Both the serializers and deserializers
> implement this to query and provide frame descriptor data. This is
> used in features explained in-depth below.
>
> * .get_mbus_config() support. The deserializers implement this to allow
> upstream devices to query the link frequency of its pads.
>
> * Address translation with I2C ATR for the serializers.
>
> * I2C ATR translation - some deserializers cannot do muxing since I2C
> communication channel masking is not available per-link, and the only
> other way to select links is to turn them off, causing link resets.
> For such cases, I2C ATR is used to change the address of the
> serializers at probe time.
>
> * Automatic GMSL link version negotiation between GMSL3, GMSL2 6Gbps, GMSL2
> 3Gbps.
>
> * Automatic stream id selection for deserializers which need serializers to
> stream on unique stream ids.
>
> * Automatic VC remapping on the deserializers. VCs are picked so that
> if they were unique on the sink pad, they will end up as unique on
> the source pad they are routed to too, prioritizing using the same
> VC ID as the sink pad, to facilitate the possibility of using tunnel
> mode.
>
> * Automatic pixel mode / tunnel mode selection. Tunnel mode is used
> when VC IDs do not need to be changed and all hardware supports
> tunnel mode, otherwise, pixel mode is used. The serializers are
> automatically switched between the two by using a private API.
>
> * Automatic double mode selection. In pixel mode, double mode can be
> used to pack two pixels into a single data unit, optimizing bandwidth
> usage. The serializers are automatically set up to support the double
> modes determined by the deserializers using a private API.
>
> * Automatic data padding. In pixel mode, if the data being transferred
> uses two different BPPs, data needs to be padded. The serializers
> automatically set this up depending on the configured double mode
> settings and incoming data types.
>
> * Logging. Both the deserializers and serializers implement the V4L2
> .log_status() ops to allow debugging of the internal state and
> important chip status registers.
>
> * PHY modes. Deserializer chips commonly have more than a single PHY.
> The firmware ports are parsed to determine the modes in which to
> configure the PHYs (2x4, 4x2, 1x4+2x2, 2x2+1x4, and variations using
> fewer lanes).
>
> * Serializer pinctrl. Serializers implement pinctrl to allow setting
> configs which would otherwise be inaccessible through GPIO: TX/RX via
> GMSL link, pull-up & pull-down (with strength), open-drain &
> push-pull, slew rate, RCLK pin selection.
>
> * TPG with selectable formats, resolutions and framerates for both
> serializers and deserializers.
>
> The drivers have been tested on the following hardware combinations, but
> further testing is welcome to ensure no / minimal breakage:
> * Raspberry Pi 5 + MAX9296A + 2xMAX96717 + 2xIMX219
> * Raspberry Pi 5 + MAX96714 + 1xMAX96717 + 1xIMX219

Thanks for the series. For validation, could you share the DT binding
used while testing this configuration (Raspberry Pi 5 + MAX96714 +
1xMAX96717 + 1xIMX219)?

I used the same with imx415 but, cannot detect the sensor ID.

[ 12.768891] max9296a 7-004c: DT source ports parsed
[ 12.768903] max9296a 7-004c: DT physical configuration selected: 0
[ 12.768909] max9296a 7-004c: DT pipe defaults initialized
[ 12.768919] max9296a 7-004c: DT sink port 0 present
[ 12.768926] max9296a 7-004c: Looking up port0-poc-supply from device tree
[ 12.768978] max9296a 7-004c: DT sink port 0 enabled
[ 12.768989] max9296a 7-004c: DT sink ports parsed
[ 12.768995] max9296a 7-004c: Initializing deserializer core
[ 12.769000] max9296a 7-004c: Applying RLMS adjust sequence (2 regs)
[ 12.770660] max9296a 7-004c: Enabled link A remote control channel
[ 12.771745] max9296a 7-004c: Enabled on-die LDO2
[ 12.771755] max9296a 7-004c: Skipping TPG init for this variant
[ 12.771762] max9296a 7-004c: Disabling deserializer output during init
[ 12.793066] max9296a 7-004c: Link 0 serializer xlate start:
power-up 0x42 alias 0x40
[ 12.793081] max9296a 7-004c: Selecting links mask 0x1
[ 12.796294] max9296a 7-004c: Selected links mask 0x1, waiting for settle
[ 13.108806] max9296a 7-004c: Link 0 serializer responded at 0x40 before reset
[ 13.216637] max9296a 7-004c: Link 0 serializer xlate complete: 0x42 -> 0x40
[ 13.216817] max9296a 7-004c: Selecting links mask 0x1
[ 13.219683] max9296a 7-004c: Selected links mask 0x1, waiting for settle
[ 13.425486] max9296a 7-004c: Consider updating driver max9296a to
match on endpoints
[ 13.425503] rockchip-csi2-dphy csi2-dcphy0: dphy0 matches max9296a
7-004c:bus type 5
[ 13.499022] max96717 10-0042: Allocated serializer core state
[ 13.499081] max96717 10-0042: Parsed serializer DT
[ 13.524495] max96717 10-0042: Initialized serializer core state
[ 13.524511] max96717 10-0042: Initializing serializer i2c-atr adapter
[ 13.527562] max96717 10-0042: Initialized serializer child I2C adapter
[ 13.527587] max96717 10-0042: Registering serializer notifier
[ 13.527598] max96717 10-0042: Added serializer source notifier for phy 0
[ 13.527607] max96717 10-0042: Registered serializer notifier
[ 13.527619] max96717 10-0042: Consider updating driver max96717 to
match on endpoints
[ 13.527635] max96717 10-0042: Registered serializer V4L2 subdevice
[ 13.540303] imx415 11-0037: detect imx415 lane 4
[ 13.540310] imx415 11-0037: current mode 2, cfg_num 12
[ 13.540356] imx415 11-0037: Failed to get reset-gpios
[ 13.540369] imx415 11-0037: Failed to get power-gpios
[ 13.540377] imx415 11-0037: no pinctrl
[ 13.540385] imx415 11-0037: Looking up dvdd-supply from device tree
[ 13.540450] imx415 11-0037: Looking up dovdd-supply from device tree
[ 13.540495] imx415 11-0037: Looking up avdd-supply from device tree
[ 13.580898] imx415 11-0037: Requested xvclk=24000000 actual=24000000
[ 13.630800] imx415 11-0037: Read chip ID reg 0x311a = 0x00 (ret=0)
[ 13.630815] imx415 11-0037: Sensor state: 0x3000=0x00 0x3001=0x00
0x311b=0x00 0x311c=0x00 0x311d=0x00
[ 13.630825] imx415 11-0037: Unexpected sensor id(000000), ret(0)

DT:
&i2c7 {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";

max96718_dcphy0: deserializer@4c {
compatible = "maxim,max96718";
reg = <0x4c>;

port0-poc-supply = <&vcc_3v3_adapter>;
i2c-alias-pool = <0x40>;

ports {
#address-cells = <1>;
#size-cells = <0>;

port@0 {
reg = <0>;

max96718_link0_in: endpoint {
remote-endpoint = <&max96717_gmsl_out>;
};
};

port@2 {
reg = <2>;

max96718_csi_out: endpoint {
remote-endpoint = <&mipidcphy0_in>;
data-lanes = <1 2 3 4>;
link-frequencies = /bits/ 64 <400000000>;
};
};
};

i2c-atr {
#address-cells = <1>;
#size-cells = <0>;

i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;

max96717_0: serializer@42 {
compatible = "maxim,max96717f";
reg = <0x42>;
gpio-controller;
#gpio-cells = <2>;
#clock-cells = <0>;
i2c-alias-pool = <0x11 0x12>;
pinctrl-names = "default";
pinctrl-0 = <&max96717_0_pwen_pins
&max96717_0_rclkout_pins>;

max96717_0_pwen_pins: pwen-pins {
function = "gpio";
pins = "mfp0";
drive-push-pull;
bias-disable;
output-high;
};

max96717_0_rclkout_pins: rclkout-pins {
function = "rclkout";
pins = "mfp4";
};

ports {
#address-cells = <1>;
#size-cells = <0>;

port@0 {
reg = <0>;

max96717_csi_in: endpoint {
remote-endpoint = <&imx415_0_out0>;
data-lanes = <1 2 3 4>;
};
};

port@1 {
reg = <1>;

max96717_gmsl_out: endpoint {
remote-endpoint = <&max96718_link0_in>;
};
};
};

i2c-atr {
#address-cells = <1>;
#size-cells = <0>;

i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;

sensor@37 {
compatible = "sony,imx415";
reg = <0x37>;
rpi-global-reg-list;
clocks = <&max96717_0>;
clock-names = "xvclk";
avdd-supply = <&avdd_2v9_cam0>;
dovdd-supply = <&dovdd_1v8_cam0>;
dvdd-supply = <&dvdd_1v1_cam0>;

port {
imx415_0_out0: endpoint {
remote-endpoint = <&max96717_csi_in>;
data-lanes = <1 2 3 4>;
};
};
};
};
};
};
};
};
};
};

Did I miss anything on the sensor side or in the DT?

Thanks,
Jagan.