Skip to content

Commit 3f9b6ce

Browse files
CC Choumartinkpetersen
authored andcommitted
scsi: ufs: ufs-mediatek: Introduce workaround for power mode change
Some MediaTek SoC chips need special flow for power mode change, especially for chips supporting HS-G5. Enable the workaround by setting the host-specific capability. Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Stanley Chu <[email protected]> Signed-off-by: CC Chou <[email protected]> Signed-off-by: Eddie Huang <[email protected]> Signed-off-by: Dennis Yu <[email protected]> Signed-off-by: Peter Wang <[email protected]> Signed-off-by: Stanley Chu <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent d81c4c6 commit 3f9b6ce

File tree

3 files changed

+60
-2
lines changed

3 files changed

+60
-2
lines changed

drivers/ufs/host/ufs-mediatek.c

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,13 @@ static bool ufs_mtk_is_broken_vcc(struct ufs_hba *hba)
8282
return !!(host->caps & UFS_MTK_CAP_BROKEN_VCC);
8383
}
8484

85+
static bool ufs_mtk_is_pmc_via_fastauto(struct ufs_hba *hba)
86+
{
87+
struct ufs_mtk_host *host = ufshcd_get_variant(hba);
88+
89+
return (host->caps & UFS_MTK_CAP_PMC_VIA_FASTAUTO);
90+
}
91+
8592
static void ufs_mtk_cfg_unipro_cg(struct ufs_hba *hba, bool enable)
8693
{
8794
u32 tmp;
@@ -579,6 +586,9 @@ static void ufs_mtk_init_host_caps(struct ufs_hba *hba)
579586
if (of_property_read_bool(np, "mediatek,ufs-broken-vcc"))
580587
host->caps |= UFS_MTK_CAP_BROKEN_VCC;
581588

589+
if (of_property_read_bool(np, "mediatek,ufs-pmc-via-fastauto"))
590+
host->caps |= UFS_MTK_CAP_PMC_VIA_FASTAUTO;
591+
582592
dev_info(hba->dev, "caps: 0x%x", host->caps);
583593
}
584594

@@ -754,6 +764,26 @@ static int ufs_mtk_init(struct ufs_hba *hba)
754764
return err;
755765
}
756766

767+
static bool ufs_mtk_pmc_via_fastauto(struct ufs_hba *hba,
768+
struct ufs_pa_layer_attr *dev_req_params)
769+
{
770+
if (!ufs_mtk_is_pmc_via_fastauto(hba))
771+
return false;
772+
773+
if (dev_req_params->hs_rate == hba->pwr_info.hs_rate)
774+
return false;
775+
776+
if (dev_req_params->pwr_tx != FAST_MODE &&
777+
dev_req_params->gear_tx < UFS_HS_G4)
778+
return false;
779+
780+
if (dev_req_params->pwr_rx != FAST_MODE &&
781+
dev_req_params->gear_rx < UFS_HS_G4)
782+
return false;
783+
784+
return true;
785+
}
786+
757787
static int ufs_mtk_pre_pwr_change(struct ufs_hba *hba,
758788
struct ufs_pa_layer_attr *dev_max_params,
759789
struct ufs_pa_layer_attr *dev_req_params)
@@ -763,8 +793,8 @@ static int ufs_mtk_pre_pwr_change(struct ufs_hba *hba,
763793
int ret;
764794

765795
ufshcd_init_pwr_dev_param(&host_cap);
766-
host_cap.hs_rx_gear = UFS_HS_G4;
767-
host_cap.hs_tx_gear = UFS_HS_G4;
796+
host_cap.hs_rx_gear = UFS_HS_G5;
797+
host_cap.hs_tx_gear = UFS_HS_G5;
768798

769799
ret = ufshcd_get_pwr_dev_param(&host_cap,
770800
dev_max_params,
@@ -774,6 +804,32 @@ static int ufs_mtk_pre_pwr_change(struct ufs_hba *hba,
774804
__func__);
775805
}
776806

807+
if (ufs_mtk_pmc_via_fastauto(hba, dev_req_params)) {
808+
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXTERMINATION), true);
809+
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXGEAR), UFS_HS_G1);
810+
811+
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_RXTERMINATION), true);
812+
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_RXGEAR), UFS_HS_G1);
813+
814+
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_ACTIVETXDATALANES),
815+
dev_req_params->lane_tx);
816+
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_ACTIVERXDATALANES),
817+
dev_req_params->lane_rx);
818+
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HSSERIES),
819+
dev_req_params->hs_rate);
820+
821+
ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXHSADAPTTYPE),
822+
PA_NO_ADAPT);
823+
824+
ret = ufshcd_uic_change_pwr_mode(hba,
825+
FASTAUTO_MODE << 4 | FASTAUTO_MODE);
826+
827+
if (ret) {
828+
dev_err(hba->dev, "%s: HSG1B FASTAUTO failed ret=%d\n",
829+
__func__, ret);
830+
}
831+
}
832+
777833
if (host->hw_ver.major >= 3) {
778834
ret = ufshcd_dme_configure_adapt(hba,
779835
dev_req_params->gear_tx,

drivers/ufs/host/ufs-mediatek.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ enum ufs_mtk_host_caps {
108108
UFS_MTK_CAP_VA09_PWR_CTRL = 1 << 1,
109109
UFS_MTK_CAP_DISABLE_AH8 = 1 << 2,
110110
UFS_MTK_CAP_BROKEN_VCC = 1 << 3,
111+
UFS_MTK_CAP_PMC_VIA_FASTAUTO = 1 << 6,
111112
};
112113

113114
struct ufs_mtk_crypt_cfg {

include/ufs/unipro.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ enum ufs_hs_gear_tag {
228228
UFS_HS_G2, /* HS Gear 2 */
229229
UFS_HS_G3, /* HS Gear 3 */
230230
UFS_HS_G4, /* HS Gear 4 */
231+
UFS_HS_G5 /* HS Gear 5 */
231232
};
232233

233234
enum ufs_unipro_ver {

0 commit comments

Comments
 (0)