[v4,04/23] phy: qcom-qmp-ufs: Add support for configuring PHY in HS Series B mode

Message ID 20221201174328.870152-5-manivannan.sadhasivam@linaro.org
State New
Headers
Series ufs: qcom: Add HS-G4 support |

Commit Message

Manivannan Sadhasivam Dec. 1, 2022, 5:43 p.m. UTC
  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>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
  

Comments

Dmitry Baryshkov Dec. 5, 2022, 9:51 p.m. UTC | #1
On 1 December 2022 20:43:09 GMT+03:00, Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> wrote:
>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>
>Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
>---
> drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
>diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>index 516027e356f0..2d5dd336aeb2 100644
>--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>@@ -547,6 +547,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;
>@@ -580,6 +582,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)
>@@ -841,6 +844,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);

I still think that qmp_ufs_init_registers() is a way to go here , see the pcie driver.

> 	qmp_ufs_lanes_init(qmp, &cfg->tbls);
> 	qmp_ufs_pcs_init(qmp, &cfg->tbls);
> }
>@@ -1011,9 +1016,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,
> };
>
  
Manivannan Sadhasivam Dec. 6, 2022, 7:12 a.m. UTC | #2
On Tue, Dec 06, 2022 at 12:51:42AM +0300, Dmitry Baryshkov wrote:
> 
> 
> On 1 December 2022 20:43:09 GMT+03:00, Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> wrote:
> >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>
> >Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> >---
> > drivers/phy/qualcomm/phy-qcom-qmp-ufs.c | 15 +++++++++++++++
> > 1 file changed, 15 insertions(+)
> >
> >diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> >index 516027e356f0..2d5dd336aeb2 100644
> >--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> >+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> >@@ -547,6 +547,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;
> >@@ -580,6 +582,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)
> >@@ -841,6 +844,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);
> 
> I still think that qmp_ufs_init_registers() is a way to go here , see the pcie driver.
> 

I did use qmp_ufs_init_registers() as a wrapper. Only difference here is that
there is one more level of abstraction which looks cleaner to me.

Thanks,
Mani

> > 	qmp_ufs_lanes_init(qmp, &cfg->tbls);
> > 	qmp_ufs_pcs_init(qmp, &cfg->tbls);
> > }
> >@@ -1011,9 +1016,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,
> > };
> > 
> 
> -- 
> With best wishes
> Dmitry
  

Patch

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
index 516027e356f0..2d5dd336aeb2 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
@@ -547,6 +547,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;
@@ -580,6 +582,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)
@@ -841,6 +844,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);
 }
@@ -1011,9 +1016,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,
 };