diff mbox series

[v2,6/7] phy: qualcomm: phy-qcom-qmp-ufs: Add High Speed Gear 5 support for SM8550

Message ID 1699332374-9324-7-git-send-email-cang@qti.qualcomm.com (mailing list archive)
State Not Applicable
Headers show
Series [v2,1/7] scsi: ufs: host: Rename structure ufs_dev_params to ufs_host_params | expand

Commit Message

Can Guo Nov. 7, 2023, 4:46 a.m. UTC
From: Can Guo <quic_cang@quicinc.com>

On SM8550, two sets of UFS PHY settings are provided, one set is to support
HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
settings are programming different values to different registers, mixing
the two sets and/or overwriting one set with another set is definitely not
blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
need to split the two sets into their dedicated tables, and leave only the
common settings in the .tlbs. To have the PHY programmed with the correct
set of PHY settings, the submode passed to PHY driver must be either HS-G4
or HS-G5.

Signed-off-by: Can Guo <quic_cang@quicinc.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
 drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
 .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
 drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
 4 files changed, 115 insertions(+), 13 deletions(-)

Comments

Dmitry Baryshkov Nov. 7, 2023, 1:18 p.m. UTC | #1
On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
>
> From: Can Guo <quic_cang@quicinc.com>
>
> On SM8550, two sets of UFS PHY settings are provided, one set is to support
> HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
> settings are programming different values to different registers, mixing
> the two sets and/or overwriting one set with another set is definitely not
> blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
> need to split the two sets into their dedicated tables, and leave only the
> common settings in the .tlbs. To have the PHY programmed with the correct
> set of PHY settings, the submode passed to PHY driver must be either HS-G4
> or HS-G5.
>
> Signed-off-by: Can Guo <quic_cang@quicinc.com>
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
>  drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
>  .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
>  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
>  4 files changed, 115 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> index c23d5e4..e563af5 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> @@ -18,6 +18,7 @@
>  #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
>  #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
>  #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
> +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
>  #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
>  #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
>  #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
> @@ -27,5 +28,6 @@
>  #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
>  #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
>  #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
> +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
>
>  #endif
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> index f420f8f..ef392ce 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> @@ -56,6 +56,8 @@
>  #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
>  #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
>  #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
> +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
> +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
>  #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
>  #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
>  #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> index 15bcb4b..48f31c8 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> @@ -10,10 +10,20 @@
>  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
>  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
>  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
> +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
> +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
>
>  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
>  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
> +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
> +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
> +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
> +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
> +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
> +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
>  #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
> +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
> +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
>  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
>  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
>  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
> @@ -25,6 +35,8 @@
>  #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
>  #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
>  #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
> +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
>  #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
> +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
>
>  #endif
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> index 3927eba..e0a01497 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
>         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
>         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
>         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> +
>         QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
>         QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
>         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
>         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
>         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
>         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
> +};
> +
> +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
> +};
> +
> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
>         QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),

Aside from moving these registers to the HS_G4 table, you are also
changing these registers. It makes me think that there was an error in
the original programming sequence.
If that is correct, could you please split the patch into two pieces:
- Fix programming sequence (add proper Fixes tags)
- Split G4 and G5 tables.

> +
> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),

I see all the MODE1 registers being only present in G4 and G5 tables.
Should they be programmed for the modes lower than G4?

> +};
> +
> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_serdes[] = {
> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x1f),
> +
> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x1b),
> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x1c),
> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
>  };
>
>  static const struct qmp_phy_init_tbl sm8550_ufsphy_tx[] = {
> -       QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_1, 0x05),
> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05),
>         QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
>  };
>
> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_tx[] = {
> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_FR_DCC_CTRL, 0x4c),
> +};
> +
>  static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
> -       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2, 0x0c),
> -       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x0f),
> -       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
>
>         QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xc2),
>         QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xc2),
> @@ -690,14 +709,46 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
>         QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
>  };
>
> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_rx[] = {
> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
> +};
> +
> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_rx[] = {
> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4, 0x0c),
> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4, 0x04),
> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS, 0x07),
> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3, 0x0e),
> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4, 0x02),
> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x1c),
> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x06),
> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x08),
> +
> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B3, 0xb9),
> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B4, 0x4f),
> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B6, 0xff),
> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL, 0x30),
> +};
> +
>  static const struct qmp_phy_init_tbl sm8550_ufsphy_pcs[] = {
>         QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x69),
>         QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
>         QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
> -       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
>         QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
>  };
>
> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_pcs[] = {
> +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
> +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
> +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
> +};
> +
> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_pcs[] = {
> +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
> +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4f),
> +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e),
> +};
> +
>  struct qmp_ufs_offsets {
>         u16 serdes;
>         u16 pcs;
> @@ -731,6 +782,8 @@ struct qmp_phy_cfg {
>         const struct qmp_phy_cfg_tbls tbls_hs_b;
>         /* Additional sequence for HS G4 */
>         const struct qmp_phy_cfg_tbls tbls_hs_g4;
> +       /* Additional sequence for HS G4 */
> +       const struct qmp_phy_cfg_tbls tbls_hs_g5;
>
>         /* clock ids to be requested */
>         const char * const *clk_list;
> @@ -1157,6 +1210,28 @@ static const struct qmp_phy_cfg sm8550_ufsphy_cfg = {
>                 .pcs            = sm8550_ufsphy_pcs,
>                 .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_pcs),
>         },
> +       .tbls_hs_b = {
> +               .serdes         = sm8550_ufsphy_hs_b_serdes,
> +               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes),
> +       },
> +       .tbls_hs_g4 = {
> +               .serdes         = sm8550_ufsphy_g4_serdes,
> +               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_g4_serdes),
> +               .tx             = sm8550_ufsphy_g4_tx,
> +               .tx_num         = ARRAY_SIZE(sm8550_ufsphy_g4_tx),
> +               .rx             = sm8550_ufsphy_g4_rx,
> +               .rx_num         = ARRAY_SIZE(sm8550_ufsphy_g4_rx),
> +               .pcs            = sm8550_ufsphy_g4_pcs,
> +               .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_g4_pcs),
> +       },
> +       .tbls_hs_g5 = {
> +               .serdes         = sm8550_ufsphy_g5_serdes,
> +               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_g5_serdes),
> +               .rx             = sm8550_ufsphy_g5_rx,
> +               .rx_num         = ARRAY_SIZE(sm8550_ufsphy_g5_rx),
> +               .pcs            = sm8550_ufsphy_g5_pcs,
> +               .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_g5_pcs),
> +       },
>         .clk_list               = sdm845_ufs_phy_clk_l,
>         .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
>         .vreg_list              = qmp_phy_vreg_l,
> @@ -1222,14 +1297,25 @@ 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->submode == UFS_HS_G4)
> +               qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
> +       else if (qmp->submode == UFS_HS_G5)
> +               qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
> +
>         if (qmp->mode == PHY_MODE_UFS_HS_B)
>                 qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_b);
> +
>         qmp_ufs_lanes_init(qmp, &cfg->tbls);
>         if (qmp->submode == UFS_HS_G4)
>                 qmp_ufs_lanes_init(qmp, &cfg->tbls_hs_g4);
> +       else if (qmp->submode == UFS_HS_G5)
> +               qmp_ufs_lanes_init(qmp, &cfg->tbls_hs_g5);
> +
>         qmp_ufs_pcs_init(qmp, &cfg->tbls);
>         if (qmp->submode == UFS_HS_G4)
>                 qmp_ufs_pcs_init(qmp, &cfg->tbls_hs_g4);
> +       else if (qmp->submode == UFS_HS_G5)
> +               qmp_ufs_pcs_init(qmp, &cfg->tbls_hs_g5);
>  }
>
>  static int qmp_ufs_com_init(struct qmp_ufs *qmp)
> --
> 2.7.4
>
>
Manivannan Sadhasivam Nov. 8, 2023, 5:49 a.m. UTC | #2
On Tue, Nov 07, 2023 at 03:18:09PM +0200, Dmitry Baryshkov wrote:
> On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
> >
> > From: Can Guo <quic_cang@quicinc.com>
> >
> > On SM8550, two sets of UFS PHY settings are provided, one set is to support
> > HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
> > settings are programming different values to different registers, mixing
> > the two sets and/or overwriting one set with another set is definitely not
> > blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
> > need to split the two sets into their dedicated tables, and leave only the
> > common settings in the .tlbs. To have the PHY programmed with the correct
> > set of PHY settings, the submode passed to PHY driver must be either HS-G4
> > or HS-G5.
> >

You should also mention that this issue is also present in G4 supported targets.
And a note that it will get fixed later.

> > Signed-off-by: Can Guo <quic_cang@quicinc.com>
> > ---
> >  drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
> >  drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
> >  .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
> >  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
> >  4 files changed, 115 insertions(+), 13 deletions(-)
> >
> > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > index c23d5e4..e563af5 100644
> > --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > @@ -18,6 +18,7 @@
> >  #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
> >  #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
> >  #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
> > +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
> >  #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
> >  #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
> >  #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
> > @@ -27,5 +28,6 @@
> >  #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
> >  #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
> >  #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
> > +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
> >
> >  #endif
> > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > index f420f8f..ef392ce 100644
> > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > @@ -56,6 +56,8 @@
> >  #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
> >  #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
> >  #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
> > +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
> > +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
> >  #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
> >  #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
> >  #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
> > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > index 15bcb4b..48f31c8 100644
> > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > @@ -10,10 +10,20 @@
> >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
> >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
> >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
> > +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
> > +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
> >
> >  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
> >  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
> > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
> > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
> > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
> > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
> > +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
> > +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
> >  #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
> > +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
> > +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
> >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
> >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
> >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
> > @@ -25,6 +35,8 @@
> >  #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
> >  #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
> >  #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
> > +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
> >  #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
> > +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
> >
> >  #endif
> > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > index 3927eba..e0a01497 100644
> > --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
> >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
> >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
> >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
> > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > +
> >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
> >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
> > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
> >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
> > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
> > +};
> > +
> > +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
> > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
> > +};
> > +
> > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
> > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
> > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
> 
> Aside from moving these registers to the HS_G4 table, you are also
> changing these registers. It makes me think that there was an error in
> the original programming sequence.
> If that is correct, could you please split the patch into two pieces:
> - Fix programming sequence (add proper Fixes tags)
> - Split G4 and G5 tables.

Ack

> 
> > +
> > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
> > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
> > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
> > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
> > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
> > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
> 
> I see all the MODE1 registers being only present in G4 and G5 tables.
> Should they be programmed for the modes lower than G4?
> 

We use G4 table for all the modes <= G4.

> > +};
> > +
> > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_serdes[] = {
> > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x1f),
> > +
> > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x1b),
> > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x1c),
> > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
> >  };
> >
> >  static const struct qmp_phy_init_tbl sm8550_ufsphy_tx[] = {
> > -       QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_1, 0x05),
> > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05),
> >         QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
> >  };
> >
> > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_tx[] = {
> > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_FR_DCC_CTRL, 0x4c),
> > +};
> > +
> >  static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
> > -       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2, 0x0c),
> > -       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x0f),
> > -       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
> > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
> >
> >         QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xc2),
> >         QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xc2),
> > @@ -690,14 +709,46 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
> >         QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
> >  };
> >
> > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_rx[] = {
> > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
> > +};
> > +
> > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_rx[] = {
> > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4, 0x0c),
> > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4, 0x04),
> > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
> > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS, 0x07),
> > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3, 0x0e),
> > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4, 0x02),
> > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x1c),
> > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x06),
> > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x08),
> > +
> > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B3, 0xb9),
> > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B4, 0x4f),
> > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B6, 0xff),
> > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL, 0x30),
> > +};
> > +
> >  static const struct qmp_phy_init_tbl sm8550_ufsphy_pcs[] = {
> >         QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x69),
> >         QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
> >         QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
> > -       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
> >         QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
> >  };
> >
> > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_pcs[] = {
> > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
> > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
> > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
> > +};
> > +
> > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_pcs[] = {
> > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
> > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4f),
> > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e),
> > +};
> > +
> >  struct qmp_ufs_offsets {
> >         u16 serdes;
> >         u16 pcs;
> > @@ -731,6 +782,8 @@ struct qmp_phy_cfg {
> >         const struct qmp_phy_cfg_tbls tbls_hs_b;
> >         /* Additional sequence for HS G4 */
> >         const struct qmp_phy_cfg_tbls tbls_hs_g4;
> > +       /* Additional sequence for HS G4 */

HS G5

> > +       const struct qmp_phy_cfg_tbls tbls_hs_g5;
> >
> >         /* clock ids to be requested */
> >         const char * const *clk_list;
> > @@ -1157,6 +1210,28 @@ static const struct qmp_phy_cfg sm8550_ufsphy_cfg = {
> >                 .pcs            = sm8550_ufsphy_pcs,
> >                 .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_pcs),
> >         },
> > +       .tbls_hs_b = {
> > +               .serdes         = sm8550_ufsphy_hs_b_serdes,
> > +               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes),
> > +       },
> > +       .tbls_hs_g4 = {
> > +               .serdes         = sm8550_ufsphy_g4_serdes,
> > +               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_g4_serdes),
> > +               .tx             = sm8550_ufsphy_g4_tx,
> > +               .tx_num         = ARRAY_SIZE(sm8550_ufsphy_g4_tx),
> > +               .rx             = sm8550_ufsphy_g4_rx,
> > +               .rx_num         = ARRAY_SIZE(sm8550_ufsphy_g4_rx),
> > +               .pcs            = sm8550_ufsphy_g4_pcs,
> > +               .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_g4_pcs),
> > +       },
> > +       .tbls_hs_g5 = {
> > +               .serdes         = sm8550_ufsphy_g5_serdes,
> > +               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_g5_serdes),
> > +               .rx             = sm8550_ufsphy_g5_rx,
> > +               .rx_num         = ARRAY_SIZE(sm8550_ufsphy_g5_rx),
> > +               .pcs            = sm8550_ufsphy_g5_pcs,
> > +               .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_g5_pcs),
> > +       },
> >         .clk_list               = sdm845_ufs_phy_clk_l,
> >         .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
> >         .vreg_list              = qmp_phy_vreg_l,
> > @@ -1222,14 +1297,25 @@ 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->submode == UFS_HS_G4)
> > +               qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
> > +       else if (qmp->submode == UFS_HS_G5)
> > +               qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
> > +

Should we program submode sequence after HS_B?

- Mani
Dmitry Baryshkov Nov. 8, 2023, 6:56 a.m. UTC | #3
On Wed, 8 Nov 2023 at 07:49, Manivannan Sadhasivam <mani@kernel.org> wrote:
>
> On Tue, Nov 07, 2023 at 03:18:09PM +0200, Dmitry Baryshkov wrote:
> > On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
> > >
> > > From: Can Guo <quic_cang@quicinc.com>
> > >
> > > On SM8550, two sets of UFS PHY settings are provided, one set is to support
> > > HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
> > > settings are programming different values to different registers, mixing
> > > the two sets and/or overwriting one set with another set is definitely not
> > > blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
> > > need to split the two sets into their dedicated tables, and leave only the
> > > common settings in the .tlbs. To have the PHY programmed with the correct
> > > set of PHY settings, the submode passed to PHY driver must be either HS-G4
> > > or HS-G5.
> > >
>
> You should also mention that this issue is also present in G4 supported targets.
> And a note that it will get fixed later.
>
> > > Signed-off-by: Can Guo <quic_cang@quicinc.com>
> > > ---
> > >  drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
> > >  drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
> > >  .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
> > >  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
> > >  4 files changed, 115 insertions(+), 13 deletions(-)
> > >
> > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > index c23d5e4..e563af5 100644
> > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > @@ -18,6 +18,7 @@
> > >  #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
> > >  #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
> > >  #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
> > > +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
> > >  #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
> > >  #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
> > >  #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
> > > @@ -27,5 +28,6 @@
> > >  #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
> > >  #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
> > >  #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
> > > +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
> > >
> > >  #endif
> > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > index f420f8f..ef392ce 100644
> > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > @@ -56,6 +56,8 @@
> > >  #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
> > >  #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
> > >  #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
> > > +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
> > > +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
> > >  #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
> > >  #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
> > >  #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
> > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > index 15bcb4b..48f31c8 100644
> > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > @@ -10,10 +10,20 @@
> > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
> > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
> > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
> > > +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
> > > +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
> > >
> > >  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
> > >  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
> > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
> > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
> > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
> > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
> > > +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
> > > +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
> > >  #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
> > > +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
> > > +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
> > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
> > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
> > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
> > > @@ -25,6 +35,8 @@
> > >  #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
> > >  #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
> > >  #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
> > > +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
> > >  #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
> > > +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
> > >
> > >  #endif
> > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > index 3927eba..e0a01497 100644
> > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
> > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
> > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
> > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
> > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > +
> > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
> > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
> > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
> > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
> > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
> > > +};
> > > +
> > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
> > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
> > > +};
> > > +
> > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
> > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
> > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
> >
> > Aside from moving these registers to the HS_G4 table, you are also
> > changing these registers. It makes me think that there was an error in
> > the original programming sequence.
> > If that is correct, could you please split the patch into two pieces:
> > - Fix programming sequence (add proper Fixes tags)
> > - Split G4 and G5 tables.
>
> Ack
>
> >
> > > +
> > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
> > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
> > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
> > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
> > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
> > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
> >
> > I see all the MODE1 registers being only present in G4 and G5 tables.
> > Should they be programmed for the modes lower than G4?
> >
>
> We use G4 table for all the modes <= G4.

Could you please point me how it's handled?
In the patch I see just:

       if (qmp->submode == UFS_HS_G4)
               qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
       else if (qmp->submode == UFS_HS_G5)
               qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);

Which looks like two special cases (HS_G4 and HS_G5) and nothing for
anything else.

>
> > > +};
> > > +
> > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_serdes[] = {
> > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x1f),
> > > +
> > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x1b),
> > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x1c),
> > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
> > >  };
> > >
> > >  static const struct qmp_phy_init_tbl sm8550_ufsphy_tx[] = {
> > > -       QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_1, 0x05),
> > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05),
> > >         QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
> > >  };
> > >
> > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_tx[] = {
> > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_FR_DCC_CTRL, 0x4c),
> > > +};
> > > +
> > >  static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
> > > -       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2, 0x0c),
> > > -       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x0f),
> > > -       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
> > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
> > >
> > >         QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xc2),
> > >         QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xc2),
> > > @@ -690,14 +709,46 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
> > >         QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
> > >  };
> > >
> > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_rx[] = {
> > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
> > > +};
> > > +
> > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_rx[] = {
> > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4, 0x0c),
> > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4, 0x04),
> > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
> > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS, 0x07),
> > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3, 0x0e),
> > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4, 0x02),
> > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x1c),
> > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x06),
> > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x08),
> > > +
> > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B3, 0xb9),
> > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B4, 0x4f),
> > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B6, 0xff),
> > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL, 0x30),
> > > +};
> > > +
> > >  static const struct qmp_phy_init_tbl sm8550_ufsphy_pcs[] = {
> > >         QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x69),
> > >         QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
> > >         QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
> > > -       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
> > >         QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
> > >  };
> > >
> > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_pcs[] = {
> > > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
> > > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
> > > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
> > > +};
> > > +
> > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_pcs[] = {
> > > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
> > > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4f),
> > > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e),
> > > +};
> > > +
> > >  struct qmp_ufs_offsets {
> > >         u16 serdes;
> > >         u16 pcs;
> > > @@ -731,6 +782,8 @@ struct qmp_phy_cfg {
> > >         const struct qmp_phy_cfg_tbls tbls_hs_b;
> > >         /* Additional sequence for HS G4 */
> > >         const struct qmp_phy_cfg_tbls tbls_hs_g4;
> > > +       /* Additional sequence for HS G4 */
>
> HS G5
>
> > > +       const struct qmp_phy_cfg_tbls tbls_hs_g5;
> > >
> > >         /* clock ids to be requested */
> > >         const char * const *clk_list;
> > > @@ -1157,6 +1210,28 @@ static const struct qmp_phy_cfg sm8550_ufsphy_cfg = {
> > >                 .pcs            = sm8550_ufsphy_pcs,
> > >                 .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_pcs),
> > >         },
> > > +       .tbls_hs_b = {
> > > +               .serdes         = sm8550_ufsphy_hs_b_serdes,
> > > +               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes),
> > > +       },
> > > +       .tbls_hs_g4 = {
> > > +               .serdes         = sm8550_ufsphy_g4_serdes,
> > > +               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_g4_serdes),
> > > +               .tx             = sm8550_ufsphy_g4_tx,
> > > +               .tx_num         = ARRAY_SIZE(sm8550_ufsphy_g4_tx),
> > > +               .rx             = sm8550_ufsphy_g4_rx,
> > > +               .rx_num         = ARRAY_SIZE(sm8550_ufsphy_g4_rx),
> > > +               .pcs            = sm8550_ufsphy_g4_pcs,
> > > +               .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_g4_pcs),
> > > +       },
> > > +       .tbls_hs_g5 = {
> > > +               .serdes         = sm8550_ufsphy_g5_serdes,
> > > +               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_g5_serdes),
> > > +               .rx             = sm8550_ufsphy_g5_rx,
> > > +               .rx_num         = ARRAY_SIZE(sm8550_ufsphy_g5_rx),
> > > +               .pcs            = sm8550_ufsphy_g5_pcs,
> > > +               .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_g5_pcs),
> > > +       },
> > >         .clk_list               = sdm845_ufs_phy_clk_l,
> > >         .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
> > >         .vreg_list              = qmp_phy_vreg_l,
> > > @@ -1222,14 +1297,25 @@ 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->submode == UFS_HS_G4)
> > > +               qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
> > > +       else if (qmp->submode == UFS_HS_G5)
> > > +               qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
> > > +
>
> Should we program submode sequence after HS_B?
>
> - Mani
>
> --
> மணிவண்ணன் சதாசிவம்



--
With best wishes
Dmitry
Can Guo Nov. 8, 2023, 9:02 a.m. UTC | #4
Hi Dmitry,

On 11/7/2023 9:18 PM, Dmitry Baryshkov wrote:
> On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
>>
>> From: Can Guo <quic_cang@quicinc.com>
>>
>> On SM8550, two sets of UFS PHY settings are provided, one set is to support
>> HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
>> settings are programming different values to different registers, mixing
>> the two sets and/or overwriting one set with another set is definitely not
>> blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
>> need to split the two sets into their dedicated tables, and leave only the
>> common settings in the .tlbs. To have the PHY programmed with the correct
>> set of PHY settings, the submode passed to PHY driver must be either HS-G4
>> or HS-G5.
>>
>> Signed-off-by: Can Guo <quic_cang@quicinc.com>
>> ---
>>   drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
>>   drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
>>   .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
>>   drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
>>   4 files changed, 115 insertions(+), 13 deletions(-)
>>
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
>> index c23d5e4..e563af5 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
>> @@ -18,6 +18,7 @@
>>   #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
>>   #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
>>   #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
>> +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
>>   #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
>>   #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
>>   #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
>> @@ -27,5 +28,6 @@
>>   #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
>>   #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
>>   #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
>> +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
>>
>>   #endif
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
>> index f420f8f..ef392ce 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
>> @@ -56,6 +56,8 @@
>>   #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
>>   #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
>>   #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
>> +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
>> +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
>>   #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
>>   #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
>>   #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
>> index 15bcb4b..48f31c8 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
>> @@ -10,10 +10,20 @@
>>   #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
>>   #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
>>   #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
>> +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
>> +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
>>
>>   #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
>>   #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
>> +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
>> +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
>> +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
>> +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
>> +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
>> +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
>>   #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
>> +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
>> +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
>>   #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
>>   #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
>>   #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
>> @@ -25,6 +35,8 @@
>>   #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
>>   #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
>>   #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
>> +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
>>   #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
>> +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
>>
>>   #endif
>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>> index 3927eba..e0a01497 100644
>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>> @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
>> +
>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
>> +};
>> +
>> +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
>> +};
>> +
>> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
> 
> Aside from moving these registers to the HS_G4 table, you are also
> changing these registers. It makes me think that there was an error in
> the original programming sequence.
> If that is correct, could you please split the patch into two pieces:
> - Fix programming sequence (add proper Fixes tags)
> - Split G4 and G5 tables.

