diff options
author | Rohit Ner <rohitner@google.com> | 2023-04-25 00:14:41 -0700 |
---|---|---|
committer | Rohit Ner <rohitner@google.com> | 2023-04-25 09:29:54 -0700 |
commit | 6e57b2f00e36e63da765e3aa1650b03772999726 (patch) | |
tree | 082e86142f3824bb82da2dca2226089146abe245 | |
parent | 100f56d873591a8de61ff8826c2ed8cdd09f3338 (diff) | |
download | arm-trusted-firmware-6e57b2f00e36e63da765e3aa1650b03772999726.tar.gz |
fix(ufs): poll UCRDY for all commands
Host must only set UICCMD if HCS.UCRDY is set to 1.
At present, SW polls for UCRDY only before sending DME_GET.
Generalise this behaviour for DME_SET, DME_LINKSTARTUP,
DME_HIBERNATE_EXIT by moving polling logic inside ufshc_send_uic_cmd.
Signed-off-by: Rohit Ner <rohitner@google.com>
Change-Id: Iece777f803a660fdd144a073834c221e889371a6
-rw-r--r-- | drivers/ufs/ufs.c | 25 |
1 files changed, 12 insertions, 13 deletions
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c index ea82d02c7..b8137c2c3 100644 --- a/drivers/ufs/ufs.c +++ b/drivers/ufs/ufs.c @@ -161,14 +161,22 @@ static int ufs_wait_for_int_status(const uint32_t expected_status, int ufshc_send_uic_cmd(uintptr_t base, uic_cmd_t *cmd) { unsigned int data; - int result; + int result, retries; if (base == 0 || cmd == NULL) return -EINVAL; - data = mmio_read_32(base + HCS); - if ((data & HCS_UCRDY) == 0) + for (retries = 0; retries < 100; retries++) { + data = mmio_read_32(base + HCS); + if ((data & HCS_UCRDY) != 0) { + break; + } + mdelay(1); + } + if (retries >= 100) { return -EBUSY; + } + mmio_write_32(base + IS, ~0); mmio_write_32(base + UCMDARG1, cmd->arg1); mmio_write_32(base + UCMDARG2, cmd->arg2); @@ -187,7 +195,6 @@ int ufshc_send_uic_cmd(uintptr_t base, uic_cmd_t *cmd) int ufshc_dme_get(unsigned int attr, unsigned int idx, unsigned int *val) { uintptr_t base; - unsigned int data; int result, retries; uic_cmd_t cmd; @@ -197,19 +204,11 @@ int ufshc_dme_get(unsigned int attr, unsigned int idx, unsigned int *val) return -EINVAL; base = ufs_params.reg_base; - for (retries = 0; retries < 100; retries++) { - data = mmio_read_32(base + HCS); - if ((data & HCS_UCRDY) != 0) - break; - mdelay(1); - } - if (retries >= 100) - return -EBUSY; - cmd.arg1 = (attr << 16) | GEN_SELECTOR_IDX(idx); cmd.arg2 = 0; cmd.arg3 = 0; cmd.op = DME_GET; + for (retries = 0; retries < UFS_UIC_COMMAND_RETRIES; ++retries) { result = ufshc_send_uic_cmd(base, &cmd); if (result == 0) |