Merge changes Iaf21883b,I523c5d57,I57164923 into integration
* changes:
fix(ufs): read and write attribute based on spec
fix(ufs): disables controller if enabled
refactor(ufs): adds a function for fdeviceinit
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index 15d80ae..7db6c0b 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -146,11 +146,43 @@
return 0;
}
+static int ufshc_hce_disable(uintptr_t base)
+{
+ unsigned int data;
+ int timeout;
+
+ /* Disable Host Controller */
+ mmio_write_32(base + HCE, HCE_DISABLE);
+ timeout = HCE_DISABLE_TIMEOUT_US;
+ do {
+ data = mmio_read_32(base + HCE);
+ if ((data & HCE_ENABLE) == HCE_DISABLE) {
+ break;
+ }
+ udelay(1);
+ } while (--timeout > 0);
+
+ if (timeout <= 0) {
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+
static int ufshc_reset(uintptr_t base)
{
unsigned int data;
int retries, result;
+ /* disable controller if enabled */
+ if (mmio_read_32(base + HCE) & HCE_ENABLE) {
+ result = ufshc_hce_disable(base);
+ if (result != 0) {
+ return -EIO;
+ }
+ }
+
for (retries = 0; retries < HCE_ENABLE_OUTER_RETRIES; ++retries) {
result = ufshc_hce_enable(base);
if (result == 0) {
@@ -408,7 +440,7 @@
break;
case QUERY_WRITE_ATTR:
query_upiu->query_func = QUERY_FUNC_STD_WRITE;
- memcpy((void *)&query_upiu->ts.attr.value, (void *)buf, length);
+ query_upiu->ts.attr.value = htobe32(*((uint32_t *)buf));
break;
default:
assert(0);
@@ -594,12 +626,14 @@
case QUERY_READ_FLAG:
*(uint32_t *)buf = (uint32_t)resp->ts.flag.value;
break;
- case QUERY_READ_ATTR:
case QUERY_READ_DESC:
memcpy((void *)buf,
(void *)(utrd.resp_upiu + sizeof(query_resp_upiu_t)),
size);
break;
+ case QUERY_READ_ATTR:
+ *(uint32_t *)buf = htobe32(resp->ts.attr.value);
+ break;
default:
/* Do nothing in default case */
break;
@@ -733,16 +767,41 @@
return size - resp->res_trans_cnt;
}
+static int ufs_set_fdevice_init(void)
+{
+ unsigned int result;
+ int timeout;
+
+ ufs_set_flag(FLAG_DEVICE_INIT);
+
+ timeout = FDEVICEINIT_TIMEOUT_MS;
+ do {
+ result = ufs_read_flag(FLAG_DEVICE_INIT);
+ if (!result) {
+ break;
+ }
+ mdelay(5);
+ timeout -= 5;
+ } while (timeout > 0);
+
+ if (result != 0U) {
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
static void ufs_enum(void)
{
unsigned int blk_num, blk_size;
- int i;
+ int i, result;
ufs_verify_init();
ufs_verify_ready();
- ufs_set_flag(FLAG_DEVICE_INIT);
- mdelay(200);
+ result = ufs_set_fdevice_init();
+ assert(result == 0);
+
/* dump available LUNs */
for (i = 0; i < UFS_MAX_LUNS; i++) {
ufs_read_capacity(i, &blk_num, &blk_size);
@@ -751,6 +810,8 @@
i, blk_num, blk_size);
}
}
+
+ (void)result;
}
static void ufs_get_device_info(struct ufs_dev_desc *card_data)
diff --git a/include/drivers/ufs.h b/include/drivers/ufs.h
index c074e85..4a5e464 100644
--- a/include/drivers/ufs.h
+++ b/include/drivers/ufs.h
@@ -69,6 +69,7 @@
/* Host Controller Enable */
#define HCE 0x34
#define HCE_ENABLE 1
+#define HCE_DISABLE 0
/* Host UIC Error Code PHY Adapter Layer */
#define UECPA 0x38
@@ -264,6 +265,9 @@
#define HCE_ENABLE_OUTER_RETRIES 3
#define HCE_ENABLE_INNER_RETRIES 50
#define HCE_ENABLE_TIMEOUT_US 100
+#define HCE_DISABLE_TIMEOUT_US 1000
+
+#define FDEVICEINIT_TIMEOUT_MS 1500
/**
* ufs_dev_desc - ufs device details from the device descriptor