@@ -2854,19 +2854,15 @@ static int ds5_hw_reset_with_recovery(struct ds5 *state)
28542854 * link is still alive, the GMSL link recovered naturally — no
28552855 * full tiered SERDES recovery needed (the common case for D457).
28562856 *
2857- * Do NOT call max9295_init_settings() here on the light path.
2858- * The D457 FW continues reconfiguring the MAX9295 serializer
2859- * for ~50-100ms after reporting 0xDEAD. Calling init_settings
2860- * now races with the FW and gets overwritten. Instead, the
2861- * CALLER is responsible for waiting (≥200ms) and then calling
2862- * max9295_init_settings() + dser init_settings() to restore
2863- * the driver's authoritative pipe configuration. See:
2864- * - ds5_probe() first-probe block (probe-time reset)
2865- * - ds5_s_ctrl() HWMC path (userspace-triggered reset)
2866- *
2867- * This differs from v1.0.1.33 which had no probe-time HW reset,
2868- * so the initial max9295_init_settings() from ds5_serdes_setup()
2869- * was never disrupted and no restoration was needed.
2857+ * Do NOT call max9295_init_settings() here. That function writes
2858+ * global serializer registers (0x02, 0x308, 0x311, 0x331) that
2859+ * disrupt the active GMSL link. Per-pipe reconfiguration is
2860+ * handled by callers:
2861+ * - First-probe: ds5_probe() configures pipe 3 (IMU) after
2862+ * this function returns, before IMU peer probes.
2863+ * - HWMC reset: ds5_invalidate_sensor() clears pipe state for
2864+ * all peers; ds5_configure() re-runs ds5_setup_pipeline()
2865+ * at the next STREAMON for each stream.
28702866 *
28712867 * Only run full tiered recovery (including init_settings +
28722868 * stability checks + Phase 2 escalation) when the I2C link
@@ -3112,53 +3108,19 @@ static int ds5_hw_reset_with_recovery(struct ds5 *state)
31123108 }
31133109 } /* if (serdes_recovery_ran) */
31143110
3115- /* 11. Targeted pipe 3 (IMU) restoration (unconditional).
3116- * The D457 FW configures MAX9295 pipes 0-2 (Depth, RGB, IR)
3117- * during boot but does NOT configure pipe 3 (IMU, vc_id=3).
3118- * Without pipe 3, the serializer has no I2C address translation
3119- * for 9-001d and the IMU is unreachable (-EREMOTEIO / -121).
3120- *
3121- * CRITICAL: Do NOT call max9295_init_settings() here. That
3122- * function writes to global registers (0x02 pipe enable, 0x308
3123- * CSI port select, 0x311 pipe data source, 0x331 MIPI RX) that
3124- * disrupt the active GMSL link. The link is UP at this point
3125- * (either naturally recovered or restored by Phase 1/2), and
3126- * writing those global registers kills it immediately.
3111+ /* 11. Per-pipe reconfiguration is NOT done here.
3112+ * - First-probe: ds5_probe() configures pipe 3 (IMU) after
3113+ * this function returns, before IMU peer probes.
3114+ * - HWMC reset: ds5_invalidate_sensor() (Step 2) already
3115+ * cleared pipe_data_type1/2/vc_id for all peers. At next
3116+ * STREAMON, ds5_configure() detects the mismatch and calls
3117+ * ds5_setup_pipeline() to reconfigure each pipe.
31273118 *
3128- * Instead, call ds5_setup_pipeline() for pipe 3 only. This
3129- * calls max9295_set_pipe() + dser set_pipe() which write ONLY
3130- * per-pipe registers (data type, vc_id, BPP, LIM_HEART) —
3131- * no global registers, no link disruption.
3132- *
3133- * Light path: 150ms delay for FW to finish MAX9295 reconfig.
3134- * Heavy path (Phase 1/2): no delay — FW is long done.
3119+ * Do NOT call max9295_init_settings() or ds5_setup_pipeline()
3120+ * here. init_settings() writes global MAX9295 registers that
3121+ * kill the GMSL link. And for HWMC resets, the existing
3122+ * ds5_configure() path handles pipe reconfiguration cleanly.
31353123 */
3136- {
3137- int pipe3_ret ;
3138-
3139- if (!serdes_recovery_ran ) {
3140- /* Light path: FW continues writing to MAX9295 for
3141- * ~50-100ms after 0xDEAD. Wait for it to finish
3142- * before we configure pipe 3.
3143- */
3144- msleep (150 );
3145- }
3146-
3147- pipe3_ret = ds5_setup_pipeline (state ,
3148- DS5_IMU_DT1 ,
3149- DS5_IMU_DT2 ,
3150- DS5_IMU_PIPE_ID ,
3151- DS5_IMU_VC_ID );
3152- if (pipe3_ret )
3153- dev_warn (& state -> client -> dev ,
3154- "%s(): post-reset pipe 3 (IMU) setup failed: %d\n" ,
3155- __func__ , pipe3_ret );
3156- else
3157- dev_info (& state -> client -> dev ,
3158- "%s(): pipe 3 (IMU) configured after %s recovery\n" ,
3159- __func__ ,
3160- serdes_recovery_ran ? "SERDES" : "light-path" );
3161- }
31623124#endif
31633125
31643126 dev_info (& state -> client -> dev ,
@@ -6807,12 +6769,67 @@ static int ds5_probe(struct i2c_client *c, const struct i2c_device_id *id)
68076769 goto e_chardev ;
68086770 }
68096771
6810- /* Allow the camera firmware to fully stabilize after HW reset.
6811- * ds5_hw_reset_with_recovery() Step 11 waits 150ms and then
6812- * restores SERDES pipe configuration . This additional delay
6813- * provides a buffer before subsequent peer probes attempt I2C .
6772+ /* Wait for D457 FW to finish reconfiguring the MAX9295
6773+ * serializer. The FW continues writing to MAX9295 for
6774+ * ~50-100ms after reporting 0xDEAD . 200ms total provides
6775+ * margin before we touch serializer registers .
68146776 */
6815- msleep (100 );
6777+ msleep (200 );
6778+
6779+ #ifdef CONFIG_VIDEO_D4XX_SERDES
6780+ /* Configure pipe 3 (IMU) on the serializer/deserializer,
6781+ * but only if an IMU peer actually exists in the device tree.
6782+ *
6783+ * The D457 FW configures pipes 0-2 (Depth/RGB/IR) during
6784+ * boot but does NOT configure pipe 3. Without pipe 3,
6785+ * the serializer has no I2C address translation for the
6786+ * IMU instance and its probe will fail with -EREMOTEIO.
6787+ *
6788+ * Only needed at first-probe time. For HWMC resets,
6789+ * ds5_configure() handles pipe reconfiguration at STREAMON.
6790+ *
6791+ * Uses ds5_setup_pipeline() (per-pipe registers only),
6792+ * NOT max9295_init_settings() which writes global registers
6793+ * (0x02, 0x308, 0x311) that disrupt the active GMSL link.
6794+ */
6795+ {
6796+ struct device_node * bus_node , * peer ;
6797+ const char * peer_cam_type ;
6798+ bool has_imu_peer = false;
6799+
6800+ bus_node = of_get_parent (c -> dev .of_node );
6801+ if (bus_node ) {
6802+ for_each_child_of_node (bus_node , peer ) {
6803+ if (!of_property_read_string (peer , "cam-type" ,
6804+ & peer_cam_type ) &&
6805+ !strcmp (peer_cam_type , "IMU" )) {
6806+ has_imu_peer = true;
6807+ of_node_put (peer );
6808+ break ;
6809+ }
6810+ }
6811+ of_node_put (bus_node );
6812+ }
6813+
6814+ if (has_imu_peer ) {
6815+ int pipe3_ret = ds5_setup_pipeline (state ,
6816+ DS5_IMU_DT1 , DS5_IMU_DT2 ,
6817+ DS5_IMU_PIPE_ID , DS5_IMU_VC_ID );
6818+ if (pipe3_ret )
6819+ dev_warn (& c -> dev ,
6820+ "%s(): first-probe pipe 3 (IMU) setup failed: %d\n" ,
6821+ __func__ , pipe3_ret );
6822+ else
6823+ dev_info (& c -> dev ,
6824+ "%s(): first-probe pipe 3 (IMU) configured\n" ,
6825+ __func__ );
6826+ } else {
6827+ dev_dbg (& c -> dev ,
6828+ "%s(): no IMU peer in DT, skipping pipe 3 setup\n" ,
6829+ __func__ );
6830+ }
6831+ }
6832+ #endif
68166833 }
68176834
68186835 /* Verify communication with retries and delay.
0 commit comments