You are correct, I don't know where the original values are from, but 
they look like a mixing of HS-G4 settings and HS-G5 settings to me, 
because I see some values are only supposed to be there for HS-G5, 
whereas the same MODE0 registers are programmed twice, I guess they 
should be MODE1 registers which are only required for HS-G4.

> 
>> +
>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
> 
> I see all the MODE1 registers being only present in G4 and G5 tables.
> Should they be programmed for the modes lower than G4?
> 

As mentioned in the commit msg, on SM8550, only two sets of UFS PHY 
settings are provided, one set is to support HS-G5, another set is to 
support HS-G4.

Although HS-G5 set of PHY settings is backward comptiable and able to 
support all lower gears, UFS driver should make sure HS-G5 set of PHY 
settings are only used when UFS device really supports HS-G5.

For UFS devices which can only support HS-G4 or lower gears, UFS driver 
would use the HS-G4 set of PHY settings, in order to save power.

Thanks,
Can Guo.
Can Guo Nov. 8, 2023, 9:19 a.m. UTC | #5
Hi Mani,

On 11/8/2023 1:49 PM, Manivannan Sadhasivam wrote:
> On Tue, Nov 07, 2023 at 03:18:09PM +0200, Dmitry Baryshkov wrote:
>> On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
>>>
>>> From: Can Guo <quic_cang@quicinc.com>
>>>
>>> On SM8550, two sets of UFS PHY settings are provided, one set is to support
>>> HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
>>> settings are programming different values to different registers, mixing
>>> the two sets and/or overwriting one set with another set is definitely not
>>> blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
>>> need to split the two sets into their dedicated tables, and leave only the
>>> common settings in the .tlbs. To have the PHY programmed with the correct
>>> set of PHY settings, the submode passed to PHY driver must be either HS-G4
>>> or HS-G5.
>>>
> 
> You should also mention that this issue is also present in G4 supported targets.
> And a note that it will get fixed later.

Will this info upset more people? How about I mention this in the cover 
letter?

> 
>>> Signed-off-by: Can Guo <quic_cang@quicinc.com>
>>> ---
>>>   drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
>>>   drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
>>>   .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
>>>   drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
>>>   4 files changed, 115 insertions(+), 13 deletions(-)
>>>
>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
>>> index c23d5e4..e563af5 100644
>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
>>> @@ -18,6 +18,7 @@
>>>   #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
>>>   #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
>>>   #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
>>> +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
>>>   #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
>>>   #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
>>>   #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
>>> @@ -27,5 +28,6 @@
>>>   #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
>>>   #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
>>>   #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
>>> +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
>>>
>>>   #endif
>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
>>> index f420f8f..ef392ce 100644
>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
>>> @@ -56,6 +56,8 @@
>>>   #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
>>>   #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
>>>   #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
>>> +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
>>> +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
>>>   #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
>>>   #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
>>>   #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
>>> index 15bcb4b..48f31c8 100644
>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
>>> @@ -10,10 +10,20 @@
>>>   #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
>>>   #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
>>>   #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
>>> +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
>>> +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
>>>
>>>   #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
>>>   #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
>>> +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
>>> +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
>>> +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
>>> +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
>>> +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
>>> +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
>>>   #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
>>> +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
>>> +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
>>>   #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
>>>   #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
>>>   #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
>>> @@ -25,6 +35,8 @@
>>>   #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
>>>   #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
>>>   #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
>>> +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
>>>   #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
>>> +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
>>>
>>>   #endif
>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>>> index 3927eba..e0a01497 100644
>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>>> @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
>>> +
>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
>>> +};
>>> +
>>> +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
>>> +};
>>> +
>>> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
>>
>> Aside from moving these registers to the HS_G4 table, you are also
>> changing these registers. It makes me think that there was an error in
>> the original programming sequence.
>> If that is correct, could you please split the patch into two pieces:
>> - Fix programming sequence (add proper Fixes tags)
>> - Split G4 and G5 tables.
> 
> Ack
> 
>>
>>> +
>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
>>
>> I see all the MODE1 registers being only present in G4 and G5 tables.
>> Should they be programmed for the modes lower than G4?
>>
> 
> We use G4 table for all the modes <= G4.
> 
>>> +};
>>> +
>>> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_serdes[] = {
>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x1f),
>>> +
>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x1b),
>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x1c),
>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
>>>   };
>>>
>>>   static const struct qmp_phy_init_tbl sm8550_ufsphy_tx[] = {
>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_1, 0x05),
>>> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05),
>>>          QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
>>>   };
>>>
>>> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_tx[] = {
>>> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_FR_DCC_CTRL, 0x4c),
>>> +};
>>> +
>>>   static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
>>> -       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2, 0x0c),
>>> -       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x0f),
>>> -       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
>>> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
>>>
>>>          QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xc2),
>>>          QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xc2),
>>> @@ -690,14 +709,46 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
>>>          QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
>>>   };
>>>
>>> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_rx[] = {
>>> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
>>> +};
>>> +
>>> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_rx[] = {
>>> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4, 0x0c),
>>> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4, 0x04),
>>> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
>>> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS, 0x07),
>>> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3, 0x0e),
>>> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4, 0x02),
>>> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x1c),
>>> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x06),
>>> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x08),
>>> +
>>> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B3, 0xb9),
>>> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B4, 0x4f),
>>> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B6, 0xff),
>>> +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL, 0x30),
>>> +};
>>> +
>>>   static const struct qmp_phy_init_tbl sm8550_ufsphy_pcs[] = {
>>>          QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x69),
>>>          QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
>>>          QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
>>> -       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
>>>          QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
>>>   };
>>>
>>> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_pcs[] = {
>>> +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
>>> +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
>>> +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
>>> +};
>>> +
>>> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_pcs[] = {
>>> +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
>>> +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4f),
>>> +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e),
>>> +};
>>> +
>>>   struct qmp_ufs_offsets {
>>>          u16 serdes;
>>>          u16 pcs;
>>> @@ -731,6 +782,8 @@ struct qmp_phy_cfg {
>>>          const struct qmp_phy_cfg_tbls tbls_hs_b;
>>>          /* Additional sequence for HS G4 */
>>>          const struct qmp_phy_cfg_tbls tbls_hs_g4;
>>> +       /* Additional sequence for HS G4 */
> 
> HS G5

Sure

> 
>>> +       const struct qmp_phy_cfg_tbls tbls_hs_g5;
>>>
>>>          /* clock ids to be requested */
>>>          const char * const *clk_list;
>>> @@ -1157,6 +1210,28 @@ static const struct qmp_phy_cfg sm8550_ufsphy_cfg = {
>>>                  .pcs            = sm8550_ufsphy_pcs,
>>>                  .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_pcs),
>>>          },
>>> +       .tbls_hs_b = {
>>> +               .serdes         = sm8550_ufsphy_hs_b_serdes,
>>> +               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes),
>>> +       },
>>> +       .tbls_hs_g4 = {
>>> +               .serdes         = sm8550_ufsphy_g4_serdes,
>>> +               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_g4_serdes),
>>> +               .tx             = sm8550_ufsphy_g4_tx,
>>> +               .tx_num         = ARRAY_SIZE(sm8550_ufsphy_g4_tx),
>>> +               .rx             = sm8550_ufsphy_g4_rx,
>>> +               .rx_num         = ARRAY_SIZE(sm8550_ufsphy_g4_rx),
>>> +               .pcs            = sm8550_ufsphy_g4_pcs,
>>> +               .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_g4_pcs),
>>> +       },
>>> +       .tbls_hs_g5 = {
>>> +               .serdes         = sm8550_ufsphy_g5_serdes,
>>> +               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_g5_serdes),
>>> +               .rx             = sm8550_ufsphy_g5_rx,
>>> +               .rx_num         = ARRAY_SIZE(sm8550_ufsphy_g5_rx),
>>> +               .pcs            = sm8550_ufsphy_g5_pcs,
>>> +               .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_g5_pcs),
>>> +       },
>>>          .clk_list               = sdm845_ufs_phy_clk_l,
>>>          .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
>>>          .vreg_list              = qmp_phy_vreg_l,
>>> @@ -1222,14 +1297,25 @@ 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->submode == UFS_HS_G4)
>>> +               qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
>>> +       else if (qmp->submode == UFS_HS_G5)
>>> +               qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
>>> +
> 
> Should we program submode sequence after HS_B?
> 
> - Mani
> 
As the UFS PHY HW programming doc mentions, order of these writes is not 
important, so long as they are programmed correctly before release S/W 
reset, then it is fine.

Thanks,
Can Guo.
Manivannan Sadhasivam Nov. 9, 2023, 3:24 a.m. UTC | #6
On Wed, Nov 08, 2023 at 08:56:16AM +0200, Dmitry Baryshkov wrote:
> On Wed, 8 Nov 2023 at 07:49, Manivannan Sadhasivam <mani@kernel.org> wrote:
> >
> > On Tue, Nov 07, 2023 at 03:18:09PM +0200, Dmitry Baryshkov wrote:
> > > On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
> > > >
> > > > From: Can Guo <quic_cang@quicinc.com>
> > > >
> > > > On SM8550, two sets of UFS PHY settings are provided, one set is to support
> > > > HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
> > > > settings are programming different values to different registers, mixing
> > > > the two sets and/or overwriting one set with another set is definitely not
> > > > blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
> > > > need to split the two sets into their dedicated tables, and leave only the
> > > > common settings in the .tlbs. To have the PHY programmed with the correct
> > > > set of PHY settings, the submode passed to PHY driver must be either HS-G4
> > > > or HS-G5.
> > > >
> >
> > You should also mention that this issue is also present in G4 supported targets.
> > And a note that it will get fixed later.
> >
> > > > Signed-off-by: Can Guo <quic_cang@quicinc.com>
> > > > ---
> > > >  drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
> > > >  drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
> > > >  .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
> > > >  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
> > > >  4 files changed, 115 insertions(+), 13 deletions(-)
> > > >
> > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > index c23d5e4..e563af5 100644
> > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > @@ -18,6 +18,7 @@
> > > >  #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
> > > >  #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
> > > >  #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
> > > > +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
> > > >  #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
> > > >  #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
> > > >  #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
> > > > @@ -27,5 +28,6 @@
> > > >  #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
> > > >  #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
> > > >  #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
> > > > +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
> > > >
> > > >  #endif
> > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > index f420f8f..ef392ce 100644
> > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > @@ -56,6 +56,8 @@
> > > >  #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
> > > >  #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
> > > >  #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
> > > > +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
> > > > +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
> > > >  #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
> > > >  #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
> > > >  #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
> > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > index 15bcb4b..48f31c8 100644
> > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > @@ -10,10 +10,20 @@
> > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
> > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
> > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
> > > > +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
> > > > +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
> > > >
> > > >  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
> > > >  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
> > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
> > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
> > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
> > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
> > > > +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
> > > > +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
> > > >  #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
> > > > +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
> > > > +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
> > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
> > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
> > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
> > > > @@ -25,6 +35,8 @@
> > > >  #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
> > > >  #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
> > > >  #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
> > > > +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
> > > >  #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
> > > > +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
> > > >
> > > >  #endif
> > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > index 3927eba..e0a01497 100644
> > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
> > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
> > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
> > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > > +
> > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
> > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
> > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
> > > > +};
> > > > +
> > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
> > > > +};
> > > > +
> > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
> > >
> > > Aside from moving these registers to the HS_G4 table, you are also
> > > changing these registers. It makes me think that there was an error in
> > > the original programming sequence.
> > > If that is correct, could you please split the patch into two pieces:
> > > - Fix programming sequence (add proper Fixes tags)
> > > - Split G4 and G5 tables.
> >
> > Ack
> >
> > >
> > > > +
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
> > >
> > > I see all the MODE1 registers being only present in G4 and G5 tables.
> > > Should they be programmed for the modes lower than G4?
> > >
> >
> > We use G4 table for all the modes <= G4.
> 
> Could you please point me how it's handled?
> In the patch I see just:
> 
>        if (qmp->submode == UFS_HS_G4)
>                qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
>        else if (qmp->submode == UFS_HS_G5)
>                qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
> 
> Which looks like two special cases (HS_G4 and HS_G5) and nothing for
> anything else.
> 

Yes, and the UFS driver passes only G4/G5. For all the gears <=G4, G4 init
sequence will be used and for G5, G5 sequence will be used.

- Mani

> >
> > > > +};
> > > > +
> > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_serdes[] = {
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x1f),
> > > > +
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x1b),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x1c),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
> > > >  };
> > > >
> > > >  static const struct qmp_phy_init_tbl sm8550_ufsphy_tx[] = {
> > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_1, 0x05),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05),
> > > >         QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
> > > >  };
> > > >
> > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_tx[] = {
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_FR_DCC_CTRL, 0x4c),
> > > > +};
> > > > +
> > > >  static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
> > > > -       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2, 0x0c),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x0f),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
> > > >
> > > >         QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xc2),
> > > >         QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xc2),
> > > > @@ -690,14 +709,46 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
> > > >         QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
> > > >  };
> > > >
> > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_rx[] = {
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
> > > > +};
> > > > +
> > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_rx[] = {
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4, 0x0c),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4, 0x04),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS, 0x07),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3, 0x0e),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4, 0x02),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x1c),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x06),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x08),
> > > > +
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B3, 0xb9),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B4, 0x4f),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B6, 0xff),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL, 0x30),
> > > > +};
> > > > +
> > > >  static const struct qmp_phy_init_tbl sm8550_ufsphy_pcs[] = {
> > > >         QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x69),
> > > >         QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
> > > >         QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
> > > > -       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
> > > >         QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
> > > >  };
> > > >
> > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_pcs[] = {
> > > > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
> > > > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
> > > > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
> > > > +};
> > > > +
> > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_pcs[] = {
> > > > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
> > > > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4f),
> > > > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e),
> > > > +};
> > > > +
> > > >  struct qmp_ufs_offsets {
> > > >         u16 serdes;
> > > >         u16 pcs;
> > > > @@ -731,6 +782,8 @@ struct qmp_phy_cfg {
> > > >         const struct qmp_phy_cfg_tbls tbls_hs_b;
> > > >         /* Additional sequence for HS G4 */
> > > >         const struct qmp_phy_cfg_tbls tbls_hs_g4;
> > > > +       /* Additional sequence for HS G4 */
> >
> > HS G5
> >
> > > > +       const struct qmp_phy_cfg_tbls tbls_hs_g5;
> > > >
> > > >         /* clock ids to be requested */
> > > >         const char * const *clk_list;
> > > > @@ -1157,6 +1210,28 @@ static const struct qmp_phy_cfg sm8550_ufsphy_cfg = {
> > > >                 .pcs            = sm8550_ufsphy_pcs,
> > > >                 .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_pcs),
> > > >         },
> > > > +       .tbls_hs_b = {
> > > > +               .serdes         = sm8550_ufsphy_hs_b_serdes,
> > > > +               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes),
> > > > +       },
> > > > +       .tbls_hs_g4 = {
> > > > +               .serdes         = sm8550_ufsphy_g4_serdes,
> > > > +               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_g4_serdes),
> > > > +               .tx             = sm8550_ufsphy_g4_tx,
> > > > +               .tx_num         = ARRAY_SIZE(sm8550_ufsphy_g4_tx),
> > > > +               .rx             = sm8550_ufsphy_g4_rx,
> > > > +               .rx_num         = ARRAY_SIZE(sm8550_ufsphy_g4_rx),
> > > > +               .pcs            = sm8550_ufsphy_g4_pcs,
> > > > +               .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_g4_pcs),
> > > > +       },
> > > > +       .tbls_hs_g5 = {
> > > > +               .serdes         = sm8550_ufsphy_g5_serdes,
> > > > +               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_g5_serdes),
> > > > +               .rx             = sm8550_ufsphy_g5_rx,
> > > > +               .rx_num         = ARRAY_SIZE(sm8550_ufsphy_g5_rx),
> > > > +               .pcs            = sm8550_ufsphy_g5_pcs,
> > > > +               .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_g5_pcs),
> > > > +       },
> > > >         .clk_list               = sdm845_ufs_phy_clk_l,
> > > >         .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
> > > >         .vreg_list              = qmp_phy_vreg_l,
> > > > @@ -1222,14 +1297,25 @@ 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->submode == UFS_HS_G4)
> > > > +               qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
> > > > +       else if (qmp->submode == UFS_HS_G5)
> > > > +               qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
> > > > +
> >
> > Should we program submode sequence after HS_B?
> >
> > - Mani
> >
> > --
> > மணிவண்ணன் சதாசிவம்
> 
> 
> 
> --
> With best wishes
> Dmitry
Manivannan Sadhasivam Nov. 9, 2023, 3:26 a.m. UTC | #7
On Wed, Nov 08, 2023 at 05:19:43PM +0800, Can Guo wrote:
> Hi Mani,
> 
> On 11/8/2023 1:49 PM, Manivannan Sadhasivam wrote:
> > On Tue, Nov 07, 2023 at 03:18:09PM +0200, Dmitry Baryshkov wrote:
> > > On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
> > > > 
> > > > From: Can Guo <quic_cang@quicinc.com>
> > > > 
> > > > On SM8550, two sets of UFS PHY settings are provided, one set is to support
> > > > HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
> > > > settings are programming different values to different registers, mixing
> > > > the two sets and/or overwriting one set with another set is definitely not
> > > > blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
> > > > need to split the two sets into their dedicated tables, and leave only the
> > > > common settings in the .tlbs. To have the PHY programmed with the correct
> > > > set of PHY settings, the submode passed to PHY driver must be either HS-G4
> > > > or HS-G5.
> > > > 
> > 
> > You should also mention that this issue is also present in G4 supported targets.
> > And a note that it will get fixed later.
> 
> Will this info upset more people? How about I mention this in the cover
> letter?
> 

It is working fine for now and we just want to make sure the sequence is aligned
with HPG. So I don't think it can upset anyone. But yeah, you can just mention
it in the cover letter.

- Mani

> > 
> > > > Signed-off-by: Can Guo <quic_cang@quicinc.com>
> > > > ---
> > > >   drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
> > > >   drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
> > > >   .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
> > > >   drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
> > > >   4 files changed, 115 insertions(+), 13 deletions(-)
> > > > 
> > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > index c23d5e4..e563af5 100644
> > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > @@ -18,6 +18,7 @@
> > > >   #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
> > > >   #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
> > > >   #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
> > > > +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
> > > >   #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
> > > >   #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
> > > >   #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
> > > > @@ -27,5 +28,6 @@
> > > >   #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
> > > >   #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
> > > >   #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
> > > > +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
> > > > 
> > > >   #endif
> > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > index f420f8f..ef392ce 100644
> > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > @@ -56,6 +56,8 @@
> > > >   #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
> > > >   #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
> > > >   #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
> > > > +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
> > > > +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
> > > >   #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
> > > >   #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
> > > >   #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
> > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > index 15bcb4b..48f31c8 100644
> > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > @@ -10,10 +10,20 @@
> > > >   #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
> > > >   #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
> > > >   #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
> > > > +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
> > > > +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
> > > > 
> > > >   #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
> > > >   #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
> > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
> > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
> > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
> > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
> > > > +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
> > > > +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
> > > >   #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
> > > > +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
> > > > +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
> > > >   #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
> > > >   #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
> > > >   #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
> > > > @@ -25,6 +35,8 @@
> > > >   #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
> > > >   #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
> > > >   #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
> > > > +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
> > > >   #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
> > > > +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
> > > > 
> > > >   #endif
> > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > index 3927eba..e0a01497 100644
> > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
> > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
> > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
> > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > > +
> > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
> > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
> > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
> > > > +};
> > > > +
> > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
> > > > +};
> > > > +
> > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
> > > 
> > > Aside from moving these registers to the HS_G4 table, you are also
> > > changing these registers. It makes me think that there was an error in
> > > the original programming sequence.
> > > If that is correct, could you please split the patch into two pieces:
> > > - Fix programming sequence (add proper Fixes tags)
> > > - Split G4 and G5 tables.
> > 
> > Ack
> > 
> > > 
> > > > +
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
> > > 
> > > I see all the MODE1 registers being only present in G4 and G5 tables.
> > > Should they be programmed for the modes lower than G4?
> > > 
> > 
> > We use G4 table for all the modes <= G4.
> > 
> > > > +};
> > > > +
> > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_serdes[] = {
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x1f),
> > > > +
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x1b),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x1c),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
> > > >   };
> > > > 
> > > >   static const struct qmp_phy_init_tbl sm8550_ufsphy_tx[] = {
> > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_1, 0x05),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05),
> > > >          QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
> > > >   };
> > > > 
> > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_tx[] = {
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_FR_DCC_CTRL, 0x4c),
> > > > +};
> > > > +
> > > >   static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
> > > > -       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2, 0x0c),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x0f),
> > > > -       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
> > > > 
> > > >          QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xc2),
> > > >          QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xc2),
> > > > @@ -690,14 +709,46 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
> > > >          QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
> > > >   };
> > > > 
> > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_rx[] = {
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
> > > > +};
> > > > +
> > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_rx[] = {
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4, 0x0c),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4, 0x04),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS, 0x07),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3, 0x0e),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4, 0x02),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x1c),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x06),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x08),
> > > > +
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B3, 0xb9),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B4, 0x4f),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B6, 0xff),
> > > > +       QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL, 0x30),
> > > > +};
> > > > +
> > > >   static const struct qmp_phy_init_tbl sm8550_ufsphy_pcs[] = {
> > > >          QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x69),
> > > >          QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
> > > >          QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
> > > > -       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
> > > >          QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
> > > >   };
> > > > 
> > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_pcs[] = {
> > > > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
> > > > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
> > > > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
> > > > +};
> > > > +
> > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_pcs[] = {
> > > > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
> > > > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4f),
> > > > +       QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e),
> > > > +};
> > > > +
> > > >   struct qmp_ufs_offsets {
> > > >          u16 serdes;
> > > >          u16 pcs;
> > > > @@ -731,6 +782,8 @@ struct qmp_phy_cfg {
> > > >          const struct qmp_phy_cfg_tbls tbls_hs_b;
> > > >          /* Additional sequence for HS G4 */
> > > >          const struct qmp_phy_cfg_tbls tbls_hs_g4;
> > > > +       /* Additional sequence for HS G4 */
> > 
> > HS G5
> 
> Sure
> 
> > 
> > > > +       const struct qmp_phy_cfg_tbls tbls_hs_g5;
> > > > 
> > > >          /* clock ids to be requested */
> > > >          const char * const *clk_list;
> > > > @@ -1157,6 +1210,28 @@ static const struct qmp_phy_cfg sm8550_ufsphy_cfg = {
> > > >                  .pcs            = sm8550_ufsphy_pcs,
> > > >                  .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_pcs),
> > > >          },
> > > > +       .tbls_hs_b = {
> > > > +               .serdes         = sm8550_ufsphy_hs_b_serdes,
> > > > +               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes),
> > > > +       },
> > > > +       .tbls_hs_g4 = {
> > > > +               .serdes         = sm8550_ufsphy_g4_serdes,
> > > > +               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_g4_serdes),
> > > > +               .tx             = sm8550_ufsphy_g4_tx,
> > > > +               .tx_num         = ARRAY_SIZE(sm8550_ufsphy_g4_tx),
> > > > +               .rx             = sm8550_ufsphy_g4_rx,
> > > > +               .rx_num         = ARRAY_SIZE(sm8550_ufsphy_g4_rx),
> > > > +               .pcs            = sm8550_ufsphy_g4_pcs,
> > > > +               .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_g4_pcs),
> > > > +       },
> > > > +       .tbls_hs_g5 = {
> > > > +               .serdes         = sm8550_ufsphy_g5_serdes,
> > > > +               .serdes_num     = ARRAY_SIZE(sm8550_ufsphy_g5_serdes),
> > > > +               .rx             = sm8550_ufsphy_g5_rx,
> > > > +               .rx_num         = ARRAY_SIZE(sm8550_ufsphy_g5_rx),
> > > > +               .pcs            = sm8550_ufsphy_g5_pcs,
> > > > +               .pcs_num        = ARRAY_SIZE(sm8550_ufsphy_g5_pcs),
> > > > +       },
> > > >          .clk_list               = sdm845_ufs_phy_clk_l,
> > > >          .num_clks               = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
> > > >          .vreg_list              = qmp_phy_vreg_l,
> > > > @@ -1222,14 +1297,25 @@ 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->submode == UFS_HS_G4)
> > > > +               qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
> > > > +       else if (qmp->submode == UFS_HS_G5)
> > > > +               qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
> > > > +
> > 
> > Should we program submode sequence after HS_B?
> > 
> > - Mani
> > 
> As the UFS PHY HW programming doc mentions, order of these writes is not
> important, so long as they are programmed correctly before release S/W
> reset, then it is fine.
> 
> Thanks,
> Can Guo.
> 
>
Dmitry Baryshkov Nov. 9, 2023, 9:40 a.m. UTC | #8
On Thu, 9 Nov 2023 at 05:24, Manivannan Sadhasivam <mani@kernel.org> wrote:
>
> On Wed, Nov 08, 2023 at 08:56:16AM +0200, Dmitry Baryshkov wrote:
> > On Wed, 8 Nov 2023 at 07:49, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > >
> > > On Tue, Nov 07, 2023 at 03:18:09PM +0200, Dmitry Baryshkov wrote:
> > > > On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
> > > > >
> > > > > From: Can Guo <quic_cang@quicinc.com>
> > > > >
> > > > > On SM8550, two sets of UFS PHY settings are provided, one set is to support
> > > > > HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
> > > > > settings are programming different values to different registers, mixing
> > > > > the two sets and/or overwriting one set with another set is definitely not
> > > > > blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
> > > > > need to split the two sets into their dedicated tables, and leave only the
> > > > > common settings in the .tlbs. To have the PHY programmed with the correct
> > > > > set of PHY settings, the submode passed to PHY driver must be either HS-G4
> > > > > or HS-G5.
> > > > >
> > >
> > > You should also mention that this issue is also present in G4 supported targets.
> > > And a note that it will get fixed later.
> > >
> > > > > Signed-off-by: Can Guo <quic_cang@quicinc.com>
> > > > > ---
> > > > >  drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
> > > > >  drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
> > > > >  .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
> > > > >  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
> > > > >  4 files changed, 115 insertions(+), 13 deletions(-)
> > > > >
> > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > index c23d5e4..e563af5 100644
> > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > @@ -18,6 +18,7 @@
> > > > >  #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
> > > > >  #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
> > > > >  #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
> > > > > +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
> > > > >  #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
> > > > >  #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
> > > > >  #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
> > > > > @@ -27,5 +28,6 @@
> > > > >  #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
> > > > >  #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
> > > > >  #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
> > > > > +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
> > > > >
> > > > >  #endif
> > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > index f420f8f..ef392ce 100644
> > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > @@ -56,6 +56,8 @@
> > > > >  #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
> > > > >  #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
> > > > >  #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
> > > > > +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
> > > > > +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
> > > > >  #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
> > > > >  #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
> > > > >  #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
> > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > index 15bcb4b..48f31c8 100644
> > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > @@ -10,10 +10,20 @@
> > > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
> > > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
> > > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
> > > > > +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
> > > > > +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
> > > > >
> > > > >  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
> > > > >  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
> > > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
> > > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
> > > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
> > > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
> > > > > +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
> > > > > +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
> > > > >  #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
> > > > > +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
> > > > > +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
> > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
> > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
> > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
> > > > > @@ -25,6 +35,8 @@
> > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
> > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
> > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
> > > > > +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
> > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
> > > > > +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
> > > > >
> > > > >  #endif
> > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > index 3927eba..e0a01497 100644
> > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
> > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
> > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
> > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
> > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > > > +
> > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
> > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
> > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
> > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
> > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
> > > > > +};
> > > > > +
> > > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
> > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
> > > > > +};
> > > > > +
> > > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
> > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
> > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
> > > >
> > > > Aside from moving these registers to the HS_G4 table, you are also
> > > > changing these registers. It makes me think that there was an error in
> > > > the original programming sequence.
> > > > If that is correct, could you please split the patch into two pieces:
> > > > - Fix programming sequence (add proper Fixes tags)
> > > > - Split G4 and G5 tables.
> > >
> > > Ack
> > >
> > > >
> > > > > +
> > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
> > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
> > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
> > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
> > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
> > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
> > > >
> > > > I see all the MODE1 registers being only present in G4 and G5 tables.
> > > > Should they be programmed for the modes lower than G4?
> > > >
> > >
> > > We use G4 table for all the modes <= G4.
> >
> > Could you please point me how it's handled?
> > In the patch I see just:
> >
> >        if (qmp->submode == UFS_HS_G4)
> >                qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
> >        else if (qmp->submode == UFS_HS_G5)
> >                qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
> >
> > Which looks like two special cases (HS_G4 and HS_G5) and nothing for
> > anything else.
> >
>
> Yes, and the UFS driver passes only G4/G5. For all the gears <=G4, G4 init
> sequence will be used and for G5, G5 sequence will be used.
>

