diff options
author | fengbaopeng <fengbaopeng@hisilicon.com> | 2018-02-12 20:53:54 +0800 |
---|---|---|
committer | wei li <liwei213@huawei.com> | 2018-02-24 09:30:41 +0800 |
commit | 5ac25de695520bb60b54bbe91a66c58ba28bde42 (patch) | |
tree | 493081d39e9b78edae567cf78d325920f90ef78d /drivers/ufs | |
parent | 15e5958560e9d31e7357e3a0ada2289e78758839 (diff) |
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>
Diffstat (limited to 'drivers/ufs')
-rw-r--r-- | drivers/ufs/ufs.c | 25 |
1 files changed, 24 insertions, 1 deletions
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; } |