Skip to content

Commit e1b53a0

Browse files
committed
RSDSO-21151: Make HW reset SERDES recovery conditional (light path)
When the GMSL link recovers naturally after HW reset (the common case for D457), skip SERDES recovery and stability verification entirely. This eliminates ~1300ms of unnecessary overhead per reset that was causing timing-sensitive CI test failures (rec-play-got-playback-frames, t2ff-sensor, hdr-performance). Changes: - Step 6: Probe I2C link after Step 5 polling succeeds. If alive, skip ds5_hw_reset_serdes_recovery() (no max9295_init_settings, no Phase 1 stability reads). Only invoke SERDES recovery when I2C is actually broken post-reset (e.g. D401 secondary FW init phase). - Step 10: Skip the 3x200ms stability verification loop and Phase 2 escalation when SERDES recovery was not performed. Steps 7-9 already validate the link via multiple I2C reads. - Reduce DS5_HW_RESET_COOLDOWN_MS from 5000ms to 2000ms. With conditional recovery eliminating unnecessary SERDES disruption, the aggressive cooldown is no longer needed for the common case. v1.0.1.33 (all CI tests passing) used fire-and-forget HW reset with zero SERDES intervention. This change restores that lightweight behavior for the normal path while keeping full tiered recovery as a fallback when the link is genuinely broken.
1 parent f05fed4 commit e1b53a0

1 file changed

Lines changed: 48 additions & 12 deletions

File tree

kernel/realsense/d4xx.c

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2323,7 +2323,7 @@ static int ds5_set_calibration_data(struct ds5 *state,
23232323
* serializer re-init (Phase 1) conflicts with the camera FW's own
23242324
* I2C bus reconfiguration after reboot.
23252325
*/
2326-
#define DS5_HW_RESET_COOLDOWN_MS 5000
2326+
#define DS5_HW_RESET_COOLDOWN_MS 2000
23272327

23282328
/*
23292329
* Register 0x5020 status values (from firmware):
@@ -2641,6 +2641,9 @@ static int ds5_hw_reset_with_recovery(struct ds5 *state)
26412641
int retry;
26422642
int __maybe_unused i;
26432643
u16 status = 0;
2644+
#ifdef CONFIG_VIDEO_D4XX_SERDES
2645+
bool serdes_recovery_ran = false;
2646+
#endif
26442647

26452648
dev_info(&state->client->dev, "%s(): Initiating HW reset with recovery\n",
26462649
__func__);
@@ -2842,15 +2845,37 @@ static int ds5_hw_reset_with_recovery(struct ds5 *state)
28422845
}
28432846

28442847
#ifdef CONFIG_VIDEO_D4XX_SERDES
2845-
/* 6. Tiered SERDES recovery:
2846-
* Phase 1: serializer-only re-init (per-camera, non-disruptive).
2847-
* Phase 2: full deserializer reset only if ALL siblings are also dead.
2848+
/* 6. Tiered SERDES recovery (conditional).
2849+
* Step 5 polled the device over I2C until 0xDEAD was returned,
2850+
* which means the GMSL link was already up at that point. Probe
2851+
* the I2C link once more: if it is still alive, the GMSL link
2852+
* recovered naturally and SERDES re-init is unnecessary (this is
2853+
* the common case for D457). Only invoke SERDES recovery when
2854+
* the link is actually broken — e.g. the camera FW's secondary
2855+
* init phase dropped the bus between Step 5 and now (observed on
2856+
* D401, occasionally on D457).
28482857
*/
2849-
ret = ds5_hw_reset_serdes_recovery(state, false);
2850-
if (ret < 0) {
2851-
dev_err(&state->client->dev,
2852-
"%s(): SERDES recovery failed: %d\n", __func__, ret);
2853-
return ret;
2858+
{
2859+
u16 link_probe = 0;
2860+
2861+
ret = ds5_read(state, DS5_FW_VERSION, &link_probe);
2862+
if (ret < 0 || link_probe == 0) {
2863+
dev_info(&state->client->dev,
2864+
"%s(): I2C link dead after Step 5 (ret=%d, val=0x%x), running SERDES recovery\n",
2865+
__func__, ret, link_probe);
2866+
ret = ds5_hw_reset_serdes_recovery(state, false);
2867+
if (ret < 0) {
2868+
dev_err(&state->client->dev,
2869+
"%s(): SERDES recovery failed: %d\n",
2870+
__func__, ret);
2871+
return ret;
2872+
}
2873+
serdes_recovery_ran = true;
2874+
} else {
2875+
dev_info(&state->client->dev,
2876+
"%s(): GMSL link recovered naturally (FW ver 0x%04x), skipping SERDES recovery\n",
2877+
__func__, link_probe);
2878+
}
28542879
}
28552880
#endif
28562881

@@ -2969,7 +2994,14 @@ static int ds5_hw_reset_with_recovery(struct ds5 *state)
29692994
}
29702995

29712996
#ifdef CONFIG_VIDEO_D4XX_SERDES
2972-
/* 10. Post-reset I2C stability verification.
2997+
/* 10. Post-reset I2C stability verification (conditional).
2998+
* Only needed when SERDES recovery was actively performed in Step 6,
2999+
* because the serializer/deserializer re-init can cause transient
3000+
* I2C instability. When the GMSL link recovered naturally (Step 6
3001+
* was skipped), Steps 7-9 already verified the link via multiple
3002+
* I2C reads — an additional 600ms+ stability loop is unnecessary
3003+
* and causes timing-sensitive CI test failures.
3004+
*
29733005
* Some camera SKUs have a secondary FW initialization phase that
29743006
* briefly drops the I2C bus ~65-110ms after the initial readiness
29753007
* checks (Steps 7-9) pass. This has been observed on both D401
@@ -2984,7 +3016,11 @@ static int ds5_hw_reset_with_recovery(struct ds5 *state)
29843016
* keep waiting (up to DS5_HW_RESET_STABILITY_TIMEOUT_MS). If it
29853017
* remains unstable, escalate to Phase 2 (full deserializer reset).
29863018
*/
2987-
{
3019+
if (!serdes_recovery_ran) {
3020+
dev_info(&state->client->dev,
3021+
"%s(): SERDES recovery was skipped (natural link recovery), "
3022+
"bypassing Step 10 stability verification\n", __func__);
3023+
} else {
29883024
int stable_count = 0;
29893025
unsigned long stab_ts = jiffies;
29903026
unsigned long stab_timeout =
@@ -3057,7 +3093,7 @@ static int ds5_hw_reset_with_recovery(struct ds5 *state)
30573093
__func__);
30583094
}
30593095
}
3060-
}
3096+
} /* if (serdes_recovery_ran) */
30613097
#endif
30623098

30633099
dev_info(&state->client->dev,

0 commit comments

Comments
 (0)