That's what I could not find in the UFS driver. I see a call to
`phy_set_mode_ext(phy, PHY_MODE_UFS_HS_B, host->phy_gear);` and
host->phy_gear is initialised to UFS_HS_G2.

Maybe we should change the condition here (in the PHY driver) to:

if (qmp->submode <= UFS_HS_G4)

?
Manivannan Sadhasivam Nov. 9, 2023, 10:42 a.m. UTC | #9
On Thu, Nov 09, 2023 at 11:40:51AM +0200, Dmitry Baryshkov wrote:
> On Thu, 9 Nov 2023 at 05:24, Manivannan Sadhasivam <mani@kernel.org> wrote:
> >
> > On Wed, Nov 08, 2023 at 08:56:16AM +0200, Dmitry Baryshkov wrote:
> > > On Wed, 8 Nov 2023 at 07:49, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > >
> > > > On Tue, Nov 07, 2023 at 03:18:09PM +0200, Dmitry Baryshkov wrote:
> > > > > On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
> > > > > >
> > > > > > From: Can Guo <quic_cang@quicinc.com>
> > > > > >
> > > > > > On SM8550, two sets of UFS PHY settings are provided, one set is to support
> > > > > > HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
> > > > > > settings are programming different values to different registers, mixing
> > > > > > the two sets and/or overwriting one set with another set is definitely not
> > > > > > blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
> > > > > > need to split the two sets into their dedicated tables, and leave only the
> > > > > > common settings in the .tlbs. To have the PHY programmed with the correct
> > > > > > set of PHY settings, the submode passed to PHY driver must be either HS-G4
> > > > > > or HS-G5.
> > > > > >
> > > >
> > > > You should also mention that this issue is also present in G4 supported targets.
> > > > And a note that it will get fixed later.
> > > >
> > > > > > Signed-off-by: Can Guo <quic_cang@quicinc.com>
> > > > > > ---
> > > > > >  drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
> > > > > >  drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
> > > > > >  .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
> > > > > >  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
> > > > > >  4 files changed, 115 insertions(+), 13 deletions(-)
> > > > > >
> > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > index c23d5e4..e563af5 100644
> > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > @@ -18,6 +18,7 @@
> > > > > >  #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
> > > > > >  #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
> > > > > >  #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
> > > > > > +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
> > > > > >  #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
> > > > > >  #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
> > > > > >  #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
> > > > > > @@ -27,5 +28,6 @@
> > > > > >  #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
> > > > > >  #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
> > > > > >  #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
> > > > > > +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
> > > > > >
> > > > > >  #endif
> > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > index f420f8f..ef392ce 100644
> > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > @@ -56,6 +56,8 @@
> > > > > >  #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
> > > > > >  #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
> > > > > >  #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
> > > > > > +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
> > > > > > +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
> > > > > >  #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
> > > > > >  #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
> > > > > >  #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
> > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > index 15bcb4b..48f31c8 100644
> > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > @@ -10,10 +10,20 @@
> > > > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
> > > > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
> > > > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
> > > > > > +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
> > > > > > +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
> > > > > >
> > > > > >  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
> > > > > >  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
> > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
> > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
> > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
> > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
> > > > > > +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
> > > > > > +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
> > > > > >  #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
> > > > > > +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
> > > > > > +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
> > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
> > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
> > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
> > > > > > @@ -25,6 +35,8 @@
> > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
> > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
> > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
> > > > > > +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
> > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
> > > > > > +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
> > > > > >
> > > > > >  #endif
> > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > index 3927eba..e0a01497 100644
> > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
> > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
> > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
> > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
> > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > > > > +
> > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
> > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
> > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
> > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
> > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
> > > > > > +};
> > > > > > +
> > > > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
> > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
> > > > > > +};
> > > > > > +
> > > > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
> > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
> > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
> > > > >
> > > > > Aside from moving these registers to the HS_G4 table, you are also
> > > > > changing these registers. It makes me think that there was an error in
> > > > > the original programming sequence.
> > > > > If that is correct, could you please split the patch into two pieces:
> > > > > - Fix programming sequence (add proper Fixes tags)
> > > > > - Split G4 and G5 tables.
> > > >
> > > > Ack
> > > >
> > > > >
> > > > > > +
> > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
> > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
> > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
> > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
> > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
> > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
> > > > >
> > > > > I see all the MODE1 registers being only present in G4 and G5 tables.
> > > > > Should they be programmed for the modes lower than G4?
> > > > >
> > > >
> > > > We use G4 table for all the modes <= G4.
> > >
> > > Could you please point me how it's handled?
> > > In the patch I see just:
> > >
> > >        if (qmp->submode == UFS_HS_G4)
> > >                qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
> > >        else if (qmp->submode == UFS_HS_G5)
> > >                qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
> > >
> > > Which looks like two special cases (HS_G4 and HS_G5) and nothing for
> > > anything else.
> > >
> >
> > Yes, and the UFS driver passes only G4/G5. For all the gears <=G4, G4 init
> > sequence will be used and for G5, G5 sequence will be used.
> >
> 
> That's what I could not find in the UFS driver. I see a call to
> `phy_set_mode_ext(phy, PHY_MODE_UFS_HS_B, host->phy_gear);` and
> host->phy_gear is initialised to UFS_HS_G2.
> 

You need to check the UFS driver changes in this series to get the complete
picture as the logic is getting changed.

It is common to get confused because of the way the UFS driver (qcom mostly)
handles the PHY init sequence programming. We used to have only one init
sequence for older targets and life was easy. But when I wanted to add G4
support for SM8250, I learned that there are 2 separate init sequences. One for
non-G4 and other for G4. So I used the phy_sub_mode property to pass the
relevant mode from the UFS driver to the PHY driver and programmed the sequence
accordingly. This got extended to non-G5 and G5 now.

Now, the UFS driver will start probing from a low gear for older targets (G2)
and G4/G5 for newer ones then scale up based on the device and host capability.
For older targets, the common table (tbls) will be used if the submode doesn't
match G4/G5. But for newer targets, the UFS driver will _only_ pass G4 or G5 as
the phy_gear, so those specific sequence will only be used.

Hope I'm clear.

- Mani

> Maybe we should change the condition here (in the PHY driver) to:
> 
> if (qmp->submode <= UFS_HS_G4)
> 
> ?
> -- 
> With best wishes
> Dmitry
Dmitry Baryshkov Nov. 9, 2023, 11 a.m. UTC | #10
On Thu, 9 Nov 2023 at 12:43, Manivannan Sadhasivam <mani@kernel.org> wrote:
>
> On Thu, Nov 09, 2023 at 11:40:51AM +0200, Dmitry Baryshkov wrote:
> > On Thu, 9 Nov 2023 at 05:24, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > >
> > > On Wed, Nov 08, 2023 at 08:56:16AM +0200, Dmitry Baryshkov wrote:
> > > > On Wed, 8 Nov 2023 at 07:49, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > > >
> > > > > On Tue, Nov 07, 2023 at 03:18:09PM +0200, Dmitry Baryshkov wrote:
> > > > > > On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
> > > > > > >
> > > > > > > From: Can Guo <quic_cang@quicinc.com>
> > > > > > >
> > > > > > > On SM8550, two sets of UFS PHY settings are provided, one set is to support
> > > > > > > HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
> > > > > > > settings are programming different values to different registers, mixing
> > > > > > > the two sets and/or overwriting one set with another set is definitely not
> > > > > > > blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
> > > > > > > need to split the two sets into their dedicated tables, and leave only the
> > > > > > > common settings in the .tlbs. To have the PHY programmed with the correct
> > > > > > > set of PHY settings, the submode passed to PHY driver must be either HS-G4
> > > > > > > or HS-G5.
> > > > > > >
> > > > >
> > > > > You should also mention that this issue is also present in G4 supported targets.
> > > > > And a note that it will get fixed later.
> > > > >
> > > > > > > Signed-off-by: Can Guo <quic_cang@quicinc.com>
> > > > > > > ---
> > > > > > >  drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
> > > > > > >  drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
> > > > > > >  .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
> > > > > > >  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
> > > > > > >  4 files changed, 115 insertions(+), 13 deletions(-)
> > > > > > >
> > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > > index c23d5e4..e563af5 100644
> > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > > @@ -18,6 +18,7 @@
> > > > > > >  #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
> > > > > > >  #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
> > > > > > >  #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
> > > > > > > +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
> > > > > > >  #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
> > > > > > >  #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
> > > > > > >  #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
> > > > > > > @@ -27,5 +28,6 @@
> > > > > > >  #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
> > > > > > >  #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
> > > > > > >  #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
> > > > > > > +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
> > > > > > >
> > > > > > >  #endif
> > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > > index f420f8f..ef392ce 100644
> > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > > @@ -56,6 +56,8 @@
> > > > > > >  #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
> > > > > > >  #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
> > > > > > >  #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
> > > > > > > +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
> > > > > > > +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
> > > > > > >  #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
> > > > > > >  #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
> > > > > > >  #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
> > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > > index 15bcb4b..48f31c8 100644
> > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > > @@ -10,10 +10,20 @@
> > > > > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
> > > > > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
> > > > > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
> > > > > > > +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
> > > > > > > +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
> > > > > > >
> > > > > > >  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
> > > > > > >  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
> > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
> > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
> > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
> > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
> > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
> > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
> > > > > > >  #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
> > > > > > > +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
> > > > > > > +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
> > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
> > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
> > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
> > > > > > > @@ -25,6 +35,8 @@
> > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
> > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
> > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
> > > > > > > +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
> > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
> > > > > > > +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
> > > > > > >
> > > > > > >  #endif
> > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > > index 3927eba..e0a01497 100644
> > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > > @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
> > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
> > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
> > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
> > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > > > > > +
> > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
> > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
> > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
> > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
> > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
> > > > > > > +};
> > > > > > > +
> > > > > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
> > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
> > > > > > > +};
> > > > > > > +
> > > > > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
> > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
> > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
> > > > > >
> > > > > > Aside from moving these registers to the HS_G4 table, you are also
> > > > > > changing these registers. It makes me think that there was an error in
> > > > > > the original programming sequence.
> > > > > > If that is correct, could you please split the patch into two pieces:
> > > > > > - Fix programming sequence (add proper Fixes tags)
> > > > > > - Split G4 and G5 tables.
> > > > >
> > > > > Ack
> > > > >
> > > > > >
> > > > > > > +
> > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
> > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
> > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
> > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
> > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
> > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
> > > > > >
> > > > > > I see all the MODE1 registers being only present in G4 and G5 tables.
> > > > > > Should they be programmed for the modes lower than G4?
> > > > > >
> > > > >
> > > > > We use G4 table for all the modes <= G4.
> > > >
> > > > Could you please point me how it's handled?
> > > > In the patch I see just:
> > > >
> > > >        if (qmp->submode == UFS_HS_G4)
> > > >                qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
> > > >        else if (qmp->submode == UFS_HS_G5)
> > > >                qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
> > > >
> > > > Which looks like two special cases (HS_G4 and HS_G5) and nothing for
> > > > anything else.
> > > >
> > >
> > > Yes, and the UFS driver passes only G4/G5. For all the gears <=G4, G4 init
> > > sequence will be used and for G5, G5 sequence will be used.
> > >
> >
> > That's what I could not find in the UFS driver. I see a call to
> > `phy_set_mode_ext(phy, PHY_MODE_UFS_HS_B, host->phy_gear);` and
> > host->phy_gear is initialised to UFS_HS_G2.
> >
>
> You need to check the UFS driver changes in this series to get the complete
> picture as the logic is getting changed.
>
> It is common to get confused because of the way the UFS driver (qcom mostly)
> handles the PHY init sequence programming. We used to have only one init
> sequence for older targets and life was easy. But when I wanted to add G4
> support for SM8250, I learned that there are 2 separate init sequences. One for
> non-G4 and other for G4. So I used the phy_sub_mode property to pass the
> relevant mode from the UFS driver to the PHY driver and programmed the sequence
> accordingly. This got extended to non-G5 and G5 now.
>
> Now, the UFS driver will start probing from a low gear for older targets (G2)
> and G4/G5 for newer ones then scale up based on the device and host capability.
> For older targets, the common table (tbls) will be used if the submode doesn't
> match G4/G5. But for newer targets, the UFS driver will _only_ pass G4 or G5 as
> the phy_gear, so those specific sequence will only be used.
>
> Hope I'm clear.

Yes, it is now clear, thank you!

Would it be possible / feasible / logical to maintain this idea even
for newer platforms (leaving the HS_A  / HS_B aside)?

tbls - works for HS_G2
tbls + tbls_g4 - works for HS_G4
tbls + tbls_g5 - works for HS_G5

I mean here that the PHY driver should not depend on the knowledge
that the UFS driver will not be setting HS_G2 for some particular
platform and ideally it should continue working if at some point we
change the UFS driver to set HS_G2.


>
> - Mani
>
> > Maybe we should change the condition here (in the PHY driver) to:
> >
> > if (qmp->submode <= UFS_HS_G4)
> >
> > ?
> > --
> > With best wishes
> > Dmitry
>
> --
> மணிவண்ணன் சதாசிவம்



--
With best wishes
Dmitry
Manivannan Sadhasivam Nov. 9, 2023, 4:04 p.m. UTC | #11
On Thu, Nov 09, 2023 at 01:00:51PM +0200, Dmitry Baryshkov wrote:
> On Thu, 9 Nov 2023 at 12:43, Manivannan Sadhasivam <mani@kernel.org> wrote:
> >
> > On Thu, Nov 09, 2023 at 11:40:51AM +0200, Dmitry Baryshkov wrote:
> > > On Thu, 9 Nov 2023 at 05:24, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > >
> > > > On Wed, Nov 08, 2023 at 08:56:16AM +0200, Dmitry Baryshkov wrote:
> > > > > On Wed, 8 Nov 2023 at 07:49, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > > > >
> > > > > > On Tue, Nov 07, 2023 at 03:18:09PM +0200, Dmitry Baryshkov wrote:
> > > > > > > On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
> > > > > > > >
> > > > > > > > From: Can Guo <quic_cang@quicinc.com>
> > > > > > > >
> > > > > > > > On SM8550, two sets of UFS PHY settings are provided, one set is to support
> > > > > > > > HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
> > > > > > > > settings are programming different values to different registers, mixing
> > > > > > > > the two sets and/or overwriting one set with another set is definitely not
> > > > > > > > blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
> > > > > > > > need to split the two sets into their dedicated tables, and leave only the
> > > > > > > > common settings in the .tlbs. To have the PHY programmed with the correct
> > > > > > > > set of PHY settings, the submode passed to PHY driver must be either HS-G4
> > > > > > > > or HS-G5.
> > > > > > > >
> > > > > >
> > > > > > You should also mention that this issue is also present in G4 supported targets.
> > > > > > And a note that it will get fixed later.
> > > > > >
> > > > > > > > Signed-off-by: Can Guo <quic_cang@quicinc.com>
> > > > > > > > ---
> > > > > > > >  drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
> > > > > > > >  drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
> > > > > > > >  .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
> > > > > > > >  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
> > > > > > > >  4 files changed, 115 insertions(+), 13 deletions(-)
> > > > > > > >
> > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > > > index c23d5e4..e563af5 100644
> > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > > > @@ -18,6 +18,7 @@
> > > > > > > >  #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
> > > > > > > >  #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
> > > > > > > >  #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
> > > > > > > > +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
> > > > > > > >  #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
> > > > > > > >  #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
> > > > > > > >  #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
> > > > > > > > @@ -27,5 +28,6 @@
> > > > > > > >  #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
> > > > > > > >  #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
> > > > > > > >  #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
> > > > > > > > +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
> > > > > > > >
> > > > > > > >  #endif
> > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > > > index f420f8f..ef392ce 100644
> > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > > > @@ -56,6 +56,8 @@
> > > > > > > >  #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
> > > > > > > >  #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
> > > > > > > >  #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
> > > > > > > > +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
> > > > > > > > +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
> > > > > > > >  #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
> > > > > > > >  #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
> > > > > > > >  #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
> > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > > > index 15bcb4b..48f31c8 100644
> > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > > > @@ -10,10 +10,20 @@
> > > > > > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
> > > > > > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
> > > > > > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
> > > > > > > > +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
> > > > > > > > +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
> > > > > > > >
> > > > > > > >  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
> > > > > > > >  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
> > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
> > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
> > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
> > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
> > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
> > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
> > > > > > > >  #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
> > > > > > > > +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
> > > > > > > > +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
> > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
> > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
> > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
> > > > > > > > @@ -25,6 +35,8 @@
> > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
> > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
> > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
> > > > > > > > +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
> > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
> > > > > > > > +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
> > > > > > > >
> > > > > > > >  #endif
> > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > > > index 3927eba..e0a01497 100644
> > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > > > @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
> > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
> > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
> > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
> > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > > > > > > +
> > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
> > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
> > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
> > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
> > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
> > > > > > > > +};
> > > > > > > > +
> > > > > > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
> > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
> > > > > > > > +};
> > > > > > > > +
> > > > > > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
> > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
> > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
> > > > > > >
> > > > > > > Aside from moving these registers to the HS_G4 table, you are also
> > > > > > > changing these registers. It makes me think that there was an error in
> > > > > > > the original programming sequence.
> > > > > > > If that is correct, could you please split the patch into two pieces:
> > > > > > > - Fix programming sequence (add proper Fixes tags)
> > > > > > > - Split G4 and G5 tables.
> > > > > >
> > > > > > Ack
> > > > > >
> > > > > > >
> > > > > > > > +
> > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
> > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
> > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
> > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
> > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
> > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
> > > > > > >
> > > > > > > I see all the MODE1 registers being only present in G4 and G5 tables.
> > > > > > > Should they be programmed for the modes lower than G4?
> > > > > > >
> > > > > >
> > > > > > We use G4 table for all the modes <= G4.
> > > > >
> > > > > Could you please point me how it's handled?
> > > > > In the patch I see just:
> > > > >
> > > > >        if (qmp->submode == UFS_HS_G4)
> > > > >                qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
> > > > >        else if (qmp->submode == UFS_HS_G5)
> > > > >                qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
> > > > >
> > > > > Which looks like two special cases (HS_G4 and HS_G5) and nothing for
> > > > > anything else.
> > > > >
> > > >
> > > > Yes, and the UFS driver passes only G4/G5. For all the gears <=G4, G4 init
> > > > sequence will be used and for G5, G5 sequence will be used.
> > > >
> > >
> > > That's what I could not find in the UFS driver. I see a call to
> > > `phy_set_mode_ext(phy, PHY_MODE_UFS_HS_B, host->phy_gear);` and
> > > host->phy_gear is initialised to UFS_HS_G2.
> > >
> >
> > You need to check the UFS driver changes in this series to get the complete
> > picture as the logic is getting changed.
> >
> > It is common to get confused because of the way the UFS driver (qcom mostly)
> > handles the PHY init sequence programming. We used to have only one init
> > sequence for older targets and life was easy. But when I wanted to add G4
> > support for SM8250, I learned that there are 2 separate init sequences. One for
> > non-G4 and other for G4. So I used the phy_sub_mode property to pass the
> > relevant mode from the UFS driver to the PHY driver and programmed the sequence
> > accordingly. This got extended to non-G5 and G5 now.
> >
> > Now, the UFS driver will start probing from a low gear for older targets (G2)
> > and G4/G5 for newer ones then scale up based on the device and host capability.
> > For older targets, the common table (tbls) will be used if the submode doesn't
> > match G4/G5. But for newer targets, the UFS driver will _only_ pass G4 or G5 as
> > the phy_gear, so those specific sequence will only be used.
> >
> > Hope I'm clear.
> 
> Yes, it is now clear, thank you!
> 
> Would it be possible / feasible / logical to maintain this idea even
> for newer platforms (leaving the HS_A  / HS_B aside)?
> 
> tbls - works for HS_G2
> tbls + tbls_g4 - works for HS_G4
> tbls + tbls_g5 - works for HS_G5
> 

