On Fri, 2024-03-08 at 15:02 +0800, peter.wang@xxxxxxxxxxxx wrote: > From: Peter Wang <peter.wang@xxxxxxxxxxxx> > > VSX(the upper layer of VCCQ/VCCQ2) should > 1. Always set to hpm mode if ufs device is active. > 2. Enter lpm mode only if ufs device is not active. > > VCCQX should > 1. Keep hpm mode if vccq and vccq2 not set in dts. > 2. Keep hpm mode if vcc not set in dts keep vcc always on. > 3. Keep hpm if broken vcc keep vcc always on and not allow vccq lpm. > 4. Except upper case, can enter lpm mode if ufs device is not active. > > Signed-off-by: Peter Wang <peter.wang@xxxxxxxxxxxx> > --- > drivers/ufs/host/ufs-mediatek.c | 41 +++++++++++++++++++++++------ > ---- > drivers/ufs/host/ufs-mediatek.h | 5 ++++ > 2 files changed, 34 insertions(+), 12 deletions(-) > > diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs- > mediatek.c > index 776bca4f70c8..6fc6fa2ea5bd 100644 > --- a/drivers/ufs/host/ufs-mediatek.c > +++ b/drivers/ufs/host/ufs-mediatek.c > @@ -119,6 +119,13 @@ static bool ufs_mtk_is_pmc_via_fastauto(struct > ufs_hba *hba) > return !!(host->caps & UFS_MTK_CAP_PMC_VIA_FASTAUTO); > } > > +static bool ufs_mtk_is_allow_vccqx_lpm(struct ufs_hba *hba) > +{ > + struct ufs_mtk_host *host = ufshcd_get_variant(hba); > + > + return !!(host->caps & UFS_MTK_CAP_ALLOW_VCCQX_LPM); > +} > + > static void ufs_mtk_cfg_unipro_cg(struct ufs_hba *hba, bool enable) > { > u32 tmp; > @@ -1271,27 +1278,37 @@ static void ufs_mtk_vsx_set_lpm(struct > ufs_hba *hba, bool lpm) > > static void ufs_mtk_dev_vreg_set_lpm(struct ufs_hba *hba, bool lpm) > { > - if (!hba->vreg_info.vccq && !hba->vreg_info.vccq2) > - return; > + bool skip_vccqx = false; > > - /* Skip if VCC is assumed always-on */ > - if (!hba->vreg_info.vcc) > - return; > - > - /* Bypass LPM when device is still active */ > + /* Prevent entering LPM when device is still active */ > if (lpm && ufshcd_is_ufs_dev_active(hba)) > return; > > - /* Bypass LPM if VCC is enabled */ > - if (lpm && hba->vreg_info.vcc->enabled) > - return; > + /* Skip vccqx lpm control and control vsx only */ > + if (!hba->vreg_info.vccq && !hba->vreg_info.vccq2) > + skip_vccqx = true; > + > + /* VCC is always-on, control vsx only */ > + if (!hba->vreg_info.vcc) > + skip_vccqx = true; > + > + /* Broken vcc keep vcc always on, most case control vsx only */ > + if (lpm && hba->vreg_info.vcc && hba->vreg_info.vcc->enabled) { > + /* Some device vccqx/vsx can enter lpm */ > + if (ufs_mtk_is_allow_vccqx_lpm(hba)) > + skip_vccqx = false; > + else /* control vsx only */ > + skip_vccqx = true; > + } > > if (lpm) { > - ufs_mtk_vccqx_set_lpm(hba, lpm); > + if (!skip_vccqx) > + ufs_mtk_vccqx_set_lpm(hba, lpm); > ufs_mtk_vsx_set_lpm(hba, lpm); > } else { > ufs_mtk_vsx_set_lpm(hba, lpm); > - ufs_mtk_vccqx_set_lpm(hba, lpm); > + if (!skip_vccqx) > + ufs_mtk_vccqx_set_lpm(hba, lpm); > } > } > > diff --git a/drivers/ufs/host/ufs-mediatek.h b/drivers/ufs/host/ufs- > mediatek.h > index f76e80d91729..0720da2f1402 100644 > --- a/drivers/ufs/host/ufs-mediatek.h > +++ b/drivers/ufs/host/ufs-mediatek.h > @@ -136,6 +136,11 @@ enum ufs_mtk_host_caps { > UFS_MTK_CAP_VA09_PWR_CTRL = 1 << 1, > UFS_MTK_CAP_DISABLE_AH8 = 1 << 2, > UFS_MTK_CAP_BROKEN_VCC = 1 << 3, > + > + /* Override UFS_MTK_CAP_BROKEN_VCC's behavior to > + * allow vccqx upstream to enter LPM > + */ > + UFS_MTK_CAP_ALLOW_VCCQX_LPM = 1 << 5, > UFS_MTK_CAP_PMC_VIA_FASTAUTO = 1 << 6, > }; > Acked-by: Chun-Hung Wu <Chun-Hung.Wu@xxxxxxxxxxxx>