diff --git a/arch/risc-v/src/mpfs/mpfs_ddr.c b/arch/risc-v/src/mpfs/mpfs_ddr.c index 565770dc1fed7..5fdde18bc5a8b 100644 --- a/arch/risc-v/src/mpfs/mpfs_ddr.c +++ b/arch/risc-v/src/mpfs/mpfs_ddr.c @@ -3941,19 +3941,30 @@ static int mpfs_ddr_setup(struct mpfs_ddr_priv_s *priv) int mpfs_ddr_init(void) { struct mpfs_ddr_priv_s *priv = &g_mpfs_ddr_priv; - int ddr_status; - - /* On -EAGAIN, the whole training is restarted from the very beginning */ + int ddr_status = -EAGAIN; + int retry_count = 20; + + /* Restart training until it passes or retry_count reaches 0. + * Errors which return -EAGAIN are known to be always + * recoverable by controller reset; don't count these errors. + * Only count errors which return -EIO; they are typically recoverable. + * If they persist, however, eventually return failure, leading to + * re-trying after full reset. + */ - do + while (ddr_status != OK && retry_count > 0) { ddr_status = mpfs_ddr_setup(priv); - if (ddr_status == -EAGAIN) + if (ddr_status != OK) { mpfs_ddr_fail(priv); } + + if (ddr_status != -EAGAIN) + { + retry_count--; + } } - while (ddr_status == -EAGAIN); if (ddr_status == 0) {