No. The PHY team only gives 2 init sequences for any SoC now.

- Mani

> I mean here that the PHY driver should not depend on the knowledge
> that the UFS driver will not be setting HS_G2 for some particular
> platform and ideally it should continue working if at some point we
> change the UFS driver to set HS_G2.
> 
> 
> >
> > - Mani
> >
> > > Maybe we should change the condition here (in the PHY driver) to:
> > >
> > > if (qmp->submode <= UFS_HS_G4)
> > >
> > > ?
> > > --
> > > With best wishes
> > > Dmitry
> >
> > --
> > மணிவண்ணன் சதாசிவம்
> 
> 
> 
> --
> With best wishes
> Dmitry
Dmitry Baryshkov Nov. 9, 2023, 10:11 p.m. UTC | #12
On Thu, 9 Nov 2023 at 18:04, Manivannan Sadhasivam <mani@kernel.org> wrote:
>
> On Thu, Nov 09, 2023 at 01:00:51PM +0200, Dmitry Baryshkov wrote:
> > On Thu, 9 Nov 2023 at 12:43, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > >
> > > On Thu, Nov 09, 2023 at 11:40:51AM +0200, Dmitry Baryshkov wrote:
> > > > On Thu, 9 Nov 2023 at 05:24, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > > >
> > > > > On Wed, Nov 08, 2023 at 08:56:16AM +0200, Dmitry Baryshkov wrote:
> > > > > > On Wed, 8 Nov 2023 at 07:49, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > > > > >
> > > > > > > On Tue, Nov 07, 2023 at 03:18:09PM +0200, Dmitry Baryshkov wrote:
> > > > > > > > On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
> > > > > > > > >
> > > > > > > > > From: Can Guo <quic_cang@quicinc.com>
> > > > > > > > >
> > > > > > > > > On SM8550, two sets of UFS PHY settings are provided, one set is to support
> > > > > > > > > HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
> > > > > > > > > settings are programming different values to different registers, mixing
> > > > > > > > > the two sets and/or overwriting one set with another set is definitely not
> > > > > > > > > blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
> > > > > > > > > need to split the two sets into their dedicated tables, and leave only the
> > > > > > > > > common settings in the .tlbs. To have the PHY programmed with the correct
> > > > > > > > > set of PHY settings, the submode passed to PHY driver must be either HS-G4
> > > > > > > > > or HS-G5.
> > > > > > > > >
> > > > > > >
> > > > > > > You should also mention that this issue is also present in G4 supported targets.
> > > > > > > And a note that it will get fixed later.
> > > > > > >
> > > > > > > > > Signed-off-by: Can Guo <quic_cang@quicinc.com>
> > > > > > > > > ---
> > > > > > > > >  drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
> > > > > > > > >  drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
> > > > > > > > >  .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
> > > > > > > > >  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
> > > > > > > > >  4 files changed, 115 insertions(+), 13 deletions(-)
> > > > > > > > >
> > > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > > > > index c23d5e4..e563af5 100644
> > > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > > > > @@ -18,6 +18,7 @@
> > > > > > > > >  #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
> > > > > > > > >  #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
> > > > > > > > >  #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
> > > > > > > > > +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
> > > > > > > > >  #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
> > > > > > > > >  #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
> > > > > > > > >  #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
> > > > > > > > > @@ -27,5 +28,6 @@
> > > > > > > > >  #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
> > > > > > > > >  #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
> > > > > > > > >  #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
> > > > > > > > > +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
> > > > > > > > >
> > > > > > > > >  #endif
> > > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > > > > index f420f8f..ef392ce 100644
> > > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > > > > @@ -56,6 +56,8 @@
> > > > > > > > >  #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
> > > > > > > > >  #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
> > > > > > > > >  #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
> > > > > > > > > +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
> > > > > > > > > +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
> > > > > > > > >  #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
> > > > > > > > >  #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
> > > > > > > > >  #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
> > > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > > > > index 15bcb4b..48f31c8 100644
> > > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > > > > @@ -10,10 +10,20 @@
> > > > > > > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
> > > > > > > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
> > > > > > > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
> > > > > > > > > +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
> > > > > > > > > +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
> > > > > > > > >
> > > > > > > > >  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
> > > > > > > > >  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
> > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
> > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
> > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
> > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
> > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
> > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
> > > > > > > > >  #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
> > > > > > > > > +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
> > > > > > > > > +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
> > > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
> > > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
> > > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
> > > > > > > > > @@ -25,6 +35,8 @@
> > > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
> > > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
> > > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
> > > > > > > > > +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
> > > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
> > > > > > > > > +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
> > > > > > > > >
> > > > > > > > >  #endif
> > > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > > > > index 3927eba..e0a01497 100644
> > > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > > > > @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
> > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
> > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
> > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
> > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > > > > > > > +
> > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
> > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
> > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
> > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
> > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
> > > > > > > > > +};
> > > > > > > > > +
> > > > > > > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
> > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
> > > > > > > > > +};
> > > > > > > > > +
> > > > > > > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
> > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
> > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
> > > > > > > >
> > > > > > > > Aside from moving these registers to the HS_G4 table, you are also
> > > > > > > > changing these registers. It makes me think that there was an error in
> > > > > > > > the original programming sequence.
> > > > > > > > If that is correct, could you please split the patch into two pieces:
> > > > > > > > - Fix programming sequence (add proper Fixes tags)
> > > > > > > > - Split G4 and G5 tables.
> > > > > > >
> > > > > > > Ack
> > > > > > >
> > > > > > > >
> > > > > > > > > +
> > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
> > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
> > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
> > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
> > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
> > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
> > > > > > > >
> > > > > > > > I see all the MODE1 registers being only present in G4 and G5 tables.
> > > > > > > > Should they be programmed for the modes lower than G4?
> > > > > > > >
> > > > > > >
> > > > > > > We use G4 table for all the modes <= G4.
> > > > > >
> > > > > > Could you please point me how it's handled?
> > > > > > In the patch I see just:
> > > > > >
> > > > > >        if (qmp->submode == UFS_HS_G4)
> > > > > >                qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
> > > > > >        else if (qmp->submode == UFS_HS_G5)
> > > > > >                qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
> > > > > >
> > > > > > Which looks like two special cases (HS_G4 and HS_G5) and nothing for
> > > > > > anything else.
> > > > > >
> > > > >
> > > > > Yes, and the UFS driver passes only G4/G5. For all the gears <=G4, G4 init
> > > > > sequence will be used and for G5, G5 sequence will be used.
> > > > >
> > > >
> > > > That's what I could not find in the UFS driver. I see a call to
> > > > `phy_set_mode_ext(phy, PHY_MODE_UFS_HS_B, host->phy_gear);` and
> > > > host->phy_gear is initialised to UFS_HS_G2.
> > > >
> > >
> > > You need to check the UFS driver changes in this series to get the complete
> > > picture as the logic is getting changed.
> > >
> > > It is common to get confused because of the way the UFS driver (qcom mostly)
> > > handles the PHY init sequence programming. We used to have only one init
> > > sequence for older targets and life was easy. But when I wanted to add G4
> > > support for SM8250, I learned that there are 2 separate init sequences. One for
> > > non-G4 and other for G4. So I used the phy_sub_mode property to pass the
> > > relevant mode from the UFS driver to the PHY driver and programmed the sequence
> > > accordingly. This got extended to non-G5 and G5 now.
> > >
> > > Now, the UFS driver will start probing from a low gear for older targets (G2)
> > > and G4/G5 for newer ones then scale up based on the device and host capability.
> > > For older targets, the common table (tbls) will be used if the submode doesn't
> > > match G4/G5. But for newer targets, the UFS driver will _only_ pass G4 or G5 as
> > > the phy_gear, so those specific sequence will only be used.
> > >
> > > Hope I'm clear.
> >
> > Yes, it is now clear, thank you!
> >
> > Would it be possible / feasible / logical to maintain this idea even
> > for newer platforms (leaving the HS_A  / HS_B aside)?
> >
> > tbls - works for HS_G2
> > tbls + tbls_g4 - works for HS_G4
> > tbls + tbls_g5 - works for HS_G5
> >
>
> No. The PHY team only gives 2 init sequences for any SoC now.

Ack. Then the code should become
if (HS_G5)
   program(tbls_hs_g5)
else
   program(tbls_hs_g4);

>
> - Mani
>
> > I mean here that the PHY driver should not depend on the knowledge
> > that the UFS driver will not be setting HS_G2 for some particular
> > platform and ideally it should continue working if at some point we
> > change the UFS driver to set HS_G2.
> >
> >
> > >
> > > - Mani
> > >
> > > > Maybe we should change the condition here (in the PHY driver) to:
> > > >
> > > > if (qmp->submode <= UFS_HS_G4)
> > > >
> > > > ?
> > > > --
> > > > With best wishes
> > > > Dmitry
> > >
> > > --
> > > மணிவண்ணன் சதாசிவம்
> >
> >
> >
> > --
> > With best wishes
> > Dmitry
>
> --
> மணிவண்ணன் சதாசிவம்
Neil Armstrong Nov. 10, 2023, 8:47 a.m. UTC | #13
Hi,

On 07/11/2023 05:46, Can Guo wrote:
> From: Can Guo <quic_cang@quicinc.com>
> 
> On SM8550, two sets of UFS PHY settings are provided, one set is to support
> HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
> settings are programming different values to different registers, mixing
> the two sets and/or overwriting one set with another set is definitely not
> blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
> need to split the two sets into their dedicated tables, and leave only the
> common settings in the .tlbs. To have the PHY programmed with the correct
> set of PHY settings, the submode passed to PHY driver must be either HS-G4
> or HS-G5.

I guess I'll need to rebase my SM8650 UFS PHY driver to support both G4 and G5 modes
at some point ?

Neil

> 
> Signed-off-by: Can Guo <quic_cang@quicinc.com>
> ---
>   drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
>   drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
>   .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
>   drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
>   4 files changed, 115 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> index c23d5e4..e563af5 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> @@ -18,6 +18,7 @@
>   #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL		0x060
>   #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY		0x074
>   #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY		0x0bc
> +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY	0x12c
>   #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL		0x158
>   #define QPHY_V6_PCS_UFS_LINECFG_DISABLE			0x17c
>   #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME		0x184
> @@ -27,5 +28,6 @@
>   #define QPHY_V6_PCS_UFS_READY_STATUS			0x1a8
>   #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1		0x1f4
>   #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1		0x1fc
> +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME		0x220
>   
>   #endif
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> index f420f8f..ef392ce 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> @@ -56,6 +56,8 @@
>   #define QSERDES_V6_COM_SYS_CLK_CTRL				0xe4
>   #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE			0xe8
>   #define QSERDES_V6_COM_PLL_IVCO					0xf4
> +#define QSERDES_V6_COM_CMN_IETRIM				0xfc
> +#define QSERDES_V6_COM_CMN_IPTRIM				0x100
>   #define QSERDES_V6_COM_SYSCLK_EN_SEL				0x110
>   #define QSERDES_V6_COM_RESETSM_CNTRL				0x118
>   #define QSERDES_V6_COM_LOCK_CMP_EN				0x120
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> index 15bcb4b..48f31c8 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> @@ -10,10 +10,20 @@
>   #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX			0x2c
>   #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX		0x30
>   #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX		0x34
> +#define QSERDES_UFS_V6_TX_LANE_MODE_1				0x7c
> +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL				0x108
>   
>   #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2		0x08
>   #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4		0x10
> +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4		0x24
> +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4	0x54
> +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2			0xd4
> +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4			0xdc
> +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4			0xf0
> +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS			0xf4
>   #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL			0x178
> +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1		0x1bc
> +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3			0x1c4
>   #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0			0x208
>   #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1			0x20c
>   #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3			0x214
> @@ -25,6 +35,8 @@
>   #define QSERDES_UFS_V6_RX_MODE_RATE3_B5				0x264
>   #define QSERDES_UFS_V6_RX_MODE_RATE3_B8				0x270
>   #define QSERDES_UFS_V6_RX_MODE_RATE4_B3				0x280
> +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4				0x284
>   #define QSERDES_UFS_V6_RX_MODE_RATE4_B6				0x28c
> +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL			0x2f8
>   
>   #endif
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> index 3927eba..e0a01497 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
>   	QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
>   	QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
>   	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
> -	QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> -	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> +
>   	QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
>   	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
> -	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
>   	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
>   	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
>   	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
>   	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
> -	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
> +};
> +
> +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
> +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
> +};
> +
> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
> +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
>   	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> -	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> -	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> -	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
> -	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
> +
> +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
> +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
> +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
> +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
> +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
> +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
> +};
> +
> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_serdes[] = {
> +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x1f),
> +
> +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x1b),
> +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x1c),
> +	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
>   };
>   
>   static const struct qmp_phy_init_tbl sm8550_ufsphy_tx[] = {
> -	QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_1, 0x05),
> +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05),
>   	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
>   };
>   
> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_tx[] = {
> +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_FR_DCC_CTRL, 0x4c),
> +};
> +
>   static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
> -	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2, 0x0c),
> -	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x0f),
> -	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
> +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
>   
>   	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xc2),
>   	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xc2),
> @@ -690,14 +709,46 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
>   	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
>   };
>   
> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_rx[] = {
> +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
> +};
> +
> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_rx[] = {
> +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4, 0x0c),
> +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4, 0x04),
> +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
> +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS, 0x07),
> +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3, 0x0e),
> +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4, 0x02),
> +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x1c),
> +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x06),
> +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x08),
> +
> +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B3, 0xb9),
> +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B4, 0x4f),
> +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B6, 0xff),
> +	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL, 0x30),
> +};
> +
>   static const struct qmp_phy_init_tbl sm8550_ufsphy_pcs[] = {
>   	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x69),
>   	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
>   	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
> -	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
>   	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
>   };
>   
> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_pcs[] = {
> +	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
> +	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
> +	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
> +};
> +
> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_pcs[] = {
> +	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
> +	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4f),
> +	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e),
> +};
> +
>   struct qmp_ufs_offsets {
>   	u16 serdes;
>   	u16 pcs;
> @@ -731,6 +782,8 @@ struct qmp_phy_cfg {
>   	const struct qmp_phy_cfg_tbls tbls_hs_b;
>   	/* Additional sequence for HS G4 */
>   	const struct qmp_phy_cfg_tbls tbls_hs_g4;
> +	/* Additional sequence for HS G4 */
> +	const struct qmp_phy_cfg_tbls tbls_hs_g5;
>   
>   	/* clock ids to be requested */
>   	const char * const *clk_list;
> @@ -1157,6 +1210,28 @@ static const struct qmp_phy_cfg sm8550_ufsphy_cfg = {
>   		.pcs		= sm8550_ufsphy_pcs,
>   		.pcs_num	= ARRAY_SIZE(sm8550_ufsphy_pcs),
>   	},
> +	.tbls_hs_b = {
> +		.serdes		= sm8550_ufsphy_hs_b_serdes,
> +		.serdes_num	= ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes),
> +	},
> +	.tbls_hs_g4 = {
> +		.serdes		= sm8550_ufsphy_g4_serdes,
> +		.serdes_num	= ARRAY_SIZE(sm8550_ufsphy_g4_serdes),
> +		.tx		= sm8550_ufsphy_g4_tx,
> +		.tx_num		= ARRAY_SIZE(sm8550_ufsphy_g4_tx),
> +		.rx		= sm8550_ufsphy_g4_rx,
> +		.rx_num		= ARRAY_SIZE(sm8550_ufsphy_g4_rx),
> +		.pcs		= sm8550_ufsphy_g4_pcs,
> +		.pcs_num	= ARRAY_SIZE(sm8550_ufsphy_g4_pcs),
> +	},
> +	.tbls_hs_g5 = {
> +		.serdes		= sm8550_ufsphy_g5_serdes,
> +		.serdes_num	= ARRAY_SIZE(sm8550_ufsphy_g5_serdes),
> +		.rx		= sm8550_ufsphy_g5_rx,
> +		.rx_num		= ARRAY_SIZE(sm8550_ufsphy_g5_rx),
> +		.pcs		= sm8550_ufsphy_g5_pcs,
> +		.pcs_num	= ARRAY_SIZE(sm8550_ufsphy_g5_pcs),
> +	},
>   	.clk_list		= sdm845_ufs_phy_clk_l,
>   	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
>   	.vreg_list		= qmp_phy_vreg_l,
> @@ -1222,14 +1297,25 @@ 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->submode == UFS_HS_G4)
> +		qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
> +	else if (qmp->submode == UFS_HS_G5)
> +		qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
> +
>   	if (qmp->mode == PHY_MODE_UFS_HS_B)
>   		qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_b);
> +
>   	qmp_ufs_lanes_init(qmp, &cfg->tbls);
>   	if (qmp->submode == UFS_HS_G4)
>   		qmp_ufs_lanes_init(qmp, &cfg->tbls_hs_g4);
> +	else if (qmp->submode == UFS_HS_G5)
> +		qmp_ufs_lanes_init(qmp, &cfg->tbls_hs_g5);
> +
>   	qmp_ufs_pcs_init(qmp, &cfg->tbls);
>   	if (qmp->submode == UFS_HS_G4)
>   		qmp_ufs_pcs_init(qmp, &cfg->tbls_hs_g4);
> +	else if (qmp->submode == UFS_HS_G5)
> +		qmp_ufs_pcs_init(qmp, &cfg->tbls_hs_g5);
>   }
>   
>   static int qmp_ufs_com_init(struct qmp_ufs *qmp)
Can Guo Nov. 10, 2023, 9:03 a.m. UTC | #14
Hi Neil,

On 11/10/2023 4:47 PM, neil.armstrong@linaro.org wrote:
> Hi,
> 
> On 07/11/2023 05:46, Can Guo wrote:
>> From: Can Guo <quic_cang@quicinc.com>
>>
>> On SM8550, two sets of UFS PHY settings are provided, one set is to 
>> support
>> HS-G5, another set is to support HS-G4 and lower gears. The two sets 
>> of PHY
>> settings are programming different values to different registers, mixing
>> the two sets and/or overwriting one set with another set is definitely 
>> not
>> blessed by UFS PHY designers. In order to add HS-G5 support for 
>> SM8550, we
>> need to split the two sets into their dedicated tables, and leave only 
>> the
>> common settings in the .tlbs. To have the PHY programmed with the correct
>> set of PHY settings, the submode passed to PHY driver must be either 
>> HS-G4
>> or HS-G5.
> 
> I guess I'll need to rebase my SM8650 UFS PHY driver to support both G4 
> and G5 modes
> at some point ?


Thank for reaching out. Yes, please.

I can help review the PHY settings.

BTW, are you enabling MCQ (by adding MCQ related DT) at the same time?

Thanks,
Can Guo.

> 
> Neil
>
Neil Armstrong Nov. 10, 2023, 9:17 a.m. UTC | #15
Hi,

On 10/11/2023 10:03, Can Guo wrote:
> Hi Neil,
> 
> On 11/10/2023 4:47 PM, neil.armstrong@linaro.org wrote:
>> Hi,
>>
>> On 07/11/2023 05:46, Can Guo wrote:
>>> From: Can Guo <quic_cang@quicinc.com>
>>>
>>> On SM8550, two sets of UFS PHY settings are provided, one set is to support
>>> HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
>>> settings are programming different values to different registers, mixing
>>> the two sets and/or overwriting one set with another set is definitely not
>>> blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
>>> need to split the two sets into their dedicated tables, and leave only the
>>> common settings in the .tlbs. To have the PHY programmed with the correct
>>> set of PHY settings, the submode passed to PHY driver must be either HS-G4
>>> or HS-G5.
>>
>> I guess I'll need to rebase my SM8650 UFS PHY driver to support both G4 and G5 modes
>> at some point ?
> 
> 
> Thank for reaching out. Yes, please.
> 
> I can help review the PHY settings.

Ok I'll try rebasing on this serie and add G5 support.

> 
> BTW, are you enabling MCQ (by adding MCQ related DT) at the same time?

I tested MCQ but it triggers the same issues we have with suspend/resume on SM8550 & SM8650,
and the bindings are not present of the UFS qcom node.

Neil

> 
> Thanks,
> Can Guo.
> 
>>
>> Neil
>>
Can Guo Nov. 10, 2023, 9:32 a.m. UTC | #16
Hi Neil,

On 11/10/2023 5:17 PM, neil.armstrong@linaro.org wrote:
> Hi,
> 
> On 10/11/2023 10:03, Can Guo wrote:
>> Hi Neil,
>>
>> On 11/10/2023 4:47 PM, neil.armstrong@linaro.org wrote:
>>> Hi,
>>>
>>> On 07/11/2023 05:46, Can Guo wrote:
>>>> From: Can Guo <quic_cang@quicinc.com>
>>>>
>>>> On SM8550, two sets of UFS PHY settings are provided, one set is to 
>>>> support
>>>> HS-G5, another set is to support HS-G4 and lower gears. The two sets 
>>>> of PHY
>>>> settings are programming different values to different registers, 
>>>> mixing
>>>> the two sets and/or overwriting one set with another set is 
>>>> definitely not
>>>> blessed by UFS PHY designers. In order to add HS-G5 support for 
>>>> SM8550, we
>>>> need to split the two sets into their dedicated tables, and leave 
>>>> only the
>>>> common settings in the .tlbs. To have the PHY programmed with the 
>>>> correct
>>>> set of PHY settings, the submode passed to PHY driver must be either 
>>>> HS-G4
>>>> or HS-G5.
>>>
>>> I guess I'll need to rebase my SM8650 UFS PHY driver to support both 
>>> G4 and G5 modes
>>> at some point ?
>>
>>
>> Thank for reaching out. Yes, please.
>>
>> I can help review the PHY settings.
> 
> Ok I'll try rebasing on this serie and add G5 support.
> 
>>
>> BTW, are you enabling MCQ (by adding MCQ related DT) at the same time?
> 
> I tested MCQ but it triggers the same issues we have with suspend/resume 
> on SM8550 & SM8650,
> and the bindings are not present of the UFS qcom node.

Are you talking about suspend/resume fail with rpm/spm_lvl == 5? If yes, 
then Nitin and Naveen are working on fixing it.

If you have plan to enable UFS MCQ on SM8650 later, please let me know, 
I have some BUG fixes for it, we can co-work.

Thanks,
Can Guo

> 
> Neil
> 
>>
>> Thanks,
>> Can Guo.
>>
>>>
>>> Neil
>>>
>
Neil Armstrong Nov. 10, 2023, 9:35 a.m. UTC | #17
On 10/11/2023 10:32, Can Guo wrote:
> Hi Neil,
> 
> On 11/10/2023 5:17 PM, neil.armstrong@linaro.org wrote:
>> Hi,
>>
>> On 10/11/2023 10:03, Can Guo wrote:
>>> Hi Neil,
>>>
>>> On 11/10/2023 4:47 PM, neil.armstrong@linaro.org wrote:
>>>> Hi,
>>>>
>>>> On 07/11/2023 05:46, Can Guo wrote:
>>>>> From: Can Guo <quic_cang@quicinc.com>
>>>>>
>>>>> On SM8550, two sets of UFS PHY settings are provided, one set is to support
>>>>> HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
>>>>> settings are programming different values to different registers, mixing
>>>>> the two sets and/or overwriting one set with another set is definitely not
>>>>> blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
>>>>> need to split the two sets into their dedicated tables, and leave only the
>>>>> common settings in the .tlbs. To have the PHY programmed with the correct
>>>>> set of PHY settings, the submode passed to PHY driver must be either HS-G4
>>>>> or HS-G5.
>>>>
>>>> I guess I'll need to rebase my SM8650 UFS PHY driver to support both G4 and G5 modes
>>>> at some point ?
>>>
>>>
>>> Thank for reaching out. Yes, please.
>>>
>>> I can help review the PHY settings.
>>
>> Ok I'll try rebasing on this serie and add G5 support.
>>
>>>
>>> BTW, are you enabling MCQ (by adding MCQ related DT) at the same time?
>>
>> I tested MCQ but it triggers the same issues we have with suspend/resume on SM8550 & SM8650,
>> and the bindings are not present of the UFS qcom node.
> 
> Are you talking about suspend/resume fail with rpm/spm_lvl == 5? If yes, then Nitin and Naveen are working on fixing it.

