summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRohit Ner <rohitner@google.com>2023-04-25 00:14:41 -0700
committerRohit Ner <rohitner@google.com>2023-04-25 09:29:54 -0700
commit6e57b2f00e36e63da765e3aa1650b03772999726 (patch)
tree082e86142f3824bb82da2dca2226089146abe245
parent100f56d873591a8de61ff8826c2ed8cdd09f3338 (diff)
downloadarm-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.c25
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)