Skip to content

Commit 9cd345a

Browse files
committed
Step 11: Replace full init_settings with targeted pipe 3 setup
max9295_init_settings() writes to global serializer registers (0x02 pipe enable, 0x308 CSI port select, 0x311 data source, 0x331 MIPI RX) that disrupt the active GMSL link. When called in Step 11 where the link is UP (either naturally recovered or restored by Phase 1/2) these global register writes kill the link within ~34ms, cascading into total I2C failure (-121) for all addresses (9-001a/b/c/d). Replace with ds5_setup_pipeline() for pipe 3 (IMU) only. This calls max9295_set_pipe() + dser set_pipe() which write ONLY per-pipe registers (data type, vc_id, BPP, LIM_HEART) no global registers are touched and the GMSL link remains stable. The D457 FW configures pipes 0-2 (Depth, RGB, IR) during boot. Pipe 3 (IMU) is the only one the driver must add post-reset. Symptom: After HW reset via HWMC (light path), init_settings at T+236ms kills the GMSL link. 34ms later all I2C addresses return -121, leading to IMU stream start failure and eventually Phase 2 deserializer reset.
1 parent cb2eca1 commit 9cd345a

1 file changed

Lines changed: 33 additions & 36 deletions

File tree

kernel/realsense/d4xx.c

Lines changed: 33 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3103,53 +3103,50 @@ static int ds5_hw_reset_with_recovery(struct ds5 *state)
31033103
}
31043104
} /* if (serdes_recovery_ran) */
31053105

3106-
/* 11. Final SERDES pipe restoration (unconditional).
3107-
* The D457 FW continues reconfiguring the MAX9295 serializer
3108-
* for ~50-100ms after reporting 0xDEAD. Any earlier call to
3109-
* max9295_init_settings() — whether from Phase 1 (heavy path)
3110-
* or skipped entirely (light path) — may have been overwritten
3111-
* by the FW's late-boot serializer init. Re-applying the
3112-
* driver's authoritative pipe configuration here, after Steps
3113-
* 7-10 have consumed enough time, ensures all 4 pipes —
3114-
* including pipe 3 (IMU, vc_id=3) — are correctly configured.
3106+
/* 11. Targeted pipe 3 (IMU) restoration (unconditional).
3107+
* The D457 FW configures MAX9295 pipes 0-2 (Depth, RGB, IR)
3108+
* during boot but does NOT configure pipe 3 (IMU, vc_id=3).
3109+
* Without pipe 3, the serializer has no I2C address translation
3110+
* for 9-001d and the IMU is unreachable (-EREMOTEIO / -121).
31153111
*
3116-
* Light path: FW finished ~100ms after 0xDEAD but Steps 7-9
3117-
* may be as short as 12ms → need 150ms extra wait.
3118-
* Heavy path (Phase 1): Phase 1 itself takes ~750ms (100ms
3119-
* post-init sleep + 3×200ms stability reads) plus Steps 7-9,
3120-
* so the FW is long done → no extra wait needed.
3121-
* Heavy path (Phase 2): Full deser reset already called
3122-
* init_settings inside recovery, but re-calling is harmless
3123-
* insurance and keeps the logic simple.
3112+
* CRITICAL: Do NOT call max9295_init_settings() here. That
3113+
* function writes to global registers (0x02 pipe enable, 0x308
3114+
* CSI port select, 0x311 pipe data source, 0x331 MIPI RX) that
3115+
* disrupt the active GMSL link. The link is UP at this point
3116+
* (either naturally recovered or restored by Phase 1/2), and
3117+
* writing those global registers kills it immediately.
3118+
*
3119+
* Instead, call ds5_setup_pipeline() for pipe 3 only. This
3120+
* calls max9295_set_pipe() + dser set_pipe() which write ONLY
3121+
* per-pipe registers (data type, vc_id, BPP, LIM_HEART) —
3122+
* no global registers, no link disruption.
3123+
*
3124+
* Light path: 150ms delay for FW to finish MAX9295 reconfig.
3125+
* Heavy path (Phase 1/2): no delay — FW is long done.
31243126
*/
31253127
{
3126-
int ser_ret, dser_ret;
3128+
int pipe3_ret;
31273129

31283130
if (!serdes_recovery_ran) {
3129-
/* Light path: FW may still be reconfiguring MAX9295.
3130-
* Wait for it to finish before we overwrite its config.
3131+
/* Light path: FW continues writing to MAX9295 for
3132+
* ~50-100ms after 0xDEAD. Wait for it to finish
3133+
* before we configure pipe 3.
31313134
*/
31323135
msleep(150);
31333136
}
3134-
/* Heavy path: no extra delay — Phase 1/2 already consumed
3135-
* enough time for FW to finish MAX9295 reconfig.
3136-
*/
31373137

3138-
ser_ret = max9295_init_settings(state->ser_dev);
3139-
if (ser_ret)
3138+
pipe3_ret = ds5_setup_pipeline(state,
3139+
GMSL_CSI_DT_YUV422_8,
3140+
GMSL_CSI_DT_EMBED,
3141+
3, /* pipe_id = 3 (IMU) */
3142+
3 /* vc_id = 3 */);
3143+
if (pipe3_ret)
31403144
dev_warn(&state->client->dev,
3141-
"%s(): post-reset ser init_settings failed: %d\n",
3142-
__func__, ser_ret);
3143-
3144-
dser_ret = state->dser_ops->init_settings(state->dser_dev);
3145-
if (dser_ret)
3146-
dev_warn(&state->client->dev,
3147-
"%s(): post-reset deser init_settings failed: %d\n",
3148-
__func__, dser_ret);
3149-
3150-
if (!ser_ret && !dser_ret)
3145+
"%s(): post-reset pipe 3 (IMU) setup failed: %d\n",
3146+
__func__, pipe3_ret);
3147+
else
31513148
dev_info(&state->client->dev,
3152-
"%s(): SERDES pipe configuration restored after %s recovery\n",
3149+
"%s(): pipe 3 (IMU) configured after %s recovery\n",
31533150
__func__,
31543151
serdes_recovery_ran ? "SERDES" : "light-path");
31553152
}

0 commit comments

Comments
 (0)