Exact, if you have some changes for me to test, I'll be happy to have a run on 8550 and 8650.

> 
> If you have plan to enable UFS MCQ on SM8650 later, please let me know, I have some BUG fixes for it, we can co-work.

Yes I plan to when basic SM8650 support gets merged, same I'm able to test some changes if needed.

Neil

> 
> Thanks,
> Can Guo
> 
>>
>> Neil
>>
>>>
>>> Thanks,
>>> Can Guo.
>>>
>>>>
>>>> Neil
>>>>
>>
Manivannan Sadhasivam Nov. 10, 2023, 1:18 p.m. UTC | #18
On Fri, Nov 10, 2023 at 12:11:46AM +0200, Dmitry Baryshkov wrote:
> On Thu, 9 Nov 2023 at 18:04, Manivannan Sadhasivam <mani@kernel.org> wrote:
> >
> > On Thu, Nov 09, 2023 at 01:00:51PM +0200, Dmitry Baryshkov wrote:
> > > On Thu, 9 Nov 2023 at 12:43, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > >
> > > > On Thu, Nov 09, 2023 at 11:40:51AM +0200, Dmitry Baryshkov wrote:
> > > > > On Thu, 9 Nov 2023 at 05:24, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > > > >
> > > > > > On Wed, Nov 08, 2023 at 08:56:16AM +0200, Dmitry Baryshkov wrote:
> > > > > > > On Wed, 8 Nov 2023 at 07:49, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > > > > > >
> > > > > > > > On Tue, Nov 07, 2023 at 03:18:09PM +0200, Dmitry Baryshkov wrote:
> > > > > > > > > On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
> > > > > > > > > >
> > > > > > > > > > From: Can Guo <quic_cang@quicinc.com>
> > > > > > > > > >
> > > > > > > > > > On SM8550, two sets of UFS PHY settings are provided, one set is to support
> > > > > > > > > > HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
> > > > > > > > > > settings are programming different values to different registers, mixing
> > > > > > > > > > the two sets and/or overwriting one set with another set is definitely not
> > > > > > > > > > blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
> > > > > > > > > > need to split the two sets into their dedicated tables, and leave only the
> > > > > > > > > > common settings in the .tlbs. To have the PHY programmed with the correct
> > > > > > > > > > set of PHY settings, the submode passed to PHY driver must be either HS-G4
> > > > > > > > > > or HS-G5.
> > > > > > > > > >
> > > > > > > >
> > > > > > > > You should also mention that this issue is also present in G4 supported targets.
> > > > > > > > And a note that it will get fixed later.
> > > > > > > >
> > > > > > > > > > Signed-off-by: Can Guo <quic_cang@quicinc.com>
> > > > > > > > > > ---
> > > > > > > > > >  drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
> > > > > > > > > >  drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
> > > > > > > > > >  .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
> > > > > > > > > >  drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
> > > > > > > > > >  4 files changed, 115 insertions(+), 13 deletions(-)
> > > > > > > > > >
> > > > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > > > > > index c23d5e4..e563af5 100644
> > > > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > > > > > @@ -18,6 +18,7 @@
> > > > > > > > > >  #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
> > > > > > > > > >  #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
> > > > > > > > > >  #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
> > > > > > > > > > +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
> > > > > > > > > >  #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
> > > > > > > > > >  #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
> > > > > > > > > >  #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
> > > > > > > > > > @@ -27,5 +28,6 @@
> > > > > > > > > >  #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
> > > > > > > > > >  #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
> > > > > > > > > >  #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
> > > > > > > > > > +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
> > > > > > > > > >
> > > > > > > > > >  #endif
> > > > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > > > > > index f420f8f..ef392ce 100644
> > > > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > > > > > @@ -56,6 +56,8 @@
> > > > > > > > > >  #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
> > > > > > > > > >  #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
> > > > > > > > > >  #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
> > > > > > > > > > +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
> > > > > > > > > > +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
> > > > > > > > > >  #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
> > > > > > > > > >  #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
> > > > > > > > > >  #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
> > > > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > > > > > index 15bcb4b..48f31c8 100644
> > > > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > > > > > @@ -10,10 +10,20 @@
> > > > > > > > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
> > > > > > > > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
> > > > > > > > > >  #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
> > > > > > > > > > +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
> > > > > > > > > > +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
> > > > > > > > > >
> > > > > > > > > >  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
> > > > > > > > > >  #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
> > > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
> > > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
> > > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
> > > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
> > > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
> > > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
> > > > > > > > > >  #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
> > > > > > > > > > +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
> > > > > > > > > > +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
> > > > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
> > > > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
> > > > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
> > > > > > > > > > @@ -25,6 +35,8 @@
> > > > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
> > > > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
> > > > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
> > > > > > > > > > +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
> > > > > > > > > >  #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
> > > > > > > > > > +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
> > > > > > > > > >
> > > > > > > > > >  #endif
> > > > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > > > > > index 3927eba..e0a01497 100644
> > > > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > > > > > @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
> > > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
> > > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
> > > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
> > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > > > > > > > > +
> > > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
> > > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
> > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
> > > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
> > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
> > > > > > > > > > +};
> > > > > > > > > > +
> > > > > > > > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
> > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
> > > > > > > > > > +};
> > > > > > > > > > +
> > > > > > > > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
> > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > > > > > > > >         QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
> > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
> > > > > > > > >
> > > > > > > > > Aside from moving these registers to the HS_G4 table, you are also
> > > > > > > > > changing these registers. It makes me think that there was an error in
> > > > > > > > > the original programming sequence.
> > > > > > > > > If that is correct, could you please split the patch into two pieces:
> > > > > > > > > - Fix programming sequence (add proper Fixes tags)
> > > > > > > > > - Split G4 and G5 tables.
> > > > > > > >
> > > > > > > > Ack
> > > > > > > >
> > > > > > > > >
> > > > > > > > > > +
> > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
> > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
> > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
> > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
> > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
> > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
> > > > > > > > >
> > > > > > > > > I see all the MODE1 registers being only present in G4 and G5 tables.
> > > > > > > > > Should they be programmed for the modes lower than G4?
> > > > > > > > >
> > > > > > > >
> > > > > > > > We use G4 table for all the modes <= G4.
> > > > > > >
> > > > > > > Could you please point me how it's handled?
> > > > > > > In the patch I see just:
> > > > > > >
> > > > > > >        if (qmp->submode == UFS_HS_G4)
> > > > > > >                qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
> > > > > > >        else if (qmp->submode == UFS_HS_G5)
> > > > > > >                qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
> > > > > > >
> > > > > > > Which looks like two special cases (HS_G4 and HS_G5) and nothing for
> > > > > > > anything else.
> > > > > > >
> > > > > >
> > > > > > Yes, and the UFS driver passes only G4/G5. For all the gears <=G4, G4 init
> > > > > > sequence will be used and for G5, G5 sequence will be used.
> > > > > >
> > > > >
> > > > > That's what I could not find in the UFS driver. I see a call to
> > > > > `phy_set_mode_ext(phy, PHY_MODE_UFS_HS_B, host->phy_gear);` and
> > > > > host->phy_gear is initialised to UFS_HS_G2.
> > > > >
> > > >
> > > > You need to check the UFS driver changes in this series to get the complete
> > > > picture as the logic is getting changed.
> > > >
> > > > It is common to get confused because of the way the UFS driver (qcom mostly)
> > > > handles the PHY init sequence programming. We used to have only one init
> > > > sequence for older targets and life was easy. But when I wanted to add G4
> > > > support for SM8250, I learned that there are 2 separate init sequences. One for
> > > > non-G4 and other for G4. So I used the phy_sub_mode property to pass the
> > > > relevant mode from the UFS driver to the PHY driver and programmed the sequence
> > > > accordingly. This got extended to non-G5 and G5 now.
> > > >
> > > > Now, the UFS driver will start probing from a low gear for older targets (G2)
> > > > and G4/G5 for newer ones then scale up based on the device and host capability.
> > > > For older targets, the common table (tbls) will be used if the submode doesn't
> > > > match G4/G5. But for newer targets, the UFS driver will _only_ pass G4 or G5 as
> > > > the phy_gear, so those specific sequence will only be used.
> > > >
> > > > Hope I'm clear.
> > >
> > > Yes, it is now clear, thank you!
> > >
> > > Would it be possible / feasible / logical to maintain this idea even
> > > for newer platforms (leaving the HS_A  / HS_B aside)?
> > >
> > > tbls - works for HS_G2
> > > tbls + tbls_g4 - works for HS_G4
> > > tbls + tbls_g5 - works for HS_G5
> > >
> >
> > No. The PHY team only gives 2 init sequences for any SoC now.
> 
> Ack. Then the code should become
> if (HS_G5)
>    program(tbls_hs_g5)
> else
>    program(tbls_hs_g4);
> 

This should work. Even if we have to accomodate G6 in the future, we can use
"else if" for that and keep G4 as the "else" condition. This logic can also be
optimized in the future.

- Mani

> >
> > - Mani
> >
> > > I mean here that the PHY driver should not depend on the knowledge
> > > that the UFS driver will not be setting HS_G2 for some particular
> > > platform and ideally it should continue working if at some point we
> > > change the UFS driver to set HS_G2.
> > >
> > >
> > > >
> > > > - Mani
> > > >
> > > > > Maybe we should change the condition here (in the PHY driver) to:
> > > > >
> > > > > if (qmp->submode <= UFS_HS_G4)
> > > > >
> > > > > ?
> > > > > --
> > > > > With best wishes
> > > > > Dmitry
> > > >
> > > > --
> > > > மணிவண்ணன் சதாசிவம்
> > >
> > >
> > >
> > > --
> > > With best wishes
> > > Dmitry
> >
> > --
> > மணிவண்ணன் சதாசிவம்
> 
> 
> 
> -- 
> With best wishes
> Dmitry
Can Guo Nov. 10, 2023, 2:40 p.m. UTC | #19
On 11/10/2023 9:18 PM, Manivannan Sadhasivam wrote:
> On Fri, Nov 10, 2023 at 12:11:46AM +0200, Dmitry Baryshkov wrote:
>> On Thu, 9 Nov 2023 at 18:04, Manivannan Sadhasivam <mani@kernel.org> wrote:
>>>
>>> On Thu, Nov 09, 2023 at 01:00:51PM +0200, Dmitry Baryshkov wrote:
>>>> On Thu, 9 Nov 2023 at 12:43, Manivannan Sadhasivam <mani@kernel.org> wrote:
>>>>>
>>>>> On Thu, Nov 09, 2023 at 11:40:51AM +0200, Dmitry Baryshkov wrote:
>>>>>> On Thu, 9 Nov 2023 at 05:24, Manivannan Sadhasivam <mani@kernel.org> wrote:
>>>>>>>
>>>>>>> On Wed, Nov 08, 2023 at 08:56:16AM +0200, Dmitry Baryshkov wrote:
>>>>>>>> On Wed, 8 Nov 2023 at 07:49, Manivannan Sadhasivam <mani@kernel.org> wrote:
>>>>>>>>>
>>>>>>>>> On Tue, Nov 07, 2023 at 03:18:09PM +0200, Dmitry Baryshkov wrote:
>>>>>>>>>> On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
>>>>>>>>>>>
>>>>>>>>>>> From: Can Guo <quic_cang@quicinc.com>
>>>>>>>>>>>
>>>>>>>>>>> On SM8550, two sets of UFS PHY settings are provided, one set is to support
>>>>>>>>>>> HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
>>>>>>>>>>> settings are programming different values to different registers, mixing
>>>>>>>>>>> the two sets and/or overwriting one set with another set is definitely not
>>>>>>>>>>> blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
>>>>>>>>>>> need to split the two sets into their dedicated tables, and leave only the
>>>>>>>>>>> common settings in the .tlbs. To have the PHY programmed with the correct
>>>>>>>>>>> set of PHY settings, the submode passed to PHY driver must be either HS-G4
>>>>>>>>>>> or HS-G5.
>>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> You should also mention that this issue is also present in G4 supported targets.
>>>>>>>>> And a note that it will get fixed later.
>>>>>>>>>
>>>>>>>>>>> Signed-off-by: Can Guo <quic_cang@quicinc.com>
>>>>>>>>>>> ---
>>>>>>>>>>>   drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
>>>>>>>>>>>   drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
>>>>>>>>>>>   .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
>>>>>>>>>>>   drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
>>>>>>>>>>>   4 files changed, 115 insertions(+), 13 deletions(-)
>>>>>>>>>>>
>>>>>>>>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
>>>>>>>>>>> index c23d5e4..e563af5 100644
>>>>>>>>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
>>>>>>>>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
>>>>>>>>>>> @@ -18,6 +18,7 @@
>>>>>>>>>>>   #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
>>>>>>>>>>>   #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
>>>>>>>>>>>   #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
>>>>>>>>>>> +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
>>>>>>>>>>>   #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
>>>>>>>>>>>   #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
>>>>>>>>>>>   #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
>>>>>>>>>>> @@ -27,5 +28,6 @@
>>>>>>>>>>>   #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
>>>>>>>>>>>   #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
>>>>>>>>>>>   #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
>>>>>>>>>>> +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
>>>>>>>>>>>
>>>>>>>>>>>   #endif
>>>>>>>>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
>>>>>>>>>>> index f420f8f..ef392ce 100644
>>>>>>>>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
>>>>>>>>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
>>>>>>>>>>> @@ -56,6 +56,8 @@
>>>>>>>>>>>   #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
>>>>>>>>>>>   #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
>>>>>>>>>>>   #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
>>>>>>>>>>> +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
>>>>>>>>>>> +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
>>>>>>>>>>>   #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
>>>>>>>>>>>   #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
>>>>>>>>>>>   #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
>>>>>>>>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
>>>>>>>>>>> index 15bcb4b..48f31c8 100644
>>>>>>>>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
>>>>>>>>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
>>>>>>>>>>> @@ -10,10 +10,20 @@
>>>>>>>>>>>   #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
>>>>>>>>>>>   #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
>>>>>>>>>>>   #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
>>>>>>>>>>> +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
>>>>>>>>>>> +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
>>>>>>>>>>>
>>>>>>>>>>>   #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
>>>>>>>>>>>   #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
>>>>>>>>>>>   #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
>>>>>>>>>>>   #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
>>>>>>>>>>>   #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
>>>>>>>>>>>   #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
>>>>>>>>>>> @@ -25,6 +35,8 @@
>>>>>>>>>>>   #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
>>>>>>>>>>>   #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
>>>>>>>>>>>   #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
>>>>>>>>>>>   #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
>>>>>>>>>>>
>>>>>>>>>>>   #endif
>>>>>>>>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>>>>>>>>>>> index 3927eba..e0a01497 100644
>>>>>>>>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>>>>>>>>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>>>>>>>>>>> @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
>>>>>>>>>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
>>>>>>>>>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
>>>>>>>>>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
>>>>>>>>>>> +
>>>>>>>>>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
>>>>>>>>>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
>>>>>>>>>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
>>>>>>>>>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
>>>>>>>>>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
>>>>>>>>>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
>>>>>>>>>>> +};
>>>>>>>>>>> +
>>>>>>>>>>> +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
>>>>>>>>>>> +};
>>>>>>>>>>> +
>>>>>>>>>>> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
>>>>>>>>>>>          QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
>>>>>>>>>>
>>>>>>>>>> Aside from moving these registers to the HS_G4 table, you are also
>>>>>>>>>> changing these registers. It makes me think that there was an error in
>>>>>>>>>> the original programming sequence.
>>>>>>>>>> If that is correct, could you please split the patch into two pieces:
>>>>>>>>>> - Fix programming sequence (add proper Fixes tags)
>>>>>>>>>> - Split G4 and G5 tables.
>>>>>>>>>
>>>>>>>>> Ack
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>> +
>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
>>>>>>>>>>
>>>>>>>>>> I see all the MODE1 registers being only present in G4 and G5 tables.
>>>>>>>>>> Should they be programmed for the modes lower than G4?
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> We use G4 table for all the modes <= G4.
>>>>>>>>
>>>>>>>> Could you please point me how it's handled?
>>>>>>>> In the patch I see just:
>>>>>>>>
>>>>>>>>         if (qmp->submode == UFS_HS_G4)
>>>>>>>>                 qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
>>>>>>>>         else if (qmp->submode == UFS_HS_G5)
>>>>>>>>                 qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
>>>>>>>>
>>>>>>>> Which looks like two special cases (HS_G4 and HS_G5) and nothing for
>>>>>>>> anything else.
>>>>>>>>
>>>>>>>
>>>>>>> Yes, and the UFS driver passes only G4/G5. For all the gears <=G4, G4 init
>>>>>>> sequence will be used and for G5, G5 sequence will be used.
>>>>>>>
>>>>>>
>>>>>> That's what I could not find in the UFS driver. I see a call to
>>>>>> `phy_set_mode_ext(phy, PHY_MODE_UFS_HS_B, host->phy_gear);` and
>>>>>> host->phy_gear is initialised to UFS_HS_G2.
>>>>>>
>>>>>
>>>>> You need to check the UFS driver changes in this series to get the complete
>>>>> picture as the logic is getting changed.
>>>>>
>>>>> It is common to get confused because of the way the UFS driver (qcom mostly)
>>>>> handles the PHY init sequence programming. We used to have only one init
>>>>> sequence for older targets and life was easy. But when I wanted to add G4
>>>>> support for SM8250, I learned that there are 2 separate init sequences. One for
>>>>> non-G4 and other for G4. So I used the phy_sub_mode property to pass the
>>>>> relevant mode from the UFS driver to the PHY driver and programmed the sequence
>>>>> accordingly. This got extended to non-G5 and G5 now.
>>>>>
>>>>> Now, the UFS driver will start probing from a low gear for older targets (G2)
>>>>> and G4/G5 for newer ones then scale up based on the device and host capability.
>>>>> For older targets, the common table (tbls) will be used if the submode doesn't
>>>>> match G4/G5. But for newer targets, the UFS driver will _only_ pass G4 or G5 as
>>>>> the phy_gear, so those specific sequence will only be used.
>>>>>
>>>>> Hope I'm clear.
>>>>
>>>> Yes, it is now clear, thank you!
>>>>
>>>> Would it be possible / feasible / logical to maintain this idea even
>>>> for newer platforms (leaving the HS_A  / HS_B aside)?
>>>>
>>>> tbls - works for HS_G2
>>>> tbls + tbls_g4 - works for HS_G4
>>>> tbls + tbls_g5 - works for HS_G5
>>>>
>>>
>>> No. The PHY team only gives 2 init sequences for any SoC now.
>>
>> Ack. Then the code should become
>> if (HS_G5)
>>     program(tbls_hs_g5)
>> else
>>     program(tbls_hs_g4);
>>
> 
> This should work. Even if we have to accomodate G6 in the future, we can use
> "else if" for that and keep G4 as the "else" condition. This logic can also be
> optimized in the future.

That would make dual init meaningless for old targets. Say on SM8450, 
the initial PHY gear is G2, with the "else" condition, during the first 
init, G4 table would be programmed, then gear negotiation happens btw 
host and device and the negotiated gear is G3 (assume a UFS2.x is 
connected). During the 2nd init, the "else" condition would __again__ 
program the G4 table - it is not programming the non-G4 table for power 
saving. The dual init is supposed to find the optimal PHY settings, but 
the "else" condition is programming G4 table unconditinally.

With the original code change in this patch, the dual init works as it 
is for old targets. say SM8450, the initial PHY gear is G2, during the 
2nd init, it is programming the non-G4 table (assume a UFS2.x is 
connected), but not the G4 table.

