phy: qcom-qmp-ufs: Add support for configuring PHY in HS Series B mode
authorManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Sat, 14 Jan 2023 07:10:01 +0000 (12:40 +0530)
committerVinod Koul <vkoul@kernel.org>
Tue, 17 Jan 2023 06:24:56 +0000 (11:54 +0530)
Add separate tables_hs_b instance to allow the PHY driver to configure the
PHY in HS Series B mode. The individual SoC configs need to supply the
serdes register setting in tables_hs_b and the UFS driver can request the
Series B mode by calling phy_set_mode() with mode set to PHY_MODE_UFS_HS_B.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Tested-by: Andrew Halaney <ahalaney@redhat.com> # Qdrive3/sa8540p-ride
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Link: https://lore.kernel.org/r/20230114071009.88102-5-manivannan.sadhasivam@linaro.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/phy/qualcomm/phy-qcom-qmp-ufs.c

index 90d644f..91285dd 100644 (file)
@@ -552,6 +552,8 @@ struct qmp_phy_cfg {
 
        /* Main init sequence for PHY blocks - serdes, tx, rx, pcs */
        const struct qmp_phy_cfg_tbls tbls;
+       /* Additional sequence for HS Series B */
+       const struct qmp_phy_cfg_tbls tbls_hs_b;
 
        /* clock ids to be requested */
        const char * const *clk_list;
@@ -585,6 +587,7 @@ struct qmp_ufs {
        struct reset_control *ufs_reset;
 
        struct phy *phy;
+       u32 mode;
 };
 
 static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
@@ -848,6 +851,8 @@ static void qmp_ufs_pcs_init(struct qmp_ufs *qmp, const struct qmp_phy_cfg_tbls
 static void qmp_ufs_init_registers(struct qmp_ufs *qmp, const struct qmp_phy_cfg *cfg)
 {
        qmp_ufs_serdes_init(qmp, &cfg->tbls);
+       if (qmp->mode == PHY_MODE_UFS_HS_B)
+               qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_b);
        qmp_ufs_lanes_init(qmp, &cfg->tbls);
        qmp_ufs_pcs_init(qmp, &cfg->tbls);
 }
@@ -1018,9 +1023,19 @@ static int qmp_ufs_disable(struct phy *phy)
        return qmp_ufs_exit(phy);
 }
 
+static int qmp_ufs_set_mode(struct phy *phy, enum phy_mode mode, int submode)
+{
+       struct qmp_ufs *qmp = phy_get_drvdata(phy);
+
+       qmp->mode = mode;
+
+       return 0;
+}
+
 static const struct phy_ops qcom_qmp_ufs_phy_ops = {
        .power_on       = qmp_ufs_enable,
        .power_off      = qmp_ufs_disable,
+       .set_mode       = qmp_ufs_set_mode,
        .owner          = THIS_MODULE,
 };