diff --git a/drivers/scsi/ufs/ufs-tegra.c b/drivers/scsi/ufs/ufs-tegra.c index 3ae829a8..5093459f 100644 --- a/drivers/scsi/ufs/ufs-tegra.c +++ b/drivers/scsi/ufs/ufs-tegra.c @@ -136,6 +136,23 @@ static int ufs_tegra_mphy_receiver_calibration(struct ufs_tegra_host *ufs_tegra, return err; } +static void ufs_tegra_mphy_war(struct ufs_tegra_host *ufs_tegra) +{ + if ((ufs_tegra->soc->chip_id == TEGRA234) && (ufs_tegra->x2config)) { + reset_control_assert(ufs_tegra->mphy_l1_rx_rst); + udelay(50); + reset_control_deassert(ufs_tegra->mphy_l1_rx_rst); + udelay(2); + + mphy_update(ufs_tegra->mphy_l1_base, + MPHY_ENABLE_RX_MPHY2UPHY_IF_OVR_CTRL, + MPHY_RX_APB_VENDOR3_0_T234); + mphy_update(ufs_tegra->mphy_l1_base, MPHY_GO_BIT, + MPHY_RX_APB_VENDOR2_0_T234); + udelay(5); + } +} + static void ufs_tegra_disable_mphylane_clks(struct ufs_tegra_host *host) { if (!host->is_lane_clks_enabled) @@ -699,12 +716,15 @@ static void ufs_tegra_mphy_rx_sync_capability(struct ufs_tegra_host *ufs_tegra) u32 val_94_97 = 0; u32 val_8c_8f = 0; u32 val_98_9b = 0; - u32 vendor2_reg; + u32 vendor2_reg, vendor3_reg; - if (ufs_tegra->soc->chip_id == TEGRA234) + if (ufs_tegra->soc->chip_id == TEGRA234) { vendor2_reg = MPHY_RX_APB_VENDOR2_0_T234; - else + vendor3_reg = MPHY_RX_APB_VENDOR3_0_T234; + } else { vendor2_reg = MPHY_RX_APB_VENDOR2_0; + vendor3_reg = MPHY_RX_APB_VENDOR3_0; + } /* MPHY RX sync lengths capability changes */ @@ -746,6 +766,9 @@ static void ufs_tegra_mphy_rx_sync_capability(struct ufs_tegra_host *ufs_tegra) MPHY_RX_APB_CAPABILITY_8C_8F_0); mphy_writel(ufs_tegra->mphy_l0_base, val_98_9b, MPHY_RX_APB_CAPABILITY_98_9B_0); + mphy_update(ufs_tegra->mphy_l0_base, + MPHY_ENABLE_RX_MPHY2UPHY_IF_OVR_CTRL, + vendor3_reg); mphy_update(ufs_tegra->mphy_l0_base, MPHY_GO_BIT, vendor2_reg); @@ -758,6 +781,9 @@ static void ufs_tegra_mphy_rx_sync_capability(struct ufs_tegra_host *ufs_tegra) MPHY_RX_APB_CAPABILITY_8C_8F_0); mphy_writel(ufs_tegra->mphy_l1_base, val_98_9b, MPHY_RX_APB_CAPABILITY_98_9B_0); + mphy_update(ufs_tegra->mphy_l1_base, + MPHY_ENABLE_RX_MPHY2UPHY_IF_OVR_CTRL, + vendor3_reg); /* set gobit */ mphy_update(ufs_tegra->mphy_l1_base, MPHY_GO_BIT, vendor2_reg); @@ -1209,8 +1235,11 @@ static int ufs_tegra_pwr_change_notify(struct ufs_hba *hba, * Clock boost during power change * is required as per T234 IAS document */ - if (ufs_tegra->soc->chip_id == TEGRA234) + if (ufs_tegra->soc->chip_id == TEGRA234) { ufs_tegra_pwr_change_clk_boost(ufs_tegra); + ufshcd_dme_configure_adapt(hba, dev_req_params->gear_rx, + PA_INITIAL_ADAPT); + } } else { if (ufs_tegra->max_pwm_gear) { ufshcd_dme_get(hba, @@ -1354,6 +1383,7 @@ static int ufs_tegra_link_startup_notify(struct ufs_hba *hba, ufs_tegra->mphy_l0_base); if (err) return err; + ufs_tegra_mphy_war(ufs_tegra); break; default: break; diff --git a/drivers/scsi/ufs/ufs-tegra.h b/drivers/scsi/ufs/ufs-tegra.h index 4e447670..46bf5003 100644 --- a/drivers/scsi/ufs/ufs-tegra.h +++ b/drivers/scsi/ufs/ufs-tegra.h @@ -93,8 +93,11 @@ #define MPHY_RX_APB_VENDOR2_0 0x184 #define MPHY_RX_APB_VENDOR2_0_T234 0x2184 +#define MPHY_RX_APB_VENDOR3_0 0x188 +#define MPHY_RX_APB_VENDOR3_0_T234 0x2188 #define MPHY_RX_APB_VENDOR2_0_RX_CAL_EN (1 << 15) #define MPHY_RX_APB_VENDOR2_0_RX_CAL_DONE (1 << 19) +#define MPHY_ENABLE_RX_MPHY2UPHY_IF_OVR_CTRL (1 << 26) #define MPHY_RX_CAPABILITY_88_8B_VAL_FPGA 0x4f00fa1a #define MPHY_RX_CAPABILITY_8C_8F_VAL_FPGA 0x50e080e