Provide HS-G4 support in MediaTek UFS platforms. To support HS-G4, introduce mechanism to get the MediaTek UFS controller version. With such information, driver can make right decision to apply different configurations in different controllers. Signed-off-by: Stanley Chu <stanley.chu@xxxxxxxxxxxx> --- drivers/scsi/ufs/ufs-mediatek.c | 32 ++++++++++++++++++++++++++++++++ drivers/scsi/ufs/ufs-mediatek.h | 11 +++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c index dda028ec30dc..1a355f519556 100644 --- a/drivers/scsi/ufs/ufs-mediatek.c +++ b/drivers/scsi/ufs/ufs-mediatek.c @@ -569,6 +569,24 @@ static int ufs_mtk_setup_clocks(struct ufs_hba *hba, bool on, return ret; } +static void ufs_mtk_get_controller_version(struct ufs_hba *hba) +{ + struct ufs_mtk_host *host = ufshcd_get_variant(hba); + int ret, ver = 0; + + if (host->hw_ver.major) + return; + + /* Set default (minimum) version anyway */ + host->hw_ver.major = 2; + + ret = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_LOCALVERINFO), &ver); + if (!ret) { + if (ver >= UFS_UNIPRO_VER_1_8) + host->hw_ver.major = 3; + } +} + /** * ufs_mtk_init - find other essential mmio bases * @hba: host controller instance @@ -649,7 +667,9 @@ static int ufs_mtk_pre_pwr_change(struct ufs_hba *hba, struct ufs_pa_layer_attr *dev_max_params, struct ufs_pa_layer_attr *dev_req_params) { + struct ufs_mtk_host *host = ufshcd_get_variant(hba); struct ufs_dev_params host_cap; + u32 adapt_val; int ret; host_cap.tx_lanes = UFS_MTK_LIMIT_NUM_LANES_TX; @@ -674,6 +694,16 @@ static int ufs_mtk_pre_pwr_change(struct ufs_hba *hba, __func__); } + if (host->hw_ver.major >= 3) { + if (dev_req_params->gear_tx == UFS_HS_G4) + adapt_val = PA_INITIAL_ADAPT; + else + adapt_val = PA_NO_ADAPT; + ufshcd_dme_set(hba, + UIC_ARG_MIB(PA_TXHSADAPTTYPE), + adapt_val); + } + return ret; } @@ -724,6 +754,8 @@ static int ufs_mtk_pre_link(struct ufs_hba *hba) int ret; u32 tmp; + ufs_mtk_get_controller_version(hba); + ret = ufs_mtk_unipro_set_lpm(hba, false); if (ret) return ret; diff --git a/drivers/scsi/ufs/ufs-mediatek.h b/drivers/scsi/ufs/ufs-mediatek.h index 30f45dfce04c..ac37b11803fb 100644 --- a/drivers/scsi/ufs/ufs-mediatek.h +++ b/drivers/scsi/ufs/ufs-mediatek.h @@ -35,8 +35,8 @@ */ #define UFS_MTK_LIMIT_NUM_LANES_RX 2 #define UFS_MTK_LIMIT_NUM_LANES_TX 2 -#define UFS_MTK_LIMIT_HSGEAR_RX UFS_HS_G3 -#define UFS_MTK_LIMIT_HSGEAR_TX UFS_HS_G3 +#define UFS_MTK_LIMIT_HSGEAR_RX UFS_HS_G4 +#define UFS_MTK_LIMIT_HSGEAR_TX UFS_HS_G4 #define UFS_MTK_LIMIT_PWMGEAR_RX UFS_PWM_G4 #define UFS_MTK_LIMIT_PWMGEAR_TX UFS_PWM_G4 #define UFS_MTK_LIMIT_RX_PWR_PWM SLOW_MODE @@ -107,6 +107,12 @@ struct ufs_mtk_crypt_cfg { int vcore_volt; }; +struct ufs_mtk_hw_ver { + u8 step; + u8 minor; + u8 major; +}; + struct ufs_mtk_host { struct phy *mphy; struct regulator *reg_va09; @@ -115,6 +121,7 @@ struct ufs_mtk_host { struct reset_control *crypto_reset; struct ufs_hba *hba; struct ufs_mtk_crypt_cfg *crypt; + struct ufs_mtk_hw_ver hw_ver; enum ufs_mtk_host_caps caps; bool mphy_powered_on; bool unipro_lpm; -- 2.18.0