Skip to content

Commit b2ca414

Browse files
committed
refactor: move IMU pipe 3 setup from hw_reset to first-probe, gate on DT
Remove Step 11 (unconditional pipe 3 setup) from ds5_hw_reset_with_recovery(). It was a hack that configured the IMU pipe even on cameras without an IMU. Two callers need pipe 3 reconfiguration after HW reset: 1. First-probe (ds5_probe): The D457 FW configures pipes 0-2 during boot but not pipe 3. Move the ds5_setup_pipeline() call into the first-probe block, gated on a DT sibling walk that checks for a cam-type=IMU peer node. This ensures pipe 3 is only configured when an IMU actually exists in the device tree. 2. HWMC reset (ds5_s_ctrl): ds5_invalidate_sensor() already clears pipe_data_type1/2/vc_id for all peers in Step 2. At the next STREAMON, ds5_configure() detects the mismatch and calls ds5_setup_pipeline() to reconfigure each pipe no special handling needed in hw_reset. Update Step 6 and Step 11 comments to document this split.
1 parent a613224 commit b2ca414

1 file changed

Lines changed: 80 additions & 63 deletions

File tree

kernel/realsense/d4xx.c

Lines changed: 80 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)