drivers:ufs: fix hynix ufs bug with quirk on hi36xx SoC

Hynix ufs has deviations on hi36xx platform which will result
in ufs bursts transfer failures at a very low probability.

To fix the problem, the Hynix device must set the register
VS_DebugSaveConfigTime to 0x10, which will set time reference
for SaveConfigTime is 250 ns. The time reference for SaveConfigTime
is 40 ns by default.

Signed-off-by: fengbaopeng <fengbaopeng@hisilicon.com>
diff --git a/drivers/synopsys/ufs/dw_ufs.c b/drivers/synopsys/ufs/dw_ufs.c
index d8ed5b6..b0ea3e7 100644
--- a/drivers/synopsys/ufs/dw_ufs.c
+++ b/drivers/synopsys/ufs/dw_ufs.c
@@ -97,10 +97,21 @@
 	int result;
 	unsigned int data, tx_lanes, rx_lanes;
 	uintptr_t base;
+	unsigned int flags;
 
 	assert((params != NULL) && (params->reg_base != 0));
 
 	base = params->reg_base;
+	flags = params->flags;
+	if ((flags & UFS_FLAGS_VENDOR_SKHYNIX) != 0U) {
+		NOTICE("ufs: H**** device must set VS_DebugSaveConfigTime 0x10\n");
+		/* VS_DebugSaveConfigTime */
+		result = ufshc_dme_set(0xd0a0, 0x0, 0x10);
+		assert(result == 0);
+		/* sync length */
+		result = ufshc_dme_set(0x1556, 0x0, 0x48);
+		assert(result == 0);
+	}
 
 	result = ufshc_dme_get(PA_TACTIVATE_OFFSET, 0, &data);
 	assert(result == 0);
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index d513d0a..254866f 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -705,11 +705,27 @@
 	}
 }
 
+static void ufs_get_device_info(struct ufs_dev_desc *card_data)
+{
+	uint8_t desc_buf[DESC_DEVICE_MAX_SIZE];
+
+	ufs_query(QUERY_READ_DESC, DESC_TYPE_DEVICE, 0, 0,
+				(uintptr_t)desc_buf, DESC_DEVICE_MAX_SIZE);
+
+	/*
+	 * getting vendor (manufacturerID) and Bank Index in big endian
+	 * format
+	 */
+	card_data->wmanufacturerid = (uint16_t)((desc_buf[DEVICE_DESC_PARAM_MANF_ID] << 8) |
+				     (desc_buf[DEVICE_DESC_PARAM_MANF_ID + 1]));
+}
+
 int ufs_init(const ufs_ops_t *ops, ufs_params_t *params)
 {
 	int result;
 	unsigned int data;
 	uic_cmd_t cmd;
+	struct ufs_dev_desc card = {0};
 
 	assert((params != NULL) &&
 	       (params->reg_base != 0) &&
@@ -750,10 +766,17 @@
 		ops->phy_init(&ufs_params);
 		result = ufshc_link_startup(ufs_params.reg_base);
 		assert(result == 0);
+
+		ufs_enum();
+
+		ufs_get_device_info(&card);
+		if (card.wmanufacturerid == UFS_VENDOR_SKHYNIX) {
+			ufs_params.flags |= UFS_FLAGS_VENDOR_SKHYNIX;
+		}
+
 		ops->phy_set_pwr_mode(&ufs_params);
 	}
 
-	ufs_enum();
 	(void)result;
 	return 0;
 }