Thanks,
Can Guo.
> 
> - Mani
> 
>>>
>>> - Mani
>>>
>>>> I mean here that the PHY driver should not depend on the knowledge
>>>> that the UFS driver will not be setting HS_G2 for some particular
>>>> platform and ideally it should continue working if at some point we
>>>> change the UFS driver to set HS_G2.
>>>>
>>>>
>>>>>
>>>>> - Mani
>>>>>
>>>>>> Maybe we should change the condition here (in the PHY driver) to:
>>>>>>
>>>>>> if (qmp->submode <= UFS_HS_G4)
>>>>>>
>>>>>> ?
>>>>>> --
>>>>>> With best wishes
>>>>>> Dmitry
>>>>>
>>>>> --
>>>>> மணிவண்ணன் சதாசிவம்
>>>>
>>>>
>>>>
>>>> --
>>>> With best wishes
>>>> Dmitry
>>>
>>> --
>>> மணிவண்ணன் சதாசிவம்
>>
>>
>>
>> -- 
>> With best wishes
>> Dmitry
>
Manivannan Sadhasivam Nov. 11, 2023, 4:12 a.m. UTC | #20
On Fri, Nov 10, 2023 at 10:40:53PM +0800, Can Guo wrote:
> 
> 
> On 11/10/2023 9:18 PM, Manivannan Sadhasivam wrote:
> > On Fri, Nov 10, 2023 at 12:11:46AM +0200, Dmitry Baryshkov wrote:
> > > On Thu, 9 Nov 2023 at 18:04, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > > 
> > > > On Thu, Nov 09, 2023 at 01:00:51PM +0200, Dmitry Baryshkov wrote:
> > > > > On Thu, 9 Nov 2023 at 12:43, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > > > > 
> > > > > > On Thu, Nov 09, 2023 at 11:40:51AM +0200, Dmitry Baryshkov wrote:
> > > > > > > On Thu, 9 Nov 2023 at 05:24, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > > > > > > 
> > > > > > > > On Wed, Nov 08, 2023 at 08:56:16AM +0200, Dmitry Baryshkov wrote:
> > > > > > > > > On Wed, 8 Nov 2023 at 07:49, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > > > > > > > > 
> > > > > > > > > > On Tue, Nov 07, 2023 at 03:18:09PM +0200, Dmitry Baryshkov wrote:
> > > > > > > > > > > On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
> > > > > > > > > > > > 
> > > > > > > > > > > > From: Can Guo <quic_cang@quicinc.com>
> > > > > > > > > > > > 
> > > > > > > > > > > > On SM8550, two sets of UFS PHY settings are provided, one set is to support
> > > > > > > > > > > > HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
> > > > > > > > > > > > settings are programming different values to different registers, mixing
> > > > > > > > > > > > the two sets and/or overwriting one set with another set is definitely not
> > > > > > > > > > > > blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
> > > > > > > > > > > > need to split the two sets into their dedicated tables, and leave only the
> > > > > > > > > > > > common settings in the .tlbs. To have the PHY programmed with the correct
> > > > > > > > > > > > set of PHY settings, the submode passed to PHY driver must be either HS-G4
> > > > > > > > > > > > or HS-G5.
> > > > > > > > > > > > 
> > > > > > > > > > 
> > > > > > > > > > You should also mention that this issue is also present in G4 supported targets.
> > > > > > > > > > And a note that it will get fixed later.
> > > > > > > > > > 
> > > > > > > > > > > > Signed-off-by: Can Guo <quic_cang@quicinc.com>
> > > > > > > > > > > > ---
> > > > > > > > > > > >   drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
> > > > > > > > > > > >   drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
> > > > > > > > > > > >   .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
> > > > > > > > > > > >   drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
> > > > > > > > > > > >   4 files changed, 115 insertions(+), 13 deletions(-)
> > > > > > > > > > > > 
> > > > > > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > > > > > > > index c23d5e4..e563af5 100644
> > > > > > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > > > > > > > @@ -18,6 +18,7 @@
> > > > > > > > > > > >   #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
> > > > > > > > > > > >   #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
> > > > > > > > > > > >   #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
> > > > > > > > > > > > +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
> > > > > > > > > > > >   #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
> > > > > > > > > > > >   #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
> > > > > > > > > > > >   #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
> > > > > > > > > > > > @@ -27,5 +28,6 @@
> > > > > > > > > > > >   #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
> > > > > > > > > > > >   #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
> > > > > > > > > > > >   #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
> > > > > > > > > > > > +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
> > > > > > > > > > > > 
> > > > > > > > > > > >   #endif
> > > > > > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > > > > > > > index f420f8f..ef392ce 100644
> > > > > > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > > > > > > > @@ -56,6 +56,8 @@
> > > > > > > > > > > >   #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
> > > > > > > > > > > >   #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
> > > > > > > > > > > >   #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
> > > > > > > > > > > > +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
> > > > > > > > > > > > +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
> > > > > > > > > > > >   #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
> > > > > > > > > > > >   #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
> > > > > > > > > > > >   #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
> > > > > > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > > > > > > > index 15bcb4b..48f31c8 100644
> > > > > > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > > > > > > > @@ -10,10 +10,20 @@
> > > > > > > > > > > >   #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
> > > > > > > > > > > >   #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
> > > > > > > > > > > >   #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
> > > > > > > > > > > > +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
> > > > > > > > > > > > +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
> > > > > > > > > > > > 
> > > > > > > > > > > >   #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
> > > > > > > > > > > >   #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
> > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
> > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
> > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
> > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
> > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
> > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
> > > > > > > > > > > >   #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
> > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
> > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
> > > > > > > > > > > >   #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
> > > > > > > > > > > >   #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
> > > > > > > > > > > >   #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
> > > > > > > > > > > > @@ -25,6 +35,8 @@
> > > > > > > > > > > >   #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
> > > > > > > > > > > >   #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
> > > > > > > > > > > >   #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
> > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
> > > > > > > > > > > >   #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
> > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
> > > > > > > > > > > > 
> > > > > > > > > > > >   #endif
> > > > > > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > > > > > > > index 3927eba..e0a01497 100644
> > > > > > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > > > > > > > @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
> > > > > > > > > > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
> > > > > > > > > > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
> > > > > > > > > > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
> > > > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > > > > > > > > > > +
> > > > > > > > > > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
> > > > > > > > > > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
> > > > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > > > > > > > > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > > > > > > > > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > > > > > > > > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
> > > > > > > > > > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
> > > > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
> > > > > > > > > > > > +};
> > > > > > > > > > > > +
> > > > > > > > > > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
> > > > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
> > > > > > > > > > > > +};
> > > > > > > > > > > > +
> > > > > > > > > > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
> > > > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > > > > > > > > > >          QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
> > > > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
> > > > > > > > > > > 
> > > > > > > > > > > Aside from moving these registers to the HS_G4 table, you are also
> > > > > > > > > > > changing these registers. It makes me think that there was an error in
> > > > > > > > > > > the original programming sequence.
> > > > > > > > > > > If that is correct, could you please split the patch into two pieces:
> > > > > > > > > > > - Fix programming sequence (add proper Fixes tags)
> > > > > > > > > > > - Split G4 and G5 tables.
> > > > > > > > > > 
> > > > > > > > > > Ack
> > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > > +
> > > > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
> > > > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
> > > > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
> > > > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
> > > > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
> > > > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
> > > > > > > > > > > 
> > > > > > > > > > > I see all the MODE1 registers being only present in G4 and G5 tables.
> > > > > > > > > > > Should they be programmed for the modes lower than G4?
> > > > > > > > > > > 
> > > > > > > > > > 
> > > > > > > > > > We use G4 table for all the modes <= G4.
> > > > > > > > > 
> > > > > > > > > Could you please point me how it's handled?
> > > > > > > > > In the patch I see just:
> > > > > > > > > 
> > > > > > > > >         if (qmp->submode == UFS_HS_G4)
> > > > > > > > >                 qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
> > > > > > > > >         else if (qmp->submode == UFS_HS_G5)
> > > > > > > > >                 qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
> > > > > > > > > 
> > > > > > > > > Which looks like two special cases (HS_G4 and HS_G5) and nothing for
> > > > > > > > > anything else.
> > > > > > > > > 
> > > > > > > > 
> > > > > > > > Yes, and the UFS driver passes only G4/G5. For all the gears <=G4, G4 init
> > > > > > > > sequence will be used and for G5, G5 sequence will be used.
> > > > > > > > 
> > > > > > > 
> > > > > > > That's what I could not find in the UFS driver. I see a call to
> > > > > > > `phy_set_mode_ext(phy, PHY_MODE_UFS_HS_B, host->phy_gear);` and
> > > > > > > host->phy_gear is initialised to UFS_HS_G2.
> > > > > > > 
> > > > > > 
> > > > > > You need to check the UFS driver changes in this series to get the complete
> > > > > > picture as the logic is getting changed.
> > > > > > 
> > > > > > It is common to get confused because of the way the UFS driver (qcom mostly)
> > > > > > handles the PHY init sequence programming. We used to have only one init
> > > > > > sequence for older targets and life was easy. But when I wanted to add G4
> > > > > > support for SM8250, I learned that there are 2 separate init sequences. One for
> > > > > > non-G4 and other for G4. So I used the phy_sub_mode property to pass the
> > > > > > relevant mode from the UFS driver to the PHY driver and programmed the sequence
> > > > > > accordingly. This got extended to non-G5 and G5 now.
> > > > > > 
> > > > > > Now, the UFS driver will start probing from a low gear for older targets (G2)
> > > > > > and G4/G5 for newer ones then scale up based on the device and host capability.
> > > > > > For older targets, the common table (tbls) will be used if the submode doesn't
> > > > > > match G4/G5. But for newer targets, the UFS driver will _only_ pass G4 or G5 as
> > > > > > the phy_gear, so those specific sequence will only be used.
> > > > > > 
> > > > > > Hope I'm clear.
> > > > > 
> > > > > Yes, it is now clear, thank you!
> > > > > 
> > > > > Would it be possible / feasible / logical to maintain this idea even
> > > > > for newer platforms (leaving the HS_A  / HS_B aside)?
> > > > > 
> > > > > tbls - works for HS_G2
> > > > > tbls + tbls_g4 - works for HS_G4
> > > > > tbls + tbls_g5 - works for HS_G5
> > > > > 
> > > > 
> > > > No. The PHY team only gives 2 init sequences for any SoC now.
> > > 
> > > Ack. Then the code should become
> > > if (HS_G5)
> > >     program(tbls_hs_g5)
> > > else
> > >     program(tbls_hs_g4);
> > > 
> > 
> > This should work. Even if we have to accomodate G6 in the future, we can use
> > "else if" for that and keep G4 as the "else" condition. This logic can also be
> > optimized in the future.
> 
> That would make dual init meaningless for old targets. Say on SM8450, the
> initial PHY gear is G2, with the "else" condition, during the first init, G4
> table would be programmed, then gear negotiation happens btw host and device
> and the negotiated gear is G3 (assume a UFS2.x is connected). During the 2nd
> init, the "else" condition would __again__ program the G4 table - it is not
> programming the non-G4 table for power saving. The dual init is supposed to
> find the optimal PHY settings, but the "else" condition is programming G4
> table unconditinally.
> 
> With the original code change in this patch, the dual init works as it is
> for old targets. say SM8450, the initial PHY gear is G2, during the 2nd
> init, it is programming the non-G4 table (assume a UFS2.x is connected), but
> not the G4 table.
> 

You are right. I completely overlooked the compatibility for old targets. But
still we can move the common table to the "else" condition. This makes it clear
that one of the 3 will be programmed at a time. But with the current logic, I
get the impression that common table is overridden by G4/G5 tables.

So this is what I'm suggesting:

if (HS_G5)
	program(tbls_hs_g5)
else if (HS_G4)
	program(tbls_hs_g4);
else
	program(tbls_hs_common);

- Mani

> Thanks,
> Can Guo.
> > 
> > - Mani
> > 
> > > > 
> > > > - Mani
> > > > 
> > > > > I mean here that the PHY driver should not depend on the knowledge
> > > > > that the UFS driver will not be setting HS_G2 for some particular
> > > > > platform and ideally it should continue working if at some point we
> > > > > change the UFS driver to set HS_G2.
> > > > > 
> > > > > 
> > > > > > 
> > > > > > - Mani
> > > > > > 
> > > > > > > Maybe we should change the condition here (in the PHY driver) to:
> > > > > > > 
> > > > > > > if (qmp->submode <= UFS_HS_G4)
> > > > > > > 
> > > > > > > ?
> > > > > > > --
> > > > > > > With best wishes
> > > > > > > Dmitry
> > > > > > 
> > > > > > --
> > > > > > மணிவண்ணன் சதாசிவம்
> > > > > 
> > > > > 
> > > > > 
> > > > > --
> > > > > With best wishes
> > > > > Dmitry
> > > > 
> > > > --
> > > > மணிவண்ணன் சதாசிவம்
> > > 
> > > 
> > > 
> > > -- 
> > > With best wishes
> > > Dmitry
> >
Can Guo Nov. 12, 2023, 5:13 a.m. UTC | #21
Hi Mani,

On 11/11/2023 12:12 PM, Manivannan Sadhasivam wrote:
> On Fri, Nov 10, 2023 at 10:40:53PM +0800, Can Guo wrote:
>>
>>
>> On 11/10/2023 9:18 PM, Manivannan Sadhasivam wrote:
>>> On Fri, Nov 10, 2023 at 12:11:46AM +0200, Dmitry Baryshkov wrote:
>>>> On Thu, 9 Nov 2023 at 18:04, Manivannan Sadhasivam <mani@kernel.org> wrote:
>>>>>
>>>>> On Thu, Nov 09, 2023 at 01:00:51PM +0200, Dmitry Baryshkov wrote:
>>>>>> On Thu, 9 Nov 2023 at 12:43, Manivannan Sadhasivam <mani@kernel.org> wrote:
>>>>>>>
>>>>>>> On Thu, Nov 09, 2023 at 11:40:51AM +0200, Dmitry Baryshkov wrote:
>>>>>>>> On Thu, 9 Nov 2023 at 05:24, Manivannan Sadhasivam <mani@kernel.org> wrote:
>>>>>>>>>
>>>>>>>>> On Wed, Nov 08, 2023 at 08:56:16AM +0200, Dmitry Baryshkov wrote:
>>>>>>>>>> On Wed, 8 Nov 2023 at 07:49, Manivannan Sadhasivam <mani@kernel.org> wrote:
>>>>>>>>>>>
>>>>>>>>>>> On Tue, Nov 07, 2023 at 03:18:09PM +0200, Dmitry Baryshkov wrote:
>>>>>>>>>>>> On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>> From: Can Guo <quic_cang@quicinc.com>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On SM8550, two sets of UFS PHY settings are provided, one set is to support
>>>>>>>>>>>>> HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
>>>>>>>>>>>>> settings are programming different values to different registers, mixing
>>>>>>>>>>>>> the two sets and/or overwriting one set with another set is definitely not
>>>>>>>>>>>>> blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
>>>>>>>>>>>>> need to split the two sets into their dedicated tables, and leave only the
>>>>>>>>>>>>> common settings in the .tlbs. To have the PHY programmed with the correct
>>>>>>>>>>>>> set of PHY settings, the submode passed to PHY driver must be either HS-G4
>>>>>>>>>>>>> or HS-G5.
>>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> You should also mention that this issue is also present in G4 supported targets.
>>>>>>>>>>> And a note that it will get fixed later.
>>>>>>>>>>>
>>>>>>>>>>>>> Signed-off-by: Can Guo <quic_cang@quicinc.com>
>>>>>>>>>>>>> ---
>>>>>>>>>>>>>    drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
>>>>>>>>>>>>>    drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
>>>>>>>>>>>>>    .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
>>>>>>>>>>>>>    drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
>>>>>>>>>>>>>    4 files changed, 115 insertions(+), 13 deletions(-)
>>>>>>>>>>>>>
>>>>>>>>>>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
>>>>>>>>>>>>> index c23d5e4..e563af5 100644
>>>>>>>>>>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
>>>>>>>>>>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
>>>>>>>>>>>>> @@ -18,6 +18,7 @@
>>>>>>>>>>>>>    #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
>>>>>>>>>>>>>    #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
>>>>>>>>>>>>>    #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
>>>>>>>>>>>>> +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
>>>>>>>>>>>>>    #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
>>>>>>>>>>>>>    #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
>>>>>>>>>>>>>    #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
>>>>>>>>>>>>> @@ -27,5 +28,6 @@
>>>>>>>>>>>>>    #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
>>>>>>>>>>>>>    #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
>>>>>>>>>>>>>    #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
>>>>>>>>>>>>> +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
>>>>>>>>>>>>>
>>>>>>>>>>>>>    #endif
>>>>>>>>>>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
>>>>>>>>>>>>> index f420f8f..ef392ce 100644
>>>>>>>>>>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
>>>>>>>>>>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
>>>>>>>>>>>>> @@ -56,6 +56,8 @@
>>>>>>>>>>>>>    #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
>>>>>>>>>>>>>    #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
>>>>>>>>>>>>>    #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
>>>>>>>>>>>>> +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
>>>>>>>>>>>>> +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
>>>>>>>>>>>>>    #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
>>>>>>>>>>>>>    #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
>>>>>>>>>>>>>    #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
>>>>>>>>>>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
>>>>>>>>>>>>> index 15bcb4b..48f31c8 100644
>>>>>>>>>>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
>>>>>>>>>>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
>>>>>>>>>>>>> @@ -10,10 +10,20 @@
>>>>>>>>>>>>>    #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
>>>>>>>>>>>>>    #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
>>>>>>>>>>>>>    #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
>>>>>>>>>>>>> +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
>>>>>>>>>>>>> +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
>>>>>>>>>>>>>
>>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
>>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
>>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
>>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
>>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
>>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
>>>>>>>>>>>>> @@ -25,6 +35,8 @@
>>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
>>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
>>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
>>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
>>>>>>>>>>>>>
>>>>>>>>>>>>>    #endif
>>>>>>>>>>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>>>>>>>>>>>>> index 3927eba..e0a01497 100644
>>>>>>>>>>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>>>>>>>>>>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>>>>>>>>>>>>> @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
>>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
>>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
>>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
>>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
>>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
>>>>>>>>>>>>> +
>>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
>>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
>>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
>>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
>>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
>>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
>>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
>>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
>>>>>>>>>>>>> +};
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
>>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
>>>>>>>>>>>>> +};
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
>>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
>>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
>>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
>>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
>>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
>>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
>>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
>>>>>>>>>>>>
>>>>>>>>>>>> Aside from moving these registers to the HS_G4 table, you are also
>>>>>>>>>>>> changing these registers. It makes me think that there was an error in
>>>>>>>>>>>> the original programming sequence.
>>>>>>>>>>>> If that is correct, could you please split the patch into two pieces:
>>>>>>>>>>>> - Fix programming sequence (add proper Fixes tags)
>>>>>>>>>>>> - Split G4 and G5 tables.
>>>>>>>>>>>
>>>>>>>>>>> Ack
>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>> +
>>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
>>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
>>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
>>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
>>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
>>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
>>>>>>>>>>>>
>>>>>>>>>>>> I see all the MODE1 registers being only present in G4 and G5 tables.
>>>>>>>>>>>> Should they be programmed for the modes lower than G4?
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> We use G4 table for all the modes <= G4.
>>>>>>>>>>
>>>>>>>>>> Could you please point me how it's handled?
>>>>>>>>>> In the patch I see just:
>>>>>>>>>>
>>>>>>>>>>          if (qmp->submode == UFS_HS_G4)
>>>>>>>>>>                  qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
>>>>>>>>>>          else if (qmp->submode == UFS_HS_G5)
>>>>>>>>>>                  qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
>>>>>>>>>>
>>>>>>>>>> Which looks like two special cases (HS_G4 and HS_G5) and nothing for
>>>>>>>>>> anything else.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Yes, and the UFS driver passes only G4/G5. For all the gears <=G4, G4 init
>>>>>>>>> sequence will be used and for G5, G5 sequence will be used.
>>>>>>>>>
>>>>>>>>
>>>>>>>> That's what I could not find in the UFS driver. I see a call to
>>>>>>>> `phy_set_mode_ext(phy, PHY_MODE_UFS_HS_B, host->phy_gear);` and
>>>>>>>> host->phy_gear is initialised to UFS_HS_G2.
>>>>>>>>
>>>>>>>
>>>>>>> You need to check the UFS driver changes in this series to get the complete
>>>>>>> picture as the logic is getting changed.
>>>>>>>
>>>>>>> It is common to get confused because of the way the UFS driver (qcom mostly)
>>>>>>> handles the PHY init sequence programming. We used to have only one init
>>>>>>> sequence for older targets and life was easy. But when I wanted to add G4
>>>>>>> support for SM8250, I learned that there are 2 separate init sequences. One for
>>>>>>> non-G4 and other for G4. So I used the phy_sub_mode property to pass the
>>>>>>> relevant mode from the UFS driver to the PHY driver and programmed the sequence
>>>>>>> accordingly. This got extended to non-G5 and G5 now.
>>>>>>>
>>>>>>> Now, the UFS driver will start probing from a low gear for older targets (G2)
>>>>>>> and G4/G5 for newer ones then scale up based on the device and host capability.
>>>>>>> For older targets, the common table (tbls) will be used if the submode doesn't
>>>>>>> match G4/G5. But for newer targets, the UFS driver will _only_ pass G4 or G5 as
>>>>>>> the phy_gear, so those specific sequence will only be used.
>>>>>>>
>>>>>>> Hope I'm clear.
>>>>>>
>>>>>> Yes, it is now clear, thank you!
>>>>>>
>>>>>> Would it be possible / feasible / logical to maintain this idea even
>>>>>> for newer platforms (leaving the HS_A  / HS_B aside)?
>>>>>>
>>>>>> tbls - works for HS_G2
>>>>>> tbls + tbls_g4 - works for HS_G4
>>>>>> tbls + tbls_g5 - works for HS_G5
>>>>>>
>>>>>
>>>>> No. The PHY team only gives 2 init sequences for any SoC now.
>>>>
>>>> Ack. Then the code should become
>>>> if (HS_G5)
>>>>      program(tbls_hs_g5)
>>>> else
>>>>      program(tbls_hs_g4);
>>>>
>>>
>>> This should work. Even if we have to accomodate G6 in the future, we can use
>>> "else if" for that and keep G4 as the "else" condition. This logic can also be
>>> optimized in the future.
>>
>> That would make dual init meaningless for old targets. Say on SM8450, the
>> initial PHY gear is G2, with the "else" condition, during the first init, G4
>> table would be programmed, then gear negotiation happens btw host and device
>> and the negotiated gear is G3 (assume a UFS2.x is connected). During the 2nd
>> init, the "else" condition would __again__ program the G4 table - it is not
>> programming the non-G4 table for power saving. The dual init is supposed to
>> find the optimal PHY settings, but the "else" condition is programming G4
>> table unconditinally.
>>
>> With the original code change in this patch, the dual init works as it is
>> for old targets. say SM8450, the initial PHY gear is G2, during the 2nd
>> init, it is programming the non-G4 table (assume a UFS2.x is connected), but
>> not the G4 table.
>>
> 
> You are right. I completely overlooked the compatibility for old targets. But
> still we can move the common table to the "else" condition. This makes it clear
> that one of the 3 will be programmed at a time. But with the current logic, I
> get the impression that common table is overridden by G4/G5 tables.
> 
> So this is what I'm suggesting:
> 
> if (HS_G5)
> 	program(tbls_hs_g5)
> else if (HS_G4)
> 	program(tbls_hs_g4);
> else
> 	program(tbls_hs_common);
> 

Common table is needed regardlessly, we cannot put it in "else", 
otherwise it would break all targets -

On old targets (no G5 supported):
Common table 		- supports non-G4 (G3 and lower)
Common table + G4 table - supports G4

On new targets (G5 supported):
Common table 		- supports nothing, as it is just common parts of G4 
table and G5 table.
Common table + G4 table - support non-G5 (G4 and lower)
Common table + G5 table - support G5

Thanks,
Can Guo.

> - Mani
> 
>> Thanks,
>> Can Guo.
>>>
>>> - Mani
>>>
>>>>>
>>>>> - Mani
>>>>>
>>>>>> I mean here that the PHY driver should not depend on the knowledge
>>>>>> that the UFS driver will not be setting HS_G2 for some particular
>>>>>> platform and ideally it should continue working if at some point we
>>>>>> change the UFS driver to set HS_G2.
>>>>>>
>>>>>>
>>>>>>>
>>>>>>> - Mani
>>>>>>>
>>>>>>>> Maybe we should change the condition here (in the PHY driver) to:
>>>>>>>>
>>>>>>>> if (qmp->submode <= UFS_HS_G4)
>>>>>>>>
>>>>>>>> ?
>>>>>>>> --
>>>>>>>> With best wishes
>>>>>>>> Dmitry
>>>>>>>
>>>>>>> --
>>>>>>> மணிவண்ணன் சதாசிவம்
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> With best wishes
>>>>>> Dmitry
>>>>>
>>>>> --
>>>>> மணிவண்ணன் சதாசிவம்
>>>>
>>>>
>>>>
>>>> -- 
>>>> With best wishes
>>>> Dmitry
>>>
>
Manivannan Sadhasivam Nov. 14, 2023, 6:12 a.m. UTC | #22
On Sun, Nov 12, 2023 at 01:13:30PM +0800, Can Guo wrote:
> Hi Mani,
> 
> On 11/11/2023 12:12 PM, Manivannan Sadhasivam wrote:
> > On Fri, Nov 10, 2023 at 10:40:53PM +0800, Can Guo wrote:
> > > 
> > > 
> > > On 11/10/2023 9:18 PM, Manivannan Sadhasivam wrote:
> > > > On Fri, Nov 10, 2023 at 12:11:46AM +0200, Dmitry Baryshkov wrote:
> > > > > On Thu, 9 Nov 2023 at 18:04, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > > > > 
> > > > > > On Thu, Nov 09, 2023 at 01:00:51PM +0200, Dmitry Baryshkov wrote:
> > > > > > > On Thu, 9 Nov 2023 at 12:43, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > > > > > > 
> > > > > > > > On Thu, Nov 09, 2023 at 11:40:51AM +0200, Dmitry Baryshkov wrote:
> > > > > > > > > On Thu, 9 Nov 2023 at 05:24, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > > > > > > > > 
> > > > > > > > > > On Wed, Nov 08, 2023 at 08:56:16AM +0200, Dmitry Baryshkov wrote:
> > > > > > > > > > > On Wed, 8 Nov 2023 at 07:49, Manivannan Sadhasivam <mani@kernel.org> wrote:
> > > > > > > > > > > > 
> > > > > > > > > > > > On Tue, Nov 07, 2023 at 03:18:09PM +0200, Dmitry Baryshkov wrote:
> > > > > > > > > > > > > On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > From: Can Guo <quic_cang@quicinc.com>
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > On SM8550, two sets of UFS PHY settings are provided, one set is to support
> > > > > > > > > > > > > > HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
> > > > > > > > > > > > > > settings are programming different values to different registers, mixing
> > > > > > > > > > > > > > the two sets and/or overwriting one set with another set is definitely not
> > > > > > > > > > > > > > blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
> > > > > > > > > > > > > > need to split the two sets into their dedicated tables, and leave only the
> > > > > > > > > > > > > > common settings in the .tlbs. To have the PHY programmed with the correct
> > > > > > > > > > > > > > set of PHY settings, the submode passed to PHY driver must be either HS-G4
> > > > > > > > > > > > > > or HS-G5.
> > > > > > > > > > > > > > 
> > > > > > > > > > > > 
> > > > > > > > > > > > You should also mention that this issue is also present in G4 supported targets.
> > > > > > > > > > > > And a note that it will get fixed later.
> > > > > > > > > > > > 
> > > > > > > > > > > > > > Signed-off-by: Can Guo <quic_cang@quicinc.com>
> > > > > > > > > > > > > > ---
> > > > > > > > > > > > > >    drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
> > > > > > > > > > > > > >    drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
> > > > > > > > > > > > > >    .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
> > > > > > > > > > > > > >    drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
> > > > > > > > > > > > > >    4 files changed, 115 insertions(+), 13 deletions(-)
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > > > > > > > > > index c23d5e4..e563af5 100644
> > > > > > > > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > > > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> > > > > > > > > > > > > > @@ -18,6 +18,7 @@
> > > > > > > > > > > > > >    #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
> > > > > > > > > > > > > >    #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
> > > > > > > > > > > > > >    #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
> > > > > > > > > > > > > > +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
> > > > > > > > > > > > > >    #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
> > > > > > > > > > > > > >    #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
> > > > > > > > > > > > > >    #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
> > > > > > > > > > > > > > @@ -27,5 +28,6 @@
> > > > > > > > > > > > > >    #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
> > > > > > > > > > > > > >    #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
> > > > > > > > > > > > > >    #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
> > > > > > > > > > > > > > +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > >    #endif
> > > > > > > > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > > > > > > > > > index f420f8f..ef392ce 100644
> > > > > > > > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > > > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> > > > > > > > > > > > > > @@ -56,6 +56,8 @@
> > > > > > > > > > > > > >    #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
> > > > > > > > > > > > > >    #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
> > > > > > > > > > > > > >    #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
> > > > > > > > > > > > > > +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
> > > > > > > > > > > > > > +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
> > > > > > > > > > > > > >    #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
> > > > > > > > > > > > > >    #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
> > > > > > > > > > > > > >    #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
> > > > > > > > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > > > > > > > > > index 15bcb4b..48f31c8 100644
> > > > > > > > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > > > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> > > > > > > > > > > > > > @@ -10,10 +10,20 @@
> > > > > > > > > > > > > >    #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
> > > > > > > > > > > > > >    #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
> > > > > > > > > > > > > >    #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
> > > > > > > > > > > > > > +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
> > > > > > > > > > > > > > +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > >    #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
> > > > > > > > > > > > > >    #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
> > > > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
> > > > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
> > > > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
> > > > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
> > > > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
> > > > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
> > > > > > > > > > > > > >    #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
> > > > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
> > > > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
> > > > > > > > > > > > > >    #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
> > > > > > > > > > > > > >    #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
> > > > > > > > > > > > > >    #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
> > > > > > > > > > > > > > @@ -25,6 +35,8 @@
> > > > > > > > > > > > > >    #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
> > > > > > > > > > > > > >    #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
> > > > > > > > > > > > > >    #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
> > > > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
> > > > > > > > > > > > > >    #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
> > > > > > > > > > > > > > +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > >    #endif
> > > > > > > > > > > > > > diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > > > > > > > > > index 3927eba..e0a01497 100644
> > > > > > > > > > > > > > --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > > > > > > > > > +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> > > > > > > > > > > > > > @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
> > > > > > > > > > > > > >           QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
> > > > > > > > > > > > > >           QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
> > > > > > > > > > > > > >           QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
> > > > > > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > > > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > > > > > > > > > > > > +
> > > > > > > > > > > > > >           QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
> > > > > > > > > > > > > >           QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
> > > > > > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > > > > > > > > > > > >           QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > > > > > > > > > > > >           QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > > > > > > > > > > > >           QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
> > > > > > > > > > > > > >           QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
> > > > > > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
> > > > > > > > > > > > > > +};
> > > > > > > > > > > > > > +
> > > > > > > > > > > > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
> > > > > > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
> > > > > > > > > > > > > > +};
> > > > > > > > > > > > > > +
> > > > > > > > > > > > > > +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
> > > > > > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> > > > > > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> > > > > > > > > > > > > >           QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> > > > > > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> > > > > > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> > > > > > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
> > > > > > > > > > > > > > -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
> > > > > > > > > > > > > 
> > > > > > > > > > > > > Aside from moving these registers to the HS_G4 table, you are also
> > > > > > > > > > > > > changing these registers. It makes me think that there was an error in
> > > > > > > > > > > > > the original programming sequence.
> > > > > > > > > > > > > If that is correct, could you please split the patch into two pieces:
> > > > > > > > > > > > > - Fix programming sequence (add proper Fixes tags)
> > > > > > > > > > > > > - Split G4 and G5 tables.
> > > > > > > > > > > > 
> > > > > > > > > > > > Ack
> > > > > > > > > > > > 
> > > > > > > > > > > > > 
> > > > > > > > > > > > > > +
> > > > > > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
> > > > > > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
> > > > > > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
> > > > > > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
> > > > > > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
> > > > > > > > > > > > > > +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
> > > > > > > > > > > > > 
> > > > > > > > > > > > > I see all the MODE1 registers being only present in G4 and G5 tables.
> > > > > > > > > > > > > Should they be programmed for the modes lower than G4?
> > > > > > > > > > > > > 
> > > > > > > > > > > > 
> > > > > > > > > > > > We use G4 table for all the modes <= G4.
> > > > > > > > > > > 
> > > > > > > > > > > Could you please point me how it's handled?
> > > > > > > > > > > In the patch I see just:
> > > > > > > > > > > 
> > > > > > > > > > >          if (qmp->submode == UFS_HS_G4)
> > > > > > > > > > >                  qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
> > > > > > > > > > >          else if (qmp->submode == UFS_HS_G5)
> > > > > > > > > > >                  qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
> > > > > > > > > > > 
> > > > > > > > > > > Which looks like two special cases (HS_G4 and HS_G5) and nothing for
> > > > > > > > > > > anything else.
> > > > > > > > > > > 
> > > > > > > > > > 
> > > > > > > > > > Yes, and the UFS driver passes only G4/G5. For all the gears <=G4, G4 init
> > > > > > > > > > sequence will be used and for G5, G5 sequence will be used.
> > > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > That's what I could not find in the UFS driver. I see a call to
> > > > > > > > > `phy_set_mode_ext(phy, PHY_MODE_UFS_HS_B, host->phy_gear);` and
> > > > > > > > > host->phy_gear is initialised to UFS_HS_G2.
> > > > > > > > > 
> > > > > > > > 
> > > > > > > > You need to check the UFS driver changes in this series to get the complete
> > > > > > > > picture as the logic is getting changed.
> > > > > > > > 
> > > > > > > > It is common to get confused because of the way the UFS driver (qcom mostly)
> > > > > > > > handles the PHY init sequence programming. We used to have only one init
> > > > > > > > sequence for older targets and life was easy. But when I wanted to add G4
> > > > > > > > support for SM8250, I learned that there are 2 separate init sequences. One for
> > > > > > > > non-G4 and other for G4. So I used the phy_sub_mode property to pass the
> > > > > > > > relevant mode from the UFS driver to the PHY driver and programmed the sequence
> > > > > > > > accordingly. This got extended to non-G5 and G5 now.
> > > > > > > > 
> > > > > > > > Now, the UFS driver will start probing from a low gear for older targets (G2)
> > > > > > > > and G4/G5 for newer ones then scale up based on the device and host capability.
> > > > > > > > For older targets, the common table (tbls) will be used if the submode doesn't
> > > > > > > > match G4/G5. But for newer targets, the UFS driver will _only_ pass G4 or G5 as
> > > > > > > > the phy_gear, so those specific sequence will only be used.
> > > > > > > > 
> > > > > > > > Hope I'm clear.
> > > > > > > 
> > > > > > > Yes, it is now clear, thank you!
> > > > > > > 
> > > > > > > Would it be possible / feasible / logical to maintain this idea even
> > > > > > > for newer platforms (leaving the HS_A  / HS_B aside)?
> > > > > > > 
> > > > > > > tbls - works for HS_G2
> > > > > > > tbls + tbls_g4 - works for HS_G4
> > > > > > > tbls + tbls_g5 - works for HS_G5
> > > > > > > 
> > > > > > 
> > > > > > No. The PHY team only gives 2 init sequences for any SoC now.
> > > > > 
> > > > > Ack. Then the code should become
> > > > > if (HS_G5)
> > > > >      program(tbls_hs_g5)
> > > > > else
> > > > >      program(tbls_hs_g4);
> > > > > 
> > > > 
> > > > This should work. Even if we have to accomodate G6 in the future, we can use
> > > > "else if" for that and keep G4 as the "else" condition. This logic can also be
> > > > optimized in the future.
> > > 
> > > That would make dual init meaningless for old targets. Say on SM8450, the
> > > initial PHY gear is G2, with the "else" condition, during the first init, G4
> > > table would be programmed, then gear negotiation happens btw host and device
> > > and the negotiated gear is G3 (assume a UFS2.x is connected). During the 2nd
> > > init, the "else" condition would __again__ program the G4 table - it is not
> > > programming the non-G4 table for power saving. The dual init is supposed to
> > > find the optimal PHY settings, but the "else" condition is programming G4
> > > table unconditinally.
> > > 
> > > With the original code change in this patch, the dual init works as it is
> > > for old targets. say SM8450, the initial PHY gear is G2, during the 2nd
> > > init, it is programming the non-G4 table (assume a UFS2.x is connected), but
> > > not the G4 table.
> > > 
> > 
> > You are right. I completely overlooked the compatibility for old targets. But
> > still we can move the common table to the "else" condition. This makes it clear
> > that one of the 3 will be programmed at a time. But with the current logic, I
> > get the impression that common table is overridden by G4/G5 tables.
> > 
> > So this is what I'm suggesting:
> > 
> > if (HS_G5)
> > 	program(tbls_hs_g5)
> > else if (HS_G4)
> > 	program(tbls_hs_g4);
> > else
> > 	program(tbls_hs_common);
> > 
> 
> Common table is needed regardlessly, we cannot put it in "else", otherwise
> it would break all targets -
> 
> On old targets (no G5 supported):
> Common table 		- supports non-G4 (G3 and lower)
> Common table + G4 table - supports G4
> 
> On new targets (G5 supported):
> Common table 		- supports nothing, as it is just common parts of G4 table
> and G5 table.
> Common table + G4 table - support non-G5 (G4 and lower)
> Common table + G5 table - support G5
> 

Doh! I missed the fact that common table is not a standalone table. Sorry for
the confusion. Let's keep it as you proposed for now. I still don't like the if
conditions as it would just keep growing with future gears, but we can get to it
later.

- Mani

> Thanks,
> Can Guo.
> 
> > - Mani
> > 
> > > Thanks,
> > > Can Guo.
> > > > 
> > > > - Mani
> > > > 
> > > > > > 
> > > > > > - Mani
> > > > > > 
> > > > > > > I mean here that the PHY driver should not depend on the knowledge
> > > > > > > that the UFS driver will not be setting HS_G2 for some particular
> > > > > > > platform and ideally it should continue working if at some point we
> > > > > > > change the UFS driver to set HS_G2.
> > > > > > > 
> > > > > > > 
> > > > > > > > 
> > > > > > > > - Mani
> > > > > > > > 
> > > > > > > > > Maybe we should change the condition here (in the PHY driver) to:
> > > > > > > > > 
> > > > > > > > > if (qmp->submode <= UFS_HS_G4)
> > > > > > > > > 
> > > > > > > > > ?
> > > > > > > > > --
> > > > > > > > > With best wishes
> > > > > > > > > Dmitry
> > > > > > > > 
> > > > > > > > --
> > > > > > > > மணிவண்ணன் சதாசிவம்
> > > > > > > 
> > > > > > > 
> > > > > > > 
> > > > > > > --
> > > > > > > With best wishes
> > > > > > > Dmitry
> > > > > > 
> > > > > > --
> > > > > > மணிவண்ணன் சதாசிவம்
> > > > > 
> > > > > 
> > > > > 
> > > > > -- 
> > > > > With best wishes
> > > > > Dmitry
> > > > 
> >
Dmitry Baryshkov Nov. 14, 2023, 9:15 a.m. UTC | #23
On Sun, 12 Nov 2023 at 07:13, Can Guo <quic_cang@quicinc.com> wrote:
>
> Hi Mani,
>
> On 11/11/2023 12:12 PM, Manivannan Sadhasivam wrote:
> > On Fri, Nov 10, 2023 at 10:40:53PM +0800, Can Guo wrote:
> >>
> >>
> >> On 11/10/2023 9:18 PM, Manivannan Sadhasivam wrote:
> >>> On Fri, Nov 10, 2023 at 12:11:46AM +0200, Dmitry Baryshkov wrote:
> >>>> On Thu, 9 Nov 2023 at 18:04, Manivannan Sadhasivam <mani@kernel.org> wrote:
> >>>>>
> >>>>> On Thu, Nov 09, 2023 at 01:00:51PM +0200, Dmitry Baryshkov wrote:
> >>>>>> On Thu, 9 Nov 2023 at 12:43, Manivannan Sadhasivam <mani@kernel.org> wrote:
> >>>>>>>
> >>>>>>> On Thu, Nov 09, 2023 at 11:40:51AM +0200, Dmitry Baryshkov wrote:
> >>>>>>>> On Thu, 9 Nov 2023 at 05:24, Manivannan Sadhasivam <mani@kernel.org> wrote:
> >>>>>>>>>
> >>>>>>>>> On Wed, Nov 08, 2023 at 08:56:16AM +0200, Dmitry Baryshkov wrote:
> >>>>>>>>>> On Wed, 8 Nov 2023 at 07:49, Manivannan Sadhasivam <mani@kernel.org> wrote:
> >>>>>>>>>>>
> >>>>>>>>>>> On Tue, Nov 07, 2023 at 03:18:09PM +0200, Dmitry Baryshkov wrote:
> >>>>>>>>>>>> On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> From: Can Guo <quic_cang@quicinc.com>
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> On SM8550, two sets of UFS PHY settings are provided, one set is to support
> >>>>>>>>>>>>> HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
> >>>>>>>>>>>>> settings are programming different values to different registers, mixing
> >>>>>>>>>>>>> the two sets and/or overwriting one set with another set is definitely not
> >>>>>>>>>>>>> blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
> >>>>>>>>>>>>> need to split the two sets into their dedicated tables, and leave only the
> >>>>>>>>>>>>> common settings in the .tlbs. To have the PHY programmed with the correct
> >>>>>>>>>>>>> set of PHY settings, the submode passed to PHY driver must be either HS-G4
> >>>>>>>>>>>>> or HS-G5.
> >>>>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>> You should also mention that this issue is also present in G4 supported targets.
> >>>>>>>>>>> And a note that it will get fixed later.
> >>>>>>>>>>>
> >>>>>>>>>>>>> Signed-off-by: Can Guo <quic_cang@quicinc.com>
> >>>>>>>>>>>>> ---
> >>>>>>>>>>>>>    drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
> >>>>>>>>>>>>>    drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
> >>>>>>>>>>>>>    .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
> >>>>>>>>>>>>>    drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
> >>>>>>>>>>>>>    4 files changed, 115 insertions(+), 13 deletions(-)
> >>>>>>>>>>>>>
> >>>>>>>>>>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> >>>>>>>>>>>>> index c23d5e4..e563af5 100644
> >>>>>>>>>>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> >>>>>>>>>>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
> >>>>>>>>>>>>> @@ -18,6 +18,7 @@
> >>>>>>>>>>>>>    #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
> >>>>>>>>>>>>>    #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
> >>>>>>>>>>>>>    #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
> >>>>>>>>>>>>> +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
> >>>>>>>>>>>>>    #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
> >>>>>>>>>>>>>    #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
> >>>>>>>>>>>>>    #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
> >>>>>>>>>>>>> @@ -27,5 +28,6 @@
> >>>>>>>>>>>>>    #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
> >>>>>>>>>>>>>    #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
> >>>>>>>>>>>>>    #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
> >>>>>>>>>>>>> +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>    #endif
> >>>>>>>>>>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> >>>>>>>>>>>>> index f420f8f..ef392ce 100644
> >>>>>>>>>>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> >>>>>>>>>>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
> >>>>>>>>>>>>> @@ -56,6 +56,8 @@
> >>>>>>>>>>>>>    #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
> >>>>>>>>>>>>>    #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
> >>>>>>>>>>>>>    #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
> >>>>>>>>>>>>> +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
> >>>>>>>>>>>>> +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
> >>>>>>>>>>>>>    #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
> >>>>>>>>>>>>>    #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
> >>>>>>>>>>>>>    #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
> >>>>>>>>>>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> >>>>>>>>>>>>> index 15bcb4b..48f31c8 100644
> >>>>>>>>>>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> >>>>>>>>>>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
> >>>>>>>>>>>>> @@ -10,10 +10,20 @@
> >>>>>>>>>>>>>    #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
> >>>>>>>>>>>>>    #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
> >>>>>>>>>>>>>    #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
> >>>>>>>>>>>>> +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
> >>>>>>>>>>>>> +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
> >>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
> >>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
> >>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
> >>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
> >>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
> >>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
> >>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
> >>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
> >>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
> >>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
> >>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
> >>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
> >>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
> >>>>>>>>>>>>> @@ -25,6 +35,8 @@
> >>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
> >>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
> >>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
> >>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
> >>>>>>>>>>>>>    #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
> >>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
> >>>>>>>>>>>>>
> >>>>>>>>>>>>>    #endif
> >>>>>>>>>>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> >>>>>>>>>>>>> index 3927eba..e0a01497 100644
> >>>>>>>>>>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> >>>>>>>>>>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
> >>>>>>>>>>>>> @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
> >>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
> >>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
> >>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
> >>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> >>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> >>>>>>>>>>>>> +
> >>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
> >>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
> >>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> >>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> >>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> >>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
> >>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
> >>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
> >>>>>>>>>>>>> +};
> >>>>>>>>>>>>> +
> >>>>>>>>>>>>> +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
> >>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
> >>>>>>>>>>>>> +};
> >>>>>>>>>>>>> +
> >>>>>>>>>>>>> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
> >>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
> >>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
> >>>>>>>>>>>>>           QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
> >>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
> >>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
> >>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
> >>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
> >>>>>>>>>>>>
> >>>>>>>>>>>> Aside from moving these registers to the HS_G4 table, you are also
> >>>>>>>>>>>> changing these registers. It makes me think that there was an error in
> >>>>>>>>>>>> the original programming sequence.
> >>>>>>>>>>>> If that is correct, could you please split the patch into two pieces:
> >>>>>>>>>>>> - Fix programming sequence (add proper Fixes tags)
> >>>>>>>>>>>> - Split G4 and G5 tables.
> >>>>>>>>>>>
> >>>>>>>>>>> Ack
> >>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>> +
> >>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
> >>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
> >>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
> >>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
> >>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
> >>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
> >>>>>>>>>>>>
> >>>>>>>>>>>> I see all the MODE1 registers being only present in G4 and G5 tables.
> >>>>>>>>>>>> Should they be programmed for the modes lower than G4?
> >>>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>> We use G4 table for all the modes <= G4.
> >>>>>>>>>>
> >>>>>>>>>> Could you please point me how it's handled?
> >>>>>>>>>> In the patch I see just:
> >>>>>>>>>>
> >>>>>>>>>>          if (qmp->submode == UFS_HS_G4)
> >>>>>>>>>>                  qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
> >>>>>>>>>>          else if (qmp->submode == UFS_HS_G5)
> >>>>>>>>>>                  qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
> >>>>>>>>>>
> >>>>>>>>>> Which looks like two special cases (HS_G4 and HS_G5) and nothing for
> >>>>>>>>>> anything else.
> >>>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Yes, and the UFS driver passes only G4/G5. For all the gears <=G4, G4 init
> >>>>>>>>> sequence will be used and for G5, G5 sequence will be used.
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>> That's what I could not find in the UFS driver. I see a call to
> >>>>>>>> `phy_set_mode_ext(phy, PHY_MODE_UFS_HS_B, host->phy_gear);` and
> >>>>>>>> host->phy_gear is initialised to UFS_HS_G2.
> >>>>>>>>
> >>>>>>>
> >>>>>>> You need to check the UFS driver changes in this series to get the complete
> >>>>>>> picture as the logic is getting changed.
> >>>>>>>
> >>>>>>> It is common to get confused because of the way the UFS driver (qcom mostly)
> >>>>>>> handles the PHY init sequence programming. We used to have only one init
> >>>>>>> sequence for older targets and life was easy. But when I wanted to add G4
> >>>>>>> support for SM8250, I learned that there are 2 separate init sequences. One for
> >>>>>>> non-G4 and other for G4. So I used the phy_sub_mode property to pass the
> >>>>>>> relevant mode from the UFS driver to the PHY driver and programmed the sequence
> >>>>>>> accordingly. This got extended to non-G5 and G5 now.
> >>>>>>>
> >>>>>>> Now, the UFS driver will start probing from a low gear for older targets (G2)
> >>>>>>> and G4/G5 for newer ones then scale up based on the device and host capability.
> >>>>>>> For older targets, the common table (tbls) will be used if the submode doesn't
> >>>>>>> match G4/G5. But for newer targets, the UFS driver will _only_ pass G4 or G5 as
> >>>>>>> the phy_gear, so those specific sequence will only be used.
> >>>>>>>
> >>>>>>> Hope I'm clear.
> >>>>>>
> >>>>>> Yes, it is now clear, thank you!
> >>>>>>
> >>>>>> Would it be possible / feasible / logical to maintain this idea even
> >>>>>> for newer platforms (leaving the HS_A  / HS_B aside)?
> >>>>>>
> >>>>>> tbls - works for HS_G2
> >>>>>> tbls + tbls_g4 - works for HS_G4
> >>>>>> tbls + tbls_g5 - works for HS_G5
> >>>>>>
> >>>>>
> >>>>> No. The PHY team only gives 2 init sequences for any SoC now.
> >>>>
> >>>> Ack. Then the code should become
> >>>> if (HS_G5)
> >>>>      program(tbls_hs_g5)
> >>>> else
> >>>>      program(tbls_hs_g4);
> >>>>
> >>>
> >>> This should work. Even if we have to accomodate G6 in the future, we can use
> >>> "else if" for that and keep G4 as the "else" condition. This logic can also be
> >>> optimized in the future.
> >>
> >> That would make dual init meaningless for old targets. Say on SM8450, the
> >> initial PHY gear is G2, with the "else" condition, during the first init, G4
> >> table would be programmed, then gear negotiation happens btw host and device
> >> and the negotiated gear is G3 (assume a UFS2.x is connected). During the 2nd
> >> init, the "else" condition would __again__ program the G4 table - it is not
> >> programming the non-G4 table for power saving. The dual init is supposed to
> >> find the optimal PHY settings, but the "else" condition is programming G4
> >> table unconditinally.
> >>
> >> With the original code change in this patch, the dual init works as it is
> >> for old targets. say SM8450, the initial PHY gear is G2, during the 2nd
> >> init, it is programming the non-G4 table (assume a UFS2.x is connected), but
> >> not the G4 table.
> >>
> >
> > You are right. I completely overlooked the compatibility for old targets. But
> > still we can move the common table to the "else" condition. This makes it clear
> > that one of the 3 will be programmed at a time. But with the current logic, I
> > get the impression that common table is overridden by G4/G5 tables.
> >
> > So this is what I'm suggesting:
> >
> > if (HS_G5)
> >       program(tbls_hs_g5)
> > else if (HS_G4)
> >       program(tbls_hs_g4);
> > else
> >       program(tbls_hs_common);
> >
>
> Common table is needed regardlessly, we cannot put it in "else",
> otherwise it would break all targets -
>
> On old targets (no G5 supported):
> Common table            - supports non-G4 (G3 and lower)
> Common table + G4 table - supports G4
>
> On new targets (G5 supported):
> Common table            - supports nothing, as it is just common parts of G4
> table and G5 table.
> Common table + G4 table - support non-G5 (G4 and lower)
> Common table + G5 table - support G5

There is one issue with this approach, which you might be able to fix.
For the older PHYs we have two cases: pre-G4 and G4. The host driver
can set any mode of its choice.
For the newer targets we only support G4 and G5 modes, don't we?
However the knowledge that there will be no modes lower than G4 is
hidden inside the host driver.
Could you please add a flag / condition to the PHY driver to error out
if the host tries to set e.g. G2 for the newer PHYs?
Can Guo Nov. 15, 2023, 7:51 a.m. UTC | #24
On 11/14/2023 5:15 PM, Dmitry Baryshkov wrote:
> On Sun, 12 Nov 2023 at 07:13, Can Guo <quic_cang@quicinc.com> wrote:
>>
>> Hi Mani,
>>
>> On 11/11/2023 12:12 PM, Manivannan Sadhasivam wrote:
>>> On Fri, Nov 10, 2023 at 10:40:53PM +0800, Can Guo wrote:
>>>>
>>>>
>>>> On 11/10/2023 9:18 PM, Manivannan Sadhasivam wrote:
>>>>> On Fri, Nov 10, 2023 at 12:11:46AM +0200, Dmitry Baryshkov wrote:
>>>>>> On Thu, 9 Nov 2023 at 18:04, Manivannan Sadhasivam <mani@kernel.org> wrote:
>>>>>>>
>>>>>>> On Thu, Nov 09, 2023 at 01:00:51PM +0200, Dmitry Baryshkov wrote:
>>>>>>>> On Thu, 9 Nov 2023 at 12:43, Manivannan Sadhasivam <mani@kernel.org> wrote:
>>>>>>>>>
>>>>>>>>> On Thu, Nov 09, 2023 at 11:40:51AM +0200, Dmitry Baryshkov wrote:
>>>>>>>>>> On Thu, 9 Nov 2023 at 05:24, Manivannan Sadhasivam <mani@kernel.org> wrote:
>>>>>>>>>>>
>>>>>>>>>>> On Wed, Nov 08, 2023 at 08:56:16AM +0200, Dmitry Baryshkov wrote:
>>>>>>>>>>>> On Wed, 8 Nov 2023 at 07:49, Manivannan Sadhasivam <mani@kernel.org> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Tue, Nov 07, 2023 at 03:18:09PM +0200, Dmitry Baryshkov wrote:
>>>>>>>>>>>>>> On Tue, 7 Nov 2023 at 06:47, Can Guo <cang@qti.qualcomm.com> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> From: Can Guo <quic_cang@quicinc.com>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On SM8550, two sets of UFS PHY settings are provided, one set is to support
>>>>>>>>>>>>>>> HS-G5, another set is to support HS-G4 and lower gears. The two sets of PHY
>>>>>>>>>>>>>>> settings are programming different values to different registers, mixing
>>>>>>>>>>>>>>> the two sets and/or overwriting one set with another set is definitely not
>>>>>>>>>>>>>>> blessed by UFS PHY designers. In order to add HS-G5 support for SM8550, we
>>>>>>>>>>>>>>> need to split the two sets into their dedicated tables, and leave only the
>>>>>>>>>>>>>>> common settings in the .tlbs. To have the PHY programmed with the correct
>>>>>>>>>>>>>>> set of PHY settings, the submode passed to PHY driver must be either HS-G4
>>>>>>>>>>>>>>> or HS-G5.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> You should also mention that this issue is also present in G4 supported targets.
>>>>>>>>>>>>> And a note that it will get fixed later.
>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Signed-off-by: Can Guo <quic_cang@quicinc.com>
>>>>>>>>>>>>>>> ---
>>>>>>>>>>>>>>>     drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h     |   2 +
>>>>>>>>>>>>>>>     drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h |   2 +
>>>>>>>>>>>>>>>     .../qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h    |  12 +++
>>>>>>>>>>>>>>>     drivers/phy/qualcomm/phy-qcom-qmp-ufs.c            | 112 ++++++++++++++++++---
>>>>>>>>>>>>>>>     4 files changed, 115 insertions(+), 13 deletions(-)
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
>>>>>>>>>>>>>>> index c23d5e4..e563af5 100644
>>>>>>>>>>>>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
>>>>>>>>>>>>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
>>>>>>>>>>>>>>> @@ -18,6 +18,7 @@
>>>>>>>>>>>>>>>     #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL            0x060
>>>>>>>>>>>>>>>     #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY           0x074
>>>>>>>>>>>>>>>     #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY           0x0bc
>>>>>>>>>>>>>>> +#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY        0x12c
>>>>>>>>>>>>>>>     #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL               0x158
>>>>>>>>>>>>>>>     #define QPHY_V6_PCS_UFS_LINECFG_DISABLE                        0x17c
>>>>>>>>>>>>>>>     #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME            0x184
>>>>>>>>>>>>>>> @@ -27,5 +28,6 @@
>>>>>>>>>>>>>>>     #define QPHY_V6_PCS_UFS_READY_STATUS                   0x1a8
>>>>>>>>>>>>>>>     #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1              0x1f4
>>>>>>>>>>>>>>>     #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1               0x1fc
>>>>>>>>>>>>>>> +#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME         0x220
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>     #endif
>>>>>>>>>>>>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
>>>>>>>>>>>>>>> index f420f8f..ef392ce 100644
>>>>>>>>>>>>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
>>>>>>>>>>>>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
>>>>>>>>>>>>>>> @@ -56,6 +56,8 @@
>>>>>>>>>>>>>>>     #define QSERDES_V6_COM_SYS_CLK_CTRL                            0xe4
>>>>>>>>>>>>>>>     #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE                       0xe8
>>>>>>>>>>>>>>>     #define QSERDES_V6_COM_PLL_IVCO                                        0xf4
>>>>>>>>>>>>>>> +#define QSERDES_V6_COM_CMN_IETRIM                              0xfc
>>>>>>>>>>>>>>> +#define QSERDES_V6_COM_CMN_IPTRIM                              0x100
>>>>>>>>>>>>>>>     #define QSERDES_V6_COM_SYSCLK_EN_SEL                           0x110
>>>>>>>>>>>>>>>     #define QSERDES_V6_COM_RESETSM_CNTRL                           0x118
>>>>>>>>>>>>>>>     #define QSERDES_V6_COM_LOCK_CMP_EN                             0x120
>>>>>>>>>>>>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
>>>>>>>>>>>>>>> index 15bcb4b..48f31c8 100644
>>>>>>>>>>>>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
>>>>>>>>>>>>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
>>>>>>>>>>>>>>> @@ -10,10 +10,20 @@
>>>>>>>>>>>>>>>     #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX                     0x2c
>>>>>>>>>>>>>>>     #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX              0x30
>>>>>>>>>>>>>>>     #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX              0x34
>>>>>>>>>>>>>>> +#define QSERDES_UFS_V6_TX_LANE_MODE_1                          0x7c
>>>>>>>>>>>>>>> +#define QSERDES_UFS_V6_TX_FR_DCC_CTRL                          0x108
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>     #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2          0x08
>>>>>>>>>>>>>>>     #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4          0x10
>>>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4          0x24
>>>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4       0x54
>>>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2                   0xd4
>>>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4                   0xdc
>>>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4                   0xf0
>>>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS                     0xf4
>>>>>>>>>>>>>>>     #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL                      0x178
>>>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1             0x1bc
>>>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3                        0x1c4
>>>>>>>>>>>>>>>     #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0                     0x208
>>>>>>>>>>>>>>>     #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1                     0x20c
>>>>>>>>>>>>>>>     #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3                     0x214
>>>>>>>>>>>>>>> @@ -25,6 +35,8 @@
>>>>>>>>>>>>>>>     #define QSERDES_UFS_V6_RX_MODE_RATE3_B5                                0x264
>>>>>>>>>>>>>>>     #define QSERDES_UFS_V6_RX_MODE_RATE3_B8                                0x270
>>>>>>>>>>>>>>>     #define QSERDES_UFS_V6_RX_MODE_RATE4_B3                                0x280
>>>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_MODE_RATE4_B4                                0x284
>>>>>>>>>>>>>>>     #define QSERDES_UFS_V6_RX_MODE_RATE4_B6                                0x28c
>>>>>>>>>>>>>>> +#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL                      0x2f8
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>     #endif
>>>>>>>>>>>>>>> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>>>>>>>>>>>>>>> index 3927eba..e0a01497 100644
>>>>>>>>>>>>>>> --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>>>>>>>>>>>>>>> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
>>>>>>>>>>>>>>> @@ -649,32 +649,51 @@ static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
>>>>>>>>>>>>>>>            QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
>>>>>>>>>>>>>>>            QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
>>>>>>>>>>>>>>>            QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
>>>>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
>>>>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>>            QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
>>>>>>>>>>>>>>>            QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
>>>>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
>>>>>>>>>>>>>>>            QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
>>>>>>>>>>>>>>>            QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
>>>>>>>>>>>>>>>            QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
>>>>>>>>>>>>>>>            QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
>>>>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
>>>>>>>>>>>>>>> +};
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
>>>>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
>>>>>>>>>>>>>>> +};
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
>>>>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
>>>>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
>>>>>>>>>>>>>>>            QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
>>>>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
>>>>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
>>>>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
>>>>>>>>>>>>>>> -       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Aside from moving these registers to the HS_G4 table, you are also
>>>>>>>>>>>>>> changing these registers. It makes me think that there was an error in
>>>>>>>>>>>>>> the original programming sequence.
>>>>>>>>>>>>>> If that is correct, could you please split the patch into two pieces:
>>>>>>>>>>>>>> - Fix programming sequence (add proper Fixes tags)
>>>>>>>>>>>>>> - Split G4 and G5 tables.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Ack
>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> +
>>>>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
>>>>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
>>>>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
>>>>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
>>>>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
>>>>>>>>>>>>>>> +       QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I see all the MODE1 registers being only present in G4 and G5 tables.
>>>>>>>>>>>>>> Should they be programmed for the modes lower than G4?
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> We use G4 table for all the modes <= G4.
>>>>>>>>>>>>
>>>>>>>>>>>> Could you please point me how it's handled?
>>>>>>>>>>>> In the patch I see just:
>>>>>>>>>>>>
>>>>>>>>>>>>           if (qmp->submode == UFS_HS_G4)
>>>>>>>>>>>>                   qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
>>>>>>>>>>>>           else if (qmp->submode == UFS_HS_G5)
>>>>>>>>>>>>                   qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
>>>>>>>>>>>>
>>>>>>>>>>>> Which looks like two special cases (HS_G4 and HS_G5) and nothing for
>>>>>>>>>>>> anything else.
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Yes, and the UFS driver passes only G4/G5. For all the gears <=G4, G4 init
>>>>>>>>>>> sequence will be used and for G5, G5 sequence will be used.
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> That's what I could not find in the UFS driver. I see a call to
>>>>>>>>>> `phy_set_mode_ext(phy, PHY_MODE_UFS_HS_B, host->phy_gear);` and
>>>>>>>>>> host->phy_gear is initialised to UFS_HS_G2.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> You need to check the UFS driver changes in this series to get the complete
>>>>>>>>> picture as the logic is getting changed.
>>>>>>>>>
>>>>>>>>> It is common to get confused because of the way the UFS driver (qcom mostly)
>>>>>>>>> handles the PHY init sequence programming. We used to have only one init
>>>>>>>>> sequence for older targets and life was easy. But when I wanted to add G4
>>>>>>>>> support for SM8250, I learned that there are 2 separate init sequences. One for
>>>>>>>>> non-G4 and other for G4. So I used the phy_sub_mode property to pass the
>>>>>>>>> relevant mode from the UFS driver to the PHY driver and programmed the sequence
>>>>>>>>> accordingly. This got extended to non-G5 and G5 now.
>>>>>>>>>
>>>>>>>>> Now, the UFS driver will start probing from a low gear for older targets (G2)
>>>>>>>>> and G4/G5 for newer ones then scale up based on the device and host capability.
>>>>>>>>> For older targets, the common table (tbls) will be used if the submode doesn't
>>>>>>>>> match G4/G5. But for newer targets, the UFS driver will _only_ pass G4 or G5 as
>>>>>>>>> the phy_gear, so those specific sequence will only be used.
>>>>>>>>>
>>>>>>>>> Hope I'm clear.
>>>>>>>>
>>>>>>>> Yes, it is now clear, thank you!
>>>>>>>>
>>>>>>>> Would it be possible / feasible / logical to maintain this idea even
>>>>>>>> for newer platforms (leaving the HS_A  / HS_B aside)?
>>>>>>>>
>>>>>>>> tbls - works for HS_G2
>>>>>>>> tbls + tbls_g4 - works for HS_G4
>>>>>>>> tbls + tbls_g5 - works for HS_G5
>>>>>>>>
>>>>>>>
>>>>>>> No. The PHY team only gives 2 init sequences for any SoC now.
>>>>>>
>>>>>> Ack. Then the code should become
>>>>>> if (HS_G5)
>>>>>>       program(tbls_hs_g5)
>>>>>> else
>>>>>>       program(tbls_hs_g4);
>>>>>>
>>>>>
>>>>> This should work. Even if we have to accomodate G6 in the future, we can use
>>>>> "else if" for that and keep G4 as the "else" condition. This logic can also be
>>>>> optimized in the future.
>>>>
>>>> That would make dual init meaningless for old targets. Say on SM8450, the
>>>> initial PHY gear is G2, with the "else" condition, during the first init, G4
>>>> table would be programmed, then gear negotiation happens btw host and device
>>>> and the negotiated gear is G3 (assume a UFS2.x is connected). During the 2nd
>>>> init, the "else" condition would __again__ program the G4 table - it is not
>>>> programming the non-G4 table for power saving. The dual init is supposed to
>>>> find the optimal PHY settings, but the "else" condition is programming G4
>>>> table unconditinally.
>>>>
>>>> With the original code change in this patch, the dual init works as it is
>>>> for old targets. say SM8450, the initial PHY gear is G2, during the 2nd
>>>> init, it is programming the non-G4 table (assume a UFS2.x is connected), but
>>>> not the G4 table.
>>>>
>>>
>>> You are right. I completely overlooked the compatibility for old targets. But
>>> still we can move the common table to the "else" condition. This makes it clear
>>> that one of the 3 will be programmed at a time. But with the current logic, I
>>> get the impression that common table is overridden by G4/G5 tables.
>>>
>>> So this is what I'm suggesting:
>>>
>>> if (HS_G5)
>>>        program(tbls_hs_g5)
>>> else if (HS_G4)
>>>        program(tbls_hs_g4);
>>> else
>>>        program(tbls_hs_common);
>>>
>>
>> Common table is needed regardlessly, we cannot put it in "else",
>> otherwise it would break all targets -
>>
>> On old targets (no G5 supported):
>> Common table            - supports non-G4 (G3 and lower)
>> Common table + G4 table - supports G4
>>
>> On new targets (G5 supported):
>> Common table            - supports nothing, as it is just common parts of G4
>> table and G5 table.
>> Common table + G4 table - support non-G5 (G4 and lower)
>> Common table + G5 table - support G5
> 
> There is one issue with this approach, which you might be able to fix.
> For the older PHYs we have two cases: pre-G4 and G4. The host driver
> can set any mode of its choice.
> For the newer targets we only support G4 and G5 modes, don't we?
> However the knowledge that there will be no modes lower than G4 is
> hidden inside the host driver.
> Could you please add a flag / condition to the PHY driver to error out
> if the host tries to set e.g. G2 for the newer PHYs?
> 

I will propose a fix for this once for all in next version.

Thanks,
Can Guo.
diff mbox series

Patch

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
index c23d5e4..e563af5 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-ufs-v6.h
@@ -18,6 +18,7 @@ 
 #define QPHY_V6_PCS_UFS_BIST_FIXED_PAT_CTRL		0x060
 #define QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY		0x074
 #define QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY		0x0bc
+#define QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY	0x12c
 #define QPHY_V6_PCS_UFS_DEBUG_BUS_CLKSEL		0x158
 #define QPHY_V6_PCS_UFS_LINECFG_DISABLE			0x17c
 #define QPHY_V6_PCS_UFS_RX_MIN_HIBERN8_TIME		0x184
@@ -27,5 +28,6 @@ 
 #define QPHY_V6_PCS_UFS_READY_STATUS			0x1a8
 #define QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1		0x1f4
 #define QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1		0x1fc
+#define QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME		0x220
 
 #endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
index f420f8f..ef392ce 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v6.h
@@ -56,6 +56,8 @@ 
 #define QSERDES_V6_COM_SYS_CLK_CTRL				0xe4
 #define QSERDES_V6_COM_SYSCLK_BUF_ENABLE			0xe8
 #define QSERDES_V6_COM_PLL_IVCO					0xf4
+#define QSERDES_V6_COM_CMN_IETRIM				0xfc
+#define QSERDES_V6_COM_CMN_IPTRIM				0x100
 #define QSERDES_V6_COM_SYSCLK_EN_SEL				0x110
 #define QSERDES_V6_COM_RESETSM_CNTRL				0x118
 #define QSERDES_V6_COM_LOCK_CMP_EN				0x120
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
index 15bcb4b..48f31c8 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-ufs-v6.h
@@ -10,10 +10,20 @@ 
 #define QSERDES_UFS_V6_TX_RES_CODE_LANE_RX			0x2c
 #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX		0x30
 #define QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX		0x34
+#define QSERDES_UFS_V6_TX_LANE_MODE_1				0x7c
+#define QSERDES_UFS_V6_TX_FR_DCC_CTRL				0x108
 
 #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2		0x08
 #define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4		0x10
+#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4		0x24
+#define QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4	0x54
+#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2			0xd4
+#define QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4			0xdc
+#define QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4			0xf0
+#define QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS			0xf4
 #define QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL			0x178
+#define QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1		0x1bc
+#define QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3			0x1c4
 #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0			0x208
 #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1			0x20c
 #define QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3			0x214
@@ -25,6 +35,8 @@ 
 #define QSERDES_UFS_V6_RX_MODE_RATE3_B5				0x264
 #define QSERDES_UFS_V6_RX_MODE_RATE3_B8				0x270
 #define QSERDES_UFS_V6_RX_MODE_RATE4_B3				0x280
+#define QSERDES_UFS_V6_RX_MODE_RATE4_B4				0x284
 #define QSERDES_UFS_V6_RX_MODE_RATE4_B6				0x28c
+#define QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL			0x2f8
 
 #endif
diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
index 3927eba..e0a01497 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c
@@ -649,32 +649,51 @@  static const struct qmp_phy_init_tbl sm8550_ufsphy_serdes[] = {
 	QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11),
 	QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00),
 	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01),
-	QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
-	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
+
 	QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00),
 	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x41),
-	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
 	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
 	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
 	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x7f),
 	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x06),
-	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x4c),
+};
+
+static const struct qmp_phy_init_tbl sm8550_ufsphy_hs_b_serdes[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x44),
+};
+
+static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_serdes[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f),
 	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x0a),
-	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18),
-	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x14),
-	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0x99),
-	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x07),
+
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x4c),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x0a),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x14),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x99),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x07),
+};
+
+static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_serdes[] = {
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x1f),
+
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x1b),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x1c),
+	QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x06),
 };
 
 static const struct qmp_phy_init_tbl sm8550_ufsphy_tx[] = {
-	QMP_PHY_INIT_CFG(QSERDES_V6_TX_LANE_MODE_1, 0x05),
+	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05),
 	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07),
 };
 
+static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_tx[] = {
+	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_FR_DCC_CTRL, 0x4c),
+};
+
 static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
-	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE2, 0x0c),
-	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x0f),
-	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
+	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c),
 
 	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xc2),
 	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xc2),
@@ -690,14 +709,46 @@  static const struct qmp_phy_init_tbl sm8550_ufsphy_rx[] = {
 	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02),
 };
 
+static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_rx[] = {
+	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x0e),
+};
+
+static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_rx[] = {
+	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE4, 0x0c),
+	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_SO_GAIN_RATE4, 0x04),
+	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x14),
+	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CONTROLS, 0x07),
+	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_OFFSET_ADAPTOR_CNTRL3, 0x0e),
+	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_COUNT_HIGH_RATE4, 0x02),
+	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_FO_GAIN_RATE4, 0x1c),
+	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FASTLOCK_SO_GAIN_RATE4, 0x06),
+	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x08),
+
+	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B3, 0xb9),
+	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B4, 0x4f),
+	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE4_B6, 0xff),
+	QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_DLL0_FTUNE_CTRL, 0x30),
+};
+
 static const struct qmp_phy_init_tbl sm8550_ufsphy_pcs[] = {
 	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x69),
 	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f),
 	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
-	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
 	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
 };
 
+static const struct qmp_phy_init_tbl sm8550_ufsphy_g4_pcs[] = {
+	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x2b),
+	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04),
+	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04),
+};
+
+static const struct qmp_phy_init_tbl sm8550_ufsphy_g5_pcs[] = {
+	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x33),
+	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HS_G5_SYNC_LENGTH_CAPABILITY, 0x4f),
+	QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSG5_SYNC_WAIT_TIME, 0x9e),
+};
+
 struct qmp_ufs_offsets {
 	u16 serdes;
 	u16 pcs;
@@ -731,6 +782,8 @@  struct qmp_phy_cfg {
 	const struct qmp_phy_cfg_tbls tbls_hs_b;
 	/* Additional sequence for HS G4 */
 	const struct qmp_phy_cfg_tbls tbls_hs_g4;
+	/* Additional sequence for HS G4 */
+	const struct qmp_phy_cfg_tbls tbls_hs_g5;
 
 	/* clock ids to be requested */
 	const char * const *clk_list;
@@ -1157,6 +1210,28 @@  static const struct qmp_phy_cfg sm8550_ufsphy_cfg = {
 		.pcs		= sm8550_ufsphy_pcs,
 		.pcs_num	= ARRAY_SIZE(sm8550_ufsphy_pcs),
 	},
+	.tbls_hs_b = {
+		.serdes		= sm8550_ufsphy_hs_b_serdes,
+		.serdes_num	= ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes),
+	},
+	.tbls_hs_g4 = {
+		.serdes		= sm8550_ufsphy_g4_serdes,
+		.serdes_num	= ARRAY_SIZE(sm8550_ufsphy_g4_serdes),
+		.tx		= sm8550_ufsphy_g4_tx,
+		.tx_num		= ARRAY_SIZE(sm8550_ufsphy_g4_tx),
+		.rx		= sm8550_ufsphy_g4_rx,
+		.rx_num		= ARRAY_SIZE(sm8550_ufsphy_g4_rx),
+		.pcs		= sm8550_ufsphy_g4_pcs,
+		.pcs_num	= ARRAY_SIZE(sm8550_ufsphy_g4_pcs),
+	},
+	.tbls_hs_g5 = {
+		.serdes		= sm8550_ufsphy_g5_serdes,
+		.serdes_num	= ARRAY_SIZE(sm8550_ufsphy_g5_serdes),
+		.rx		= sm8550_ufsphy_g5_rx,
+		.rx_num		= ARRAY_SIZE(sm8550_ufsphy_g5_rx),
+		.pcs		= sm8550_ufsphy_g5_pcs,
+		.pcs_num	= ARRAY_SIZE(sm8550_ufsphy_g5_pcs),
+	},
 	.clk_list		= sdm845_ufs_phy_clk_l,
 	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
 	.vreg_list		= qmp_phy_vreg_l,
@@ -1222,14 +1297,25 @@  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->submode == UFS_HS_G4)
+		qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g4);
+	else if (qmp->submode == UFS_HS_G5)
+		qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_g5);
+
 	if (qmp->mode == PHY_MODE_UFS_HS_B)
 		qmp_ufs_serdes_init(qmp, &cfg->tbls_hs_b);
+
 	qmp_ufs_lanes_init(qmp, &cfg->tbls);
 	if (qmp->submode == UFS_HS_G4)
 		qmp_ufs_lanes_init(qmp, &cfg->tbls_hs_g4);
+	else if (qmp->submode == UFS_HS_G5)
+		qmp_ufs_lanes_init(qmp, &cfg->tbls_hs_g5);
+
 	qmp_ufs_pcs_init(qmp, &cfg->tbls);
 	if (qmp->submode == UFS_HS_G4)
 		qmp_ufs_pcs_init(qmp, &cfg->tbls_hs_g4);
+	else if (qmp->submode == UFS_HS_G5)
+		qmp_ufs_pcs_init(qmp, &cfg->tbls_hs_g5);
 }
 
 static int qmp_ufs_com_init(struct qmp_ufs *qmp)