fix(ufs): add reset before DME_LINKSTARTUP
This change aims to make the UFS code more robust by performing a
controller reset if linkstartup fails. This idea was borrowed from
Linux's ufshcd_link_startup function.
Signed-off-by: Jorge Troncoso <jatron@google.com>
Change-Id: I6b52148d1bf155b11198dc82a39b1120057adaaf
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index 695a614..ae42e32 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -169,18 +169,30 @@
return 0;
}
-static int ufshc_link_startup(uintptr_t base)
+static int ufshc_dme_link_startup(uintptr_t base)
{
uic_cmd_t cmd;
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.op = DME_LINKSTARTUP;
+ return ufshc_send_uic_cmd(base, &cmd);
+}
+
+static int ufshc_link_startup(uintptr_t base)
+{
int data, result;
int retries;
- for (retries = 10; retries > 0; retries--) {
- memset(&cmd, 0, sizeof(cmd));
- cmd.op = DME_LINKSTARTUP;
- result = ufshc_send_uic_cmd(base, &cmd);
- if (result != 0)
+ for (retries = DME_LINKSTARTUP_RETRIES; retries > 0; retries--) {
+ result = ufshc_dme_link_startup(base);
+ if (result != 0) {
+ /* Reset controller before trying again */
+ result = ufshc_reset(base);
+ if (result != 0) {
+ return result;
+ }
continue;
+ }
while ((mmio_read_32(base + HCS) & HCS_DP) == 0)
;
data = mmio_read_32(base + IS);