mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-26 14:55:16 +00:00
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>
This commit is contained in:
parent
15e5958560
commit
5ac25de695
3 changed files with 54 additions and 1 deletions
|
@ -97,10 +97,21 @@ static int dwufs_phy_set_pwr_mode(ufs_params_t *params)
|
||||||
int result;
|
int result;
|
||||||
unsigned int data, tx_lanes, rx_lanes;
|
unsigned int data, tx_lanes, rx_lanes;
|
||||||
uintptr_t base;
|
uintptr_t base;
|
||||||
|
unsigned int flags;
|
||||||
|
|
||||||
assert((params != NULL) && (params->reg_base != 0));
|
assert((params != NULL) && (params->reg_base != 0));
|
||||||
|
|
||||||
base = params->reg_base;
|
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);
|
result = ufshc_dme_get(PA_TACTIVATE_OFFSET, 0, &data);
|
||||||
assert(result == 0);
|
assert(result == 0);
|
||||||
|
|
|
@ -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 ufs_init(const ufs_ops_t *ops, ufs_params_t *params)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
unsigned int data;
|
unsigned int data;
|
||||||
uic_cmd_t cmd;
|
uic_cmd_t cmd;
|
||||||
|
struct ufs_dev_desc card = {0};
|
||||||
|
|
||||||
assert((params != NULL) &&
|
assert((params != NULL) &&
|
||||||
(params->reg_base != 0) &&
|
(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);
|
ops->phy_init(&ufs_params);
|
||||||
result = ufshc_link_startup(ufs_params.reg_base);
|
result = ufshc_link_startup(ufs_params.reg_base);
|
||||||
assert(result == 0);
|
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);
|
ops->phy_set_pwr_mode(&ufs_params);
|
||||||
}
|
}
|
||||||
|
|
||||||
ufs_enum();
|
|
||||||
(void)result;
|
(void)result;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#ifndef __UFS_H__
|
#ifndef __UFS_H__
|
||||||
#define __UFS_H__
|
#define __UFS_H__
|
||||||
|
|
||||||
|
#include <utils_def.h>
|
||||||
|
|
||||||
/* register map of UFSHCI */
|
/* register map of UFSHCI */
|
||||||
/* Controller Capabilities */
|
/* Controller Capabilities */
|
||||||
#define CAP 0x00
|
#define CAP 0x00
|
||||||
|
@ -214,6 +216,9 @@
|
||||||
#define DESC_TYPE_INTERCONNECT 0x04
|
#define DESC_TYPE_INTERCONNECT 0x04
|
||||||
#define DESC_TYPE_STRING 0x05
|
#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_CUR_PWR_MODE 0x02 /* bCurrentPowerMode */
|
||||||
#define ATTR_ACTIVECC 0x03 /* bActiveICCLevel */
|
#define ATTR_ACTIVECC 0x03 /* bActiveICCLevel */
|
||||||
|
|
||||||
|
@ -246,8 +251,22 @@
|
||||||
|
|
||||||
#define FLAG_DEVICE_INIT 0x01
|
#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 */
|
/* UFS Driver Flags */
|
||||||
#define UFS_FLAGS_SKIPINIT (1 << 0)
|
#define UFS_FLAGS_SKIPINIT (1 << 0)
|
||||||
|
#define UFS_FLAGS_VENDOR_SKHYNIX (U(1) << 2)
|
||||||
|
|
||||||
typedef struct sense_data {
|
typedef struct sense_data {
|
||||||
uint8_t resp_code : 7;
|
uint8_t resp_code : 7;
|
||||||
|
|
Loading…
Add table
Reference in a new issue