From ef875d7d9e25d4e7be4120457a149f561fc897b7 Mon Sep 17 00:00:00 2001 From: Jukka Laitinen Date: Wed, 29 Jan 2025 14:15:59 +0200 Subject: [PATCH] arch/risc-v/src/mpfs/mpfs_ddr.c: Re-try DDR training on any error Also errors which currently return other than -EAGAIN, are typically recoverable with retraining. So just re-try trainining 20 times on any error, resetting the controller in between. Only reset if it is not recovered in this time. Signed-off-by: Jukka Laitinen --- arch/risc-v/src/mpfs/mpfs_ddr.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/arch/risc-v/src/mpfs/mpfs_ddr.c b/arch/risc-v/src/mpfs/mpfs_ddr.c index c20e456b8fe..e9c0a2f3309 100644 --- a/arch/risc-v/src/mpfs/mpfs_ddr.c +++ b/arch/risc-v/src/mpfs/mpfs_ddr.c @@ -3943,19 +3943,31 @@ 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 retry_count = 20; int ddr_status; - /* On -EAGAIN, the whole training is restarted from the very beginning */ + /* 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 { 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); + while (ddr_status != OK && retry_count > 0); if (ddr_status == 0) {