Re: [PATCH v5 3/7] phy: qcom-qmp: move DP functions to callbacks

2021-03-29 Thread Bjorn Andersson
On Sun 28 Mar 15:52 CDT 2021, Dmitry Baryshkov wrote:

> In preparation to adding support for V4 DP PHY move DP functions to
> callbacks at struct qmp_phy_cfg.
> 

Reviewed-by: Bjorn Andersson 

Regards,
Bjorn

> Signed-off-by: Dmitry Baryshkov 
> ---
>  drivers/phy/qualcomm/phy-qcom-qmp.c | 438 +++-
>  1 file changed, 231 insertions(+), 207 deletions(-)
> 
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
> b/drivers/phy/qualcomm/phy-qcom-qmp.c
> index 9cdebe7f26cb..4150096fd350 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
> @@ -2268,6 +2268,8 @@ static const struct qmp_phy_init_tbl 
> sm8350_usb3_uniphy_pcs_tbl[] = {
>   QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
>  };
>  
> +struct qmp_phy;
> +
>  /* struct qmp_phy_cfg - per-PHY initialization config */
>  struct qmp_phy_cfg {
>   /* phy-type - PCIE/UFS/USB */
> @@ -2307,6 +2309,12 @@ struct qmp_phy_cfg {
>   const struct qmp_phy_init_tbl *serdes_tbl_hbr3;
>   int serdes_tbl_hbr3_num;
>  
> + /* DP PHY callbacks */
> + int (*configure_dp_phy)(struct qmp_phy *qphy);
> + void (*configure_dp_tx)(struct qmp_phy *qphy);
> + int (*calibrate_dp_phy)(struct qmp_phy *qphy);
> + void (*dp_aux_init)(struct qmp_phy *qphy);
> +
>   /* clock ids to be requested */
>   const char * const *clk_list;
>   int num_clks;
> @@ -2423,6 +2431,216 @@ struct qcom_qmp {
>   struct reset_control *ufs_reset;
>  };
>  
> +static void qcom_qmp_v3_phy_dp_aux_init(struct qmp_phy *qphy)
> +{
> + writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
> +DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
> +qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
> +
> + /* Turn on BIAS current for PHY/PLL */
> + writel(QSERDES_V3_COM_BIAS_EN | QSERDES_V3_COM_BIAS_EN_MUX |
> +QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL,
> +qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
> +
> + writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
> +
> + writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
> +DP_PHY_PD_CTL_LANE_0_1_PWRDN |
> +DP_PHY_PD_CTL_LANE_2_3_PWRDN | DP_PHY_PD_CTL_PLL_PWRDN |
> +DP_PHY_PD_CTL_DP_CLAMP_EN,
> +qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
> +
> + writel(QSERDES_V3_COM_BIAS_EN |
> +QSERDES_V3_COM_BIAS_EN_MUX | QSERDES_V3_COM_CLKBUF_R_EN |
> +QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL |
> +QSERDES_V3_COM_CLKBUF_RX_DRIVE_L,
> +qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
> +
> + writel(0x00, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG0);
> + writel(0x13, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG1);
> + writel(0x24, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG2);
> + writel(0x00, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG3);
> + writel(0x0a, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG4);
> + writel(0x26, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG5);
> + writel(0x0a, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG6);
> + writel(0x03, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG7);
> + writel(0xbb, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG8);
> + writel(0x03, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG9);
> + qphy->dp_aux_cfg = 0;
> +
> + writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
> +PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
> +PHY_AUX_REQ_ERR_MASK,
> +qphy->pcs + QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK);
> +}
> +
> +static const u8 qmp_dp_v3_pre_emphasis_hbr_rbr[4][4] = {
> + { 0x00, 0x0c, 0x14, 0x19 },
> + { 0x00, 0x0b, 0x12, 0xff },
> + { 0x00, 0x0b, 0xff, 0xff },
> + { 0x04, 0xff, 0xff, 0xff }
> +};
> +
> +static const u8 qmp_dp_v3_voltage_swing_hbr_rbr[4][4] = {
> + { 0x08, 0x0f, 0x16, 0x1f },
> + { 0x11, 0x1e, 0x1f, 0xff },
> + { 0x19, 0x1f, 0xff, 0xff },
> + { 0x1f, 0xff, 0xff, 0xff }
> +};
> +
> +static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy)
> +{
> + const struct phy_configure_opts_dp *dp_opts = >dp_opts;
> + unsigned int v_level = 0, p_level = 0;
> + u32 bias_en, drvr_en;
> + u8 voltage_swing_cfg, pre_emphasis_cfg;
> + int i;
> +
> + for (i = 0; i < dp_opts->lanes; i++) {
> + v_level = max(v_level, dp_opts->voltage[i]);
> + p_level = max(p_level, dp_opts->pre[i]);
> + }
> +
> + if (dp_opts->lanes == 1) {
> + bias_en = 0x3e;
> + drvr_en = 0x13;
> + } else {
> + bias_en = 0x3f;
> + drvr_en = 0x10;
> + }
> +
> + voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr_rbr[v_level][p_level];
> + pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr_rbr[v_level][p_level];
> +
> + /* TODO: Move check to config check */
> + if (voltage_swing_cfg == 0xFF && pre_emphasis_cfg == 0xFF)
> + return;
> +
> + /* Enable 

[PATCH v5 3/7] phy: qcom-qmp: move DP functions to callbacks

2021-03-28 Thread Dmitry Baryshkov
In preparation to adding support for V4 DP PHY move DP functions to
callbacks at struct qmp_phy_cfg.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/phy/qualcomm/phy-qcom-qmp.c | 438 +++-
 1 file changed, 231 insertions(+), 207 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.c 
b/drivers/phy/qualcomm/phy-qcom-qmp.c
index 9cdebe7f26cb..4150096fd350 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp.c
@@ -2268,6 +2268,8 @@ static const struct qmp_phy_init_tbl 
sm8350_usb3_uniphy_pcs_tbl[] = {
QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1, 0x21),
 };
 
+struct qmp_phy;
+
 /* struct qmp_phy_cfg - per-PHY initialization config */
 struct qmp_phy_cfg {
/* phy-type - PCIE/UFS/USB */
@@ -2307,6 +2309,12 @@ struct qmp_phy_cfg {
const struct qmp_phy_init_tbl *serdes_tbl_hbr3;
int serdes_tbl_hbr3_num;
 
+   /* DP PHY callbacks */
+   int (*configure_dp_phy)(struct qmp_phy *qphy);
+   void (*configure_dp_tx)(struct qmp_phy *qphy);
+   int (*calibrate_dp_phy)(struct qmp_phy *qphy);
+   void (*dp_aux_init)(struct qmp_phy *qphy);
+
/* clock ids to be requested */
const char * const *clk_list;
int num_clks;
@@ -2423,6 +2431,216 @@ struct qcom_qmp {
struct reset_control *ufs_reset;
 };
 
+static void qcom_qmp_v3_phy_dp_aux_init(struct qmp_phy *qphy)
+{
+   writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
+  DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN,
+  qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
+
+   /* Turn on BIAS current for PHY/PLL */
+   writel(QSERDES_V3_COM_BIAS_EN | QSERDES_V3_COM_BIAS_EN_MUX |
+  QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL,
+  qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
+
+   writel(DP_PHY_PD_CTL_PSR_PWRDN, qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
+
+   writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN |
+  DP_PHY_PD_CTL_LANE_0_1_PWRDN |
+  DP_PHY_PD_CTL_LANE_2_3_PWRDN | DP_PHY_PD_CTL_PLL_PWRDN |
+  DP_PHY_PD_CTL_DP_CLAMP_EN,
+  qphy->pcs + QSERDES_V3_DP_PHY_PD_CTL);
+
+   writel(QSERDES_V3_COM_BIAS_EN |
+  QSERDES_V3_COM_BIAS_EN_MUX | QSERDES_V3_COM_CLKBUF_R_EN |
+  QSERDES_V3_COM_CLKBUF_L_EN | QSERDES_V3_COM_EN_SYSCLK_TX_SEL |
+  QSERDES_V3_COM_CLKBUF_RX_DRIVE_L,
+  qphy->serdes + QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN);
+
+   writel(0x00, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG0);
+   writel(0x13, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG1);
+   writel(0x24, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG2);
+   writel(0x00, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG3);
+   writel(0x0a, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG4);
+   writel(0x26, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG5);
+   writel(0x0a, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG6);
+   writel(0x03, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG7);
+   writel(0xbb, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG8);
+   writel(0x03, qphy->pcs + QSERDES_V3_DP_PHY_AUX_CFG9);
+   qphy->dp_aux_cfg = 0;
+
+   writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK |
+  PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK |
+  PHY_AUX_REQ_ERR_MASK,
+  qphy->pcs + QSERDES_V3_DP_PHY_AUX_INTERRUPT_MASK);
+}
+
+static const u8 qmp_dp_v3_pre_emphasis_hbr_rbr[4][4] = {
+   { 0x00, 0x0c, 0x14, 0x19 },
+   { 0x00, 0x0b, 0x12, 0xff },
+   { 0x00, 0x0b, 0xff, 0xff },
+   { 0x04, 0xff, 0xff, 0xff }
+};
+
+static const u8 qmp_dp_v3_voltage_swing_hbr_rbr[4][4] = {
+   { 0x08, 0x0f, 0x16, 0x1f },
+   { 0x11, 0x1e, 0x1f, 0xff },
+   { 0x19, 0x1f, 0xff, 0xff },
+   { 0x1f, 0xff, 0xff, 0xff }
+};
+
+static void qcom_qmp_v3_phy_configure_dp_tx(struct qmp_phy *qphy)
+{
+   const struct phy_configure_opts_dp *dp_opts = >dp_opts;
+   unsigned int v_level = 0, p_level = 0;
+   u32 bias_en, drvr_en;
+   u8 voltage_swing_cfg, pre_emphasis_cfg;
+   int i;
+
+   for (i = 0; i < dp_opts->lanes; i++) {
+   v_level = max(v_level, dp_opts->voltage[i]);
+   p_level = max(p_level, dp_opts->pre[i]);
+   }
+
+   if (dp_opts->lanes == 1) {
+   bias_en = 0x3e;
+   drvr_en = 0x13;
+   } else {
+   bias_en = 0x3f;
+   drvr_en = 0x10;
+   }
+
+   voltage_swing_cfg = qmp_dp_v3_voltage_swing_hbr_rbr[v_level][p_level];
+   pre_emphasis_cfg = qmp_dp_v3_pre_emphasis_hbr_rbr[v_level][p_level];
+
+   /* TODO: Move check to config check */
+   if (voltage_swing_cfg == 0xFF && pre_emphasis_cfg == 0xFF)
+   return;
+
+   /* Enable MUX to use Cursor values from these registers */
+   voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN;
+   pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN;
+
+