scsi: ufs: host: ufs-exynos: Add support for FSD UFS HCI
Adds support of UFS HCI which is found in Tesla Full Self-Driving (FSD) SoC. Link: https://lore.kernel.org/r/20220610104119.66401-7-alim.akhtar@samsung.com Co-developed-by: Bharat Uppal <bharat.uppal@samsung.com> Signed-off-by: Bharat Uppal <bharat.uppal@samsung.com> Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
daa782a51e
commit
216f74e805
@ -146,6 +146,10 @@ enum {
|
|||||||
#define UNIPRO_DME_PWR_REQ_REMOTEL2TIMER1 0x0A8
|
#define UNIPRO_DME_PWR_REQ_REMOTEL2TIMER1 0x0A8
|
||||||
#define UNIPRO_DME_PWR_REQ_REMOTEL2TIMER2 0x0AC
|
#define UNIPRO_DME_PWR_REQ_REMOTEL2TIMER2 0x0AC
|
||||||
|
|
||||||
|
#define UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER0 0x78B8
|
||||||
|
#define UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER1 0x78BC
|
||||||
|
#define UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER2 0x78C0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UFS Protector registers
|
* UFS Protector registers
|
||||||
*/
|
*/
|
||||||
@ -1474,6 +1478,99 @@ static int exynosauto_ufs_vh_init(struct ufs_hba *hba)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fsd_ufs_pre_link(struct exynos_ufs *ufs)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct ufs_hba *hba = ufs->hba;
|
||||||
|
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_CLK_PERIOD),
|
||||||
|
DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(0x201), 0x12);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x40);
|
||||||
|
|
||||||
|
for_each_ufs_tx_lane(ufs, i) {
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0xAA, i),
|
||||||
|
DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x8F, i), 0x3F);
|
||||||
|
}
|
||||||
|
|
||||||
|
for_each_ufs_rx_lane(ufs, i) {
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x12, i),
|
||||||
|
DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x5C, i), 0x38);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x0F, i), 0x0);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x65, i), 0x1);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x69, i), 0x1);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x21, i), 0x0);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x22, i), 0x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x0);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_AUTOMODE_THLD), 0x4E20);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OPTION_SUITE), 0x2e820183);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_LOCAL_TX_LCC_ENABLE), 0x0);
|
||||||
|
|
||||||
|
exynos_ufs_establish_connt(ufs);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fsd_ufs_post_link(struct exynos_ufs *ufs)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct ufs_hba *hba = ufs->hba;
|
||||||
|
u32 hw_cap_min_tactivate;
|
||||||
|
u32 peer_rx_min_actv_time_cap;
|
||||||
|
u32 max_rx_hibern8_time_cap;
|
||||||
|
|
||||||
|
ufshcd_dme_get(hba, UIC_ARG_MIB_SEL(0x8F, 4),
|
||||||
|
&hw_cap_min_tactivate); /* HW Capability of MIN_TACTIVATE */
|
||||||
|
ufshcd_dme_get(hba, UIC_ARG_MIB(PA_TACTIVATE),
|
||||||
|
&peer_rx_min_actv_time_cap); /* PA_TActivate */
|
||||||
|
ufshcd_dme_get(hba, UIC_ARG_MIB(PA_HIBERN8TIME),
|
||||||
|
&max_rx_hibern8_time_cap); /* PA_Hibern8Time */
|
||||||
|
|
||||||
|
if (peer_rx_min_actv_time_cap >= hw_cap_min_tactivate)
|
||||||
|
ufshcd_dme_peer_set(hba, UIC_ARG_MIB(PA_TACTIVATE),
|
||||||
|
peer_rx_min_actv_time_cap + 1);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HIBERN8TIME), max_rx_hibern8_time_cap + 1);
|
||||||
|
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_MODE), 0x01);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_SAVECONFIGTIME), 0xFA);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_MODE), 0x00);
|
||||||
|
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x40);
|
||||||
|
|
||||||
|
for_each_ufs_rx_lane(ufs, i) {
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x35, i), 0x05);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x73, i), 0x01);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x41, i), 0x02);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x42, i), 0xAC);
|
||||||
|
}
|
||||||
|
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(0x200), 0x0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fsd_ufs_pre_pwr_change(struct exynos_ufs *ufs,
|
||||||
|
struct ufs_pa_layer_attr *pwr)
|
||||||
|
{
|
||||||
|
struct ufs_hba *hba = ufs->hba;
|
||||||
|
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXTERMINATION), 0x1);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_RXTERMINATION), 0x1);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA0), 12000);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA1), 32000);
|
||||||
|
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PWRMODEUSERDATA2), 16000);
|
||||||
|
|
||||||
|
unipro_writel(ufs, 12000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER0);
|
||||||
|
unipro_writel(ufs, 32000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER1);
|
||||||
|
unipro_writel(ufs, 16000, UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER2);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct ufs_hba_variant_ops ufs_hba_exynos_ops = {
|
static struct ufs_hba_variant_ops ufs_hba_exynos_ops = {
|
||||||
.name = "exynos_ufs",
|
.name = "exynos_ufs",
|
||||||
.init = exynos_ufs_init,
|
.init = exynos_ufs_init,
|
||||||
@ -1596,6 +1693,47 @@ static struct exynos_ufs_drv_data exynos_ufs_drvs = {
|
|||||||
.post_pwr_change = exynos7_ufs_post_pwr_change,
|
.post_pwr_change = exynos7_ufs_post_pwr_change,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct exynos_ufs_uic_attr fsd_uic_attr = {
|
||||||
|
.tx_trailingclks = 0x10,
|
||||||
|
.tx_dif_p_nsec = 3000000, /* unit: ns */
|
||||||
|
.tx_dif_n_nsec = 1000000, /* unit: ns */
|
||||||
|
.tx_high_z_cnt_nsec = 20000, /* unit: ns */
|
||||||
|
.tx_base_unit_nsec = 100000, /* unit: ns */
|
||||||
|
.tx_gran_unit_nsec = 4000, /* unit: ns */
|
||||||
|
.tx_sleep_cnt = 1000, /* unit: ns */
|
||||||
|
.tx_min_activatetime = 0xa,
|
||||||
|
.rx_filler_enable = 0x2,
|
||||||
|
.rx_dif_p_nsec = 1000000, /* unit: ns */
|
||||||
|
.rx_hibern8_wait_nsec = 4000000, /* unit: ns */
|
||||||
|
.rx_base_unit_nsec = 100000, /* unit: ns */
|
||||||
|
.rx_gran_unit_nsec = 4000, /* unit: ns */
|
||||||
|
.rx_sleep_cnt = 1280, /* unit: ns */
|
||||||
|
.rx_stall_cnt = 320, /* unit: ns */
|
||||||
|
.rx_hs_g1_sync_len_cap = SYNC_LEN_COARSE(0xf),
|
||||||
|
.rx_hs_g2_sync_len_cap = SYNC_LEN_COARSE(0xf),
|
||||||
|
.rx_hs_g3_sync_len_cap = SYNC_LEN_COARSE(0xf),
|
||||||
|
.rx_hs_g1_prep_sync_len_cap = PREP_LEN(0xf),
|
||||||
|
.rx_hs_g2_prep_sync_len_cap = PREP_LEN(0xf),
|
||||||
|
.rx_hs_g3_prep_sync_len_cap = PREP_LEN(0xf),
|
||||||
|
.pa_dbg_option_suite = 0x2E820183,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct exynos_ufs_drv_data fsd_ufs_drvs = {
|
||||||
|
.uic_attr = &fsd_uic_attr,
|
||||||
|
.quirks = UFSHCD_QUIRK_PRDT_BYTE_GRAN |
|
||||||
|
UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR |
|
||||||
|
UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR |
|
||||||
|
UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING |
|
||||||
|
UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR,
|
||||||
|
.opts = EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL |
|
||||||
|
EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL |
|
||||||
|
EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR |
|
||||||
|
EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX,
|
||||||
|
.pre_link = fsd_ufs_pre_link,
|
||||||
|
.post_link = fsd_ufs_post_link,
|
||||||
|
.pre_pwr_change = fsd_ufs_pre_pwr_change,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct of_device_id exynos_ufs_of_match[] = {
|
static const struct of_device_id exynos_ufs_of_match[] = {
|
||||||
{ .compatible = "samsung,exynos7-ufs",
|
{ .compatible = "samsung,exynos7-ufs",
|
||||||
.data = &exynos_ufs_drvs },
|
.data = &exynos_ufs_drvs },
|
||||||
@ -1603,6 +1741,8 @@ static const struct of_device_id exynos_ufs_of_match[] = {
|
|||||||
.data = &exynosauto_ufs_drvs },
|
.data = &exynosauto_ufs_drvs },
|
||||||
{ .compatible = "samsung,exynosautov9-ufs-vh",
|
{ .compatible = "samsung,exynosautov9-ufs-vh",
|
||||||
.data = &exynosauto_ufs_vh_drvs },
|
.data = &exynosauto_ufs_vh_drvs },
|
||||||
|
{ .compatible = "tesla,fsd-ufs",
|
||||||
|
.data = &fsd_ufs_drvs },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#define PA_DBG_RXPHY_CFGUPDT 0x9519
|
#define PA_DBG_RXPHY_CFGUPDT 0x9519
|
||||||
#define PA_DBG_MODE 0x9529
|
#define PA_DBG_MODE 0x9529
|
||||||
#define PA_DBG_SKIP_RESET_PHY 0x9539
|
#define PA_DBG_SKIP_RESET_PHY 0x9539
|
||||||
|
#define PA_DBG_AUTOMODE_THLD 0x9536
|
||||||
#define PA_DBG_OV_TM 0x9540
|
#define PA_DBG_OV_TM 0x9540
|
||||||
#define PA_DBG_SKIP_LINE_RESET 0x9541
|
#define PA_DBG_SKIP_LINE_RESET 0x9541
|
||||||
#define PA_DBG_LINE_RESET_REQ 0x9543
|
#define PA_DBG_LINE_RESET_REQ 0x9543
|
||||||
|
Loading…
Reference in New Issue
Block a user