summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/synopsys/ufs/dw_ufs.c11
-rw-r--r--drivers/ufs/ufs.c25
-rw-r--r--include/drivers/ufs.h19
3 files changed, 54 insertions, 1 deletions
diff --git a/drivers/synopsys/ufs/dw_ufs.c b/drivers/synopsys/ufs/dw_ufs.c
index d8ed5b6c..b0ea3e73 100644
--- a/drivers/synopsys/ufs/dw_ufs.c
+++ b/drivers/synopsys/ufs/dw_ufs.c
@@ -97,10 +97,21 @@ static int dwufs_phy_set_pwr_mode(ufs_params_t *params)
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 d513d0a5..254866f8 100644
--- a/drivers/ufs/ufs.c
+++ b/drivers/ufs/ufs.c
@@ -705,11 +705,27 @@ static void ufs_enum(void)
}
}
+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 @@ int ufs_init(const ufs_ops_t *ops, ufs_params_t *params)
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;
}
diff --git a/include/drivers/ufs.h b/include/drivers/ufs.h
index 3a4f1c78..88dedc5a 100644
--- a/include/drivers/ufs.h
+++ b/include/drivers/ufs.h
@@ -7,6 +7,8 @@
#ifndef __UFS_H__
#define __UFS_H__
+#include <utils_def.h>
+
/* register map of UFSHCI */
/* Controller Capabilities */
#define CAP 0x00
@@ -214,6 +216,9 @@
#define DESC_TYPE_INTERCONNECT 0x04
#define DESC_TYPE_STRING 0x05
+#define DESC_DEVICE_MAX_SIZE 0x1F
+#define DEVICE_DESC_PARAM_MANF_ID 0x18
+
#define ATTR_CUR_PWR_MODE 0x02 /* bCurrentPowerMode */
#define ATTR_ACTIVECC 0x03 /* bActiveICCLevel */
@@ -246,8 +251,22 @@
#define FLAG_DEVICE_INIT 0x01
+#define UFS_VENDOR_SKHYNIX U(0x1AD)
+
+#define MAX_MODEL_LEN 16
+/**
+ * ufs_dev_desc - ufs device details from the device descriptor
+ * @wmanufacturerid: card details
+ * @model: card model
+ */
+struct ufs_dev_desc {
+ uint16_t wmanufacturerid;
+ int8_t model[MAX_MODEL_LEN + 1];
+};
+
/* UFS Driver Flags */
#define UFS_FLAGS_SKIPINIT (1 << 0)
+#define UFS_FLAGS_VENDOR_SKHYNIX (U(1) << 2)
typedef struct sense_data {
uint8_t resp_code : 7;