Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2017, The Linux Foundation. All rights reserved.
0004  */
0005 
0006 #include <linux/clk.h>
0007 #include <linux/clk-provider.h>
0008 #include <linux/delay.h>
0009 #include <linux/err.h>
0010 #include <linux/io.h>
0011 #include <linux/iopoll.h>
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/of.h>
0015 #include <linux/of_device.h>
0016 #include <linux/of_address.h>
0017 #include <linux/phy/phy.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/regulator/consumer.h>
0020 #include <linux/reset.h>
0021 #include <linux/slab.h>
0022 
0023 #include <dt-bindings/phy/phy.h>
0024 
0025 #include "phy-qcom-qmp.h"
0026 
0027 /* QPHY_SW_RESET bit */
0028 #define SW_RESET                BIT(0)
0029 /* QPHY_POWER_DOWN_CONTROL */
0030 #define SW_PWRDN                BIT(0)
0031 #define REFCLK_DRV_DSBL             BIT(1)
0032 /* QPHY_START_CONTROL bits */
0033 #define SERDES_START                BIT(0)
0034 #define PCS_START               BIT(1)
0035 #define PLL_READY_GATE_EN           BIT(3)
0036 /* QPHY_PCS_STATUS bit */
0037 #define PHYSTATUS               BIT(6)
0038 #define PHYSTATUS_4_20              BIT(7)
0039 /* QPHY_PCS_READY_STATUS & QPHY_COM_PCS_READY_STATUS bit */
0040 #define PCS_READY               BIT(0)
0041 
0042 /* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
0043 /* DP PHY soft reset */
0044 #define SW_DPPHY_RESET              BIT(0)
0045 /* mux to select DP PHY reset control, 0:HW control, 1: software reset */
0046 #define SW_DPPHY_RESET_MUX          BIT(1)
0047 /* USB3 PHY soft reset */
0048 #define SW_USB3PHY_RESET            BIT(2)
0049 /* mux to select USB3 PHY reset control, 0:HW control, 1: software reset */
0050 #define SW_USB3PHY_RESET_MUX            BIT(3)
0051 
0052 /* QPHY_V3_DP_COM_PHY_MODE_CTRL register bits */
0053 #define USB3_MODE               BIT(0) /* enables USB3 mode */
0054 #define DP_MODE                 BIT(1) /* enables DP mode */
0055 
0056 /* QPHY_PCS_AUTONOMOUS_MODE_CTRL register bits */
0057 #define ARCVR_DTCT_EN               BIT(0)
0058 #define ALFPS_DTCT_EN               BIT(1)
0059 #define ARCVR_DTCT_EVENT_SEL            BIT(4)
0060 
0061 /* QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR register bits */
0062 #define IRQ_CLEAR               BIT(0)
0063 
0064 /* QPHY_PCS_LFPS_RXTERM_IRQ_STATUS register bits */
0065 #define RCVR_DETECT             BIT(0)
0066 
0067 /* QPHY_V3_PCS_MISC_CLAMP_ENABLE register bits */
0068 #define CLAMP_EN                BIT(0) /* enables i/o clamp_n */
0069 
0070 #define PHY_INIT_COMPLETE_TIMEOUT       10000
0071 #define POWER_DOWN_DELAY_US_MIN         10
0072 #define POWER_DOWN_DELAY_US_MAX         11
0073 
0074 #define MAX_PROP_NAME               32
0075 
0076 /* Define the assumed distance between lanes for underspecified device trees. */
0077 #define QMP_PHY_LEGACY_LANE_STRIDE      0x400
0078 
0079 struct qmp_phy_init_tbl {
0080     unsigned int offset;
0081     unsigned int val;
0082     /*
0083      * register part of layout ?
0084      * if yes, then offset gives index in the reg-layout
0085      */
0086     bool in_layout;
0087     /*
0088      * mask of lanes for which this register is written
0089      * for cases when second lane needs different values
0090      */
0091     u8 lane_mask;
0092 };
0093 
0094 #define QMP_PHY_INIT_CFG(o, v)      \
0095     {               \
0096         .offset = o,        \
0097         .val = v,       \
0098         .lane_mask = 0xff,  \
0099     }
0100 
0101 #define QMP_PHY_INIT_CFG_L(o, v)    \
0102     {               \
0103         .offset = o,        \
0104         .val = v,       \
0105         .in_layout = true,  \
0106         .lane_mask = 0xff,  \
0107     }
0108 
0109 #define QMP_PHY_INIT_CFG_LANE(o, v, l)  \
0110     {               \
0111         .offset = o,        \
0112         .val = v,       \
0113         .lane_mask = l,     \
0114     }
0115 
0116 /* set of registers with offsets different per-PHY */
0117 enum qphy_reg_layout {
0118     /* Common block control registers */
0119     QPHY_COM_SW_RESET,
0120     QPHY_COM_POWER_DOWN_CONTROL,
0121     QPHY_COM_START_CONTROL,
0122     QPHY_COM_PCS_READY_STATUS,
0123     /* PCS registers */
0124     QPHY_SW_RESET,
0125     QPHY_START_CTRL,
0126     QPHY_PCS_READY_STATUS,
0127     QPHY_PCS_STATUS,
0128     QPHY_PCS_AUTONOMOUS_MODE_CTRL,
0129     QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR,
0130     QPHY_PCS_LFPS_RXTERM_IRQ_STATUS,
0131     QPHY_PCS_POWER_DOWN_CONTROL,
0132     /* PCS_MISC registers */
0133     QPHY_PCS_MISC_TYPEC_CTRL,
0134     /* Keep last to ensure regs_layout arrays are properly initialized */
0135     QPHY_LAYOUT_SIZE
0136 };
0137 
0138 static const unsigned int msm8996_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
0139     [QPHY_START_CTRL]       = 0x00,
0140     [QPHY_PCS_READY_STATUS]     = 0x168,
0141 };
0142 
0143 static const unsigned int sdm845_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
0144     [QPHY_START_CTRL]       = 0x00,
0145     [QPHY_PCS_READY_STATUS]     = 0x160,
0146 };
0147 
0148 static const unsigned int sm6115_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
0149     [QPHY_START_CTRL]       = 0x00,
0150     [QPHY_PCS_READY_STATUS]     = 0x168,
0151 };
0152 
0153 static const unsigned int sm8150_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
0154     [QPHY_START_CTRL]       = QPHY_V4_PCS_UFS_PHY_START,
0155     [QPHY_PCS_READY_STATUS]     = QPHY_V4_PCS_UFS_READY_STATUS,
0156     [QPHY_SW_RESET]         = QPHY_V4_PCS_UFS_SW_RESET,
0157 };
0158 
0159 static const struct qmp_phy_init_tbl msm8996_ufs_serdes_tbl[] = {
0160     QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
0161     QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xd7),
0162     QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
0163     QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
0164     QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
0165     QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
0166     QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x05),
0167     QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
0168     QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
0169     QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
0170     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x10),
0171     QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
0172     QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
0173     QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
0174     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
0175     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
0176     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x54),
0177     QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
0178     QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
0179     QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
0180     QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
0181     QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
0182     QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
0183     QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
0184     QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
0185     QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
0186     QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
0187     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
0188     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
0189     QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
0190     QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
0191     QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
0192     QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
0193     QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
0194     QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
0195     QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
0196     QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
0197     QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
0198     QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
0199     QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
0200     QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
0201     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
0202     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
0203     QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
0204     QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
0205     QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
0206 };
0207 
0208 static const struct qmp_phy_init_tbl msm8996_ufs_tx_tbl[] = {
0209     QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
0210     QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x02),
0211 };
0212 
0213 static const struct qmp_phy_init_tbl msm8996_ufs_rx_tbl[] = {
0214     QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
0215     QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x02),
0216     QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x00),
0217     QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x18),
0218     QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
0219     QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5b),
0220     QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xff),
0221     QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3f),
0222     QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xff),
0223     QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x0f),
0224     QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0E),
0225 };
0226 
0227 static const struct qmp_phy_init_tbl sm6115_ufsphy_serdes_tbl[] = {
0228     QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
0229     QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
0230     QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
0231     QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
0232     QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
0233     QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
0234     QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
0235     QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
0236     QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
0237     QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
0238     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
0239     QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
0240     QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
0241     QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
0242     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
0243     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
0244     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x04),
0245     QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
0246     QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
0247     QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
0248     QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
0249     QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
0250     QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
0251     QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
0252     QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
0253     QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
0254     QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
0255     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
0256     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
0257     QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
0258     QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
0259     QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
0260     QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
0261     QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
0262     QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
0263     QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
0264     QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
0265     QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
0266     QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
0267     QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
0268     QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
0269     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
0270     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
0271     QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
0272     QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
0273     QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
0274     QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
0275     QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
0276     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL1, 0xff),
0277     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00),
0278 
0279     /* Rate B */
0280     QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x44),
0281 };
0282 
0283 static const struct qmp_phy_init_tbl sm6115_ufsphy_tx_tbl[] = {
0284     QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
0285     QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
0286 };
0287 
0288 static const struct qmp_phy_init_tbl sm6115_ufsphy_rx_tbl[] = {
0289     QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
0290     QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x0F),
0291     QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x40),
0292     QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E),
0293     QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
0294     QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5B),
0295     QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xFF),
0296     QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3F),
0297     QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xFF),
0298     QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x3F),
0299     QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0D),
0300     QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
0301     QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
0302     QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN, 0x04),
0303     QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5B),
0304 };
0305 
0306 static const struct qmp_phy_init_tbl sm6115_ufsphy_pcs_tbl[] = {
0307     QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_PWM_GEAR_BAND, 0x15),
0308     QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_SIGDET_CTRL2, 0x6d),
0309     QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_LARGE_AMP_DRV_LVL, 0x0f),
0310     QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_SMALL_AMP_DRV_LVL, 0x02),
0311     QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28),
0312     QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_SYM_RESYNC_CTRL, 0x03),
0313     QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_LARGE_AMP_POST_EMP_LVL, 0x12),
0314     QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_SMALL_AMP_POST_EMP_LVL, 0x0f),
0315     QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */
0316 };
0317 
0318 static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes_tbl[] = {
0319     QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
0320     QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
0321     QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
0322     QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
0323     QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
0324     QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0xd5),
0325     QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
0326     QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
0327     QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
0328     QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
0329     QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),
0330     QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
0331     QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x04),
0332     QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x05),
0333     QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL1, 0xff),
0334     QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL2, 0x00),
0335     QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
0336     QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
0337     QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
0338     QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
0339     QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
0340     QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
0341     QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xda),
0342     QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
0343     QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0xff),
0344     QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0c),
0345     QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE1, 0x98),
0346     QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE1, 0x06),
0347     QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE1, 0x16),
0348     QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE1, 0x36),
0349     QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
0350     QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
0351     QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE1, 0xc1),
0352     QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE1, 0x00),
0353     QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE1, 0x32),
0354     QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE1, 0x0f),
0355 
0356     /* Rate B */
0357     QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x44),
0358 };
0359 
0360 static const struct qmp_phy_init_tbl sdm845_ufsphy_tx_tbl[] = {
0361     QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
0362     QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x04),
0363     QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
0364 };
0365 
0366 static const struct qmp_phy_init_tbl sdm845_ufsphy_rx_tbl[] = {
0367     QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24),
0368     QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f),
0369     QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
0370     QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
0371     QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
0372     QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b),
0373     QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
0374     QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
0375     QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1b),
0376     QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
0377     QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
0378     QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04),
0379     QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
0380     QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81),
0381     QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
0382     QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
0383 };
0384 
0385 static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs_tbl[] = {
0386     QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL2, 0x6e),
0387     QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
0388     QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
0389     QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03),
0390     QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
0391     QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL1, 0x0f),
0392     QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_MIN_HIBERN8_TIME, 0x9a),
0393     QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
0394 };
0395 
0396 static const struct qmp_phy_init_tbl sm8150_ufsphy_serdes_tbl[] = {
0397     QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9),
0398     QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11),
0399     QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
0400     QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x01),
0401     QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
0402     QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
0403     QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_INITVAL2, 0x00),
0404     QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
0405     QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
0406     QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
0407     QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
0408     QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
0409     QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xff),
0410     QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0c),
0411     QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
0412     QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
0413     QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x98),
0414     QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
0415     QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
0416     QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
0417     QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x32),
0418     QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x0f),
0419     QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
0420     QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
0421 
0422     /* Rate B */
0423     QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x06),
0424 };
0425 
0426 static const struct qmp_phy_init_tbl sm8150_ufsphy_tx_tbl[] = {
0427     QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
0428     QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
0429     QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
0430     QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
0431     QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x05),
0432     QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c),
0433 };
0434 
0435 static const struct qmp_phy_init_tbl sm8150_ufsphy_rx_tbl[] = {
0436     QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
0437     QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
0438     QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
0439     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
0440     QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
0441     QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
0442     QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
0443     QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
0444     QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80),
0445     QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
0446     QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
0447     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b),
0448     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
0449     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
0450     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d),
0451     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
0452     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10),
0453     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
0454     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
0455     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x36),
0456     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x36),
0457     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xf6),
0458     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b),
0459     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3d),
0460     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0),
0461     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8),
0462     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
0463     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
0464     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
0465     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
0466     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
0467     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
0468     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
0469     QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
0470 
0471 };
0472 
0473 static const struct qmp_phy_init_tbl sm8150_ufsphy_pcs_tbl[] = {
0474     QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
0475     QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
0476     QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
0477     QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
0478     QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
0479     QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
0480     QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
0481 };
0482 
0483 static const struct qmp_phy_init_tbl sm8350_ufsphy_serdes_tbl[] = {
0484     QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0xd9),
0485     QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x11),
0486     QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00),
0487     QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42),
0488     QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
0489     QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
0490     QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_INITVAL2, 0x00),
0491     QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
0492     QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
0493     QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x14),
0494     QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x18),
0495     QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x18),
0496     QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0xff),
0497     QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x19),
0498     QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
0499     QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
0500     QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x98),
0501     QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x14),
0502     QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x18),
0503     QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x18),
0504     QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x65),
0505     QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x1e),
0506     QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
0507     QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
0508 
0509     /* Rate B */
0510     QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x06),
0511 };
0512 
0513 static const struct qmp_phy_init_tbl sm8350_ufsphy_tx_tbl[] = {
0514     QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
0515     QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
0516     QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
0517     QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
0518     QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xf5),
0519     QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
0520     QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x09),
0521     QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
0522     QMP_PHY_INIT_CFG(QSERDES_V5_TX_TRAN_DRVR_EMP_EN, 0x0c),
0523 };
0524 
0525 static const struct qmp_phy_init_tbl sm8350_ufsphy_rx_tbl[] = {
0526     QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_LVL, 0x24),
0527     QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x0f),
0528     QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
0529     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_BAND, 0x18),
0530     QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
0531     QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
0532     QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf1),
0533     QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
0534     QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CTRL2, 0x80),
0535     QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0e),
0536     QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x04),
0537     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_TERM_BW, 0x1b),
0538     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
0539     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
0540     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
0541     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
0542     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
0543     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
0544     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x10),
0545     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
0546     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
0547     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x6d),
0548     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x6d),
0549     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xed),
0550     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3b),
0551     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0x3c),
0552     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xe0),
0553     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xc8),
0554     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xc8),
0555     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x3b),
0556     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xb7),
0557     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_LOW, 0xe0),
0558     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH, 0xc8),
0559     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH2, 0xc8),
0560     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x3b),
0561     QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0xb7),
0562     QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c),
0563 };
0564 
0565 static const struct qmp_phy_init_tbl sm8350_ufsphy_pcs_tbl[] = {
0566     QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
0567     QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
0568     QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
0569     QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
0570     QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
0571     QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
0572     QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_PLL_CNTL, 0x03),
0573     QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB, 0x16),
0574     QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB, 0xd8),
0575     QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_PWM_GEAR_BAND, 0xaa),
0576     QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HS_GEAR_BAND, 0x06),
0577     QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x03),
0578     QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x03),
0579     QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL1, 0x0e),
0580     QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
0581 };
0582 
0583 struct qmp_phy;
0584 
0585 /* struct qmp_phy_cfg - per-PHY initialization config */
0586 struct qmp_phy_cfg {
0587     /* phy-type - PCIE/UFS/USB */
0588     unsigned int type;
0589     /* number of lanes provided by phy */
0590     int nlanes;
0591 
0592     /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
0593     const struct qmp_phy_init_tbl *serdes_tbl;
0594     int serdes_tbl_num;
0595     const struct qmp_phy_init_tbl *tx_tbl;
0596     int tx_tbl_num;
0597     const struct qmp_phy_init_tbl *rx_tbl;
0598     int rx_tbl_num;
0599     const struct qmp_phy_init_tbl *pcs_tbl;
0600     int pcs_tbl_num;
0601 
0602     /* clock ids to be requested */
0603     const char * const *clk_list;
0604     int num_clks;
0605     /* regulators to be requested */
0606     const char * const *vreg_list;
0607     int num_vregs;
0608 
0609     /* array of registers with different offsets */
0610     const unsigned int *regs;
0611 
0612     unsigned int start_ctrl;
0613     unsigned int pwrdn_ctrl;
0614     /* bit offset of PHYSTATUS in QPHY_PCS_STATUS register */
0615     unsigned int phy_status;
0616 
0617     /* true, if PHY has secondary tx/rx lanes to be configured */
0618     bool is_dual_lane_phy;
0619 
0620     /* true, if PCS block has no separate SW_RESET register */
0621     bool no_pcs_sw_reset;
0622 };
0623 
0624 /**
0625  * struct qmp_phy - per-lane phy descriptor
0626  *
0627  * @phy: generic phy
0628  * @cfg: phy specific configuration
0629  * @serdes: iomapped memory space for phy's serdes (i.e. PLL)
0630  * @tx: iomapped memory space for lane's tx
0631  * @rx: iomapped memory space for lane's rx
0632  * @pcs: iomapped memory space for lane's pcs
0633  * @tx2: iomapped memory space for second lane's tx (in dual lane PHYs)
0634  * @rx2: iomapped memory space for second lane's rx (in dual lane PHYs)
0635  * @pcs_misc: iomapped memory space for lane's pcs_misc
0636  * @index: lane index
0637  * @qmp: QMP phy to which this lane belongs
0638  * @mode: current PHY mode
0639  */
0640 struct qmp_phy {
0641     struct phy *phy;
0642     const struct qmp_phy_cfg *cfg;
0643     void __iomem *serdes;
0644     void __iomem *tx;
0645     void __iomem *rx;
0646     void __iomem *pcs;
0647     void __iomem *tx2;
0648     void __iomem *rx2;
0649     void __iomem *pcs_misc;
0650     unsigned int index;
0651     struct qcom_qmp *qmp;
0652     enum phy_mode mode;
0653 };
0654 
0655 /**
0656  * struct qcom_qmp - structure holding QMP phy block attributes
0657  *
0658  * @dev: device
0659  *
0660  * @clks: array of clocks required by phy
0661  * @resets: array of resets required by phy
0662  * @vregs: regulator supplies bulk data
0663  *
0664  * @phys: array of per-lane phy descriptors
0665  * @ufs_reset: optional UFS PHY reset handle
0666  */
0667 struct qcom_qmp {
0668     struct device *dev;
0669 
0670     struct clk_bulk_data *clks;
0671     struct regulator_bulk_data *vregs;
0672 
0673     struct qmp_phy **phys;
0674 
0675     struct reset_control *ufs_reset;
0676 };
0677 
0678 static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
0679 {
0680     u32 reg;
0681 
0682     reg = readl(base + offset);
0683     reg |= val;
0684     writel(reg, base + offset);
0685 
0686     /* ensure that above write is through */
0687     readl(base + offset);
0688 }
0689 
0690 static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
0691 {
0692     u32 reg;
0693 
0694     reg = readl(base + offset);
0695     reg &= ~val;
0696     writel(reg, base + offset);
0697 
0698     /* ensure that above write is through */
0699     readl(base + offset);
0700 }
0701 
0702 /* list of clocks required by phy */
0703 static const char * const msm8996_ufs_phy_clk_l[] = {
0704     "ref",
0705 };
0706 
0707 /* the primary usb3 phy on sm8250 doesn't have a ref clock */
0708 static const char * const sm8450_ufs_phy_clk_l[] = {
0709     "qref", "ref", "ref_aux",
0710 };
0711 
0712 static const char * const sdm845_ufs_phy_clk_l[] = {
0713     "ref", "ref_aux",
0714 };
0715 
0716 /* list of regulators */
0717 static const char * const qmp_phy_vreg_l[] = {
0718     "vdda-phy", "vdda-pll",
0719 };
0720 
0721 static const struct qmp_phy_cfg msm8996_ufs_cfg = {
0722     .type           = PHY_TYPE_UFS,
0723     .nlanes         = 1,
0724 
0725     .serdes_tbl     = msm8996_ufs_serdes_tbl,
0726     .serdes_tbl_num     = ARRAY_SIZE(msm8996_ufs_serdes_tbl),
0727     .tx_tbl         = msm8996_ufs_tx_tbl,
0728     .tx_tbl_num     = ARRAY_SIZE(msm8996_ufs_tx_tbl),
0729     .rx_tbl         = msm8996_ufs_rx_tbl,
0730     .rx_tbl_num     = ARRAY_SIZE(msm8996_ufs_rx_tbl),
0731 
0732     .clk_list       = msm8996_ufs_phy_clk_l,
0733     .num_clks       = ARRAY_SIZE(msm8996_ufs_phy_clk_l),
0734 
0735     .vreg_list      = qmp_phy_vreg_l,
0736     .num_vregs      = ARRAY_SIZE(qmp_phy_vreg_l),
0737 
0738     .regs           = msm8996_ufsphy_regs_layout,
0739 
0740     .start_ctrl     = SERDES_START,
0741     .pwrdn_ctrl     = SW_PWRDN,
0742     .phy_status     = PHYSTATUS,
0743 
0744     .no_pcs_sw_reset    = true,
0745 };
0746 
0747 static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
0748     .type           = PHY_TYPE_UFS,
0749     .nlanes         = 2,
0750 
0751     .serdes_tbl     = sdm845_ufsphy_serdes_tbl,
0752     .serdes_tbl_num     = ARRAY_SIZE(sdm845_ufsphy_serdes_tbl),
0753     .tx_tbl         = sdm845_ufsphy_tx_tbl,
0754     .tx_tbl_num     = ARRAY_SIZE(sdm845_ufsphy_tx_tbl),
0755     .rx_tbl         = sdm845_ufsphy_rx_tbl,
0756     .rx_tbl_num     = ARRAY_SIZE(sdm845_ufsphy_rx_tbl),
0757     .pcs_tbl        = sdm845_ufsphy_pcs_tbl,
0758     .pcs_tbl_num        = ARRAY_SIZE(sdm845_ufsphy_pcs_tbl),
0759     .clk_list       = sdm845_ufs_phy_clk_l,
0760     .num_clks       = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
0761     .vreg_list      = qmp_phy_vreg_l,
0762     .num_vregs      = ARRAY_SIZE(qmp_phy_vreg_l),
0763     .regs           = sdm845_ufsphy_regs_layout,
0764 
0765     .start_ctrl     = SERDES_START,
0766     .pwrdn_ctrl     = SW_PWRDN,
0767     .phy_status     = PHYSTATUS,
0768 
0769     .is_dual_lane_phy   = true,
0770     .no_pcs_sw_reset    = true,
0771 };
0772 
0773 static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
0774     .type           = PHY_TYPE_UFS,
0775     .nlanes         = 1,
0776 
0777     .serdes_tbl     = sm6115_ufsphy_serdes_tbl,
0778     .serdes_tbl_num     = ARRAY_SIZE(sm6115_ufsphy_serdes_tbl),
0779     .tx_tbl         = sm6115_ufsphy_tx_tbl,
0780     .tx_tbl_num     = ARRAY_SIZE(sm6115_ufsphy_tx_tbl),
0781     .rx_tbl         = sm6115_ufsphy_rx_tbl,
0782     .rx_tbl_num     = ARRAY_SIZE(sm6115_ufsphy_rx_tbl),
0783     .pcs_tbl        = sm6115_ufsphy_pcs_tbl,
0784     .pcs_tbl_num        = ARRAY_SIZE(sm6115_ufsphy_pcs_tbl),
0785     .clk_list       = sdm845_ufs_phy_clk_l,
0786     .num_clks       = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
0787     .vreg_list      = qmp_phy_vreg_l,
0788     .num_vregs      = ARRAY_SIZE(qmp_phy_vreg_l),
0789     .regs           = sm6115_ufsphy_regs_layout,
0790 
0791     .start_ctrl     = SERDES_START,
0792     .pwrdn_ctrl     = SW_PWRDN,
0793 
0794     .no_pcs_sw_reset    = true,
0795 };
0796 
0797 static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
0798     .type           = PHY_TYPE_UFS,
0799     .nlanes         = 2,
0800 
0801     .serdes_tbl     = sm8150_ufsphy_serdes_tbl,
0802     .serdes_tbl_num     = ARRAY_SIZE(sm8150_ufsphy_serdes_tbl),
0803     .tx_tbl         = sm8150_ufsphy_tx_tbl,
0804     .tx_tbl_num     = ARRAY_SIZE(sm8150_ufsphy_tx_tbl),
0805     .rx_tbl         = sm8150_ufsphy_rx_tbl,
0806     .rx_tbl_num     = ARRAY_SIZE(sm8150_ufsphy_rx_tbl),
0807     .pcs_tbl        = sm8150_ufsphy_pcs_tbl,
0808     .pcs_tbl_num        = ARRAY_SIZE(sm8150_ufsphy_pcs_tbl),
0809     .clk_list       = sdm845_ufs_phy_clk_l,
0810     .num_clks       = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
0811     .vreg_list      = qmp_phy_vreg_l,
0812     .num_vregs      = ARRAY_SIZE(qmp_phy_vreg_l),
0813     .regs           = sm8150_ufsphy_regs_layout,
0814 
0815     .start_ctrl     = SERDES_START,
0816     .pwrdn_ctrl     = SW_PWRDN,
0817     .phy_status     = PHYSTATUS,
0818 
0819     .is_dual_lane_phy   = true,
0820 };
0821 
0822 static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
0823     .type           = PHY_TYPE_UFS,
0824     .nlanes         = 2,
0825 
0826     .serdes_tbl     = sm8350_ufsphy_serdes_tbl,
0827     .serdes_tbl_num     = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
0828     .tx_tbl         = sm8350_ufsphy_tx_tbl,
0829     .tx_tbl_num     = ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
0830     .rx_tbl         = sm8350_ufsphy_rx_tbl,
0831     .rx_tbl_num     = ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
0832     .pcs_tbl        = sm8350_ufsphy_pcs_tbl,
0833     .pcs_tbl_num        = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
0834     .clk_list       = sdm845_ufs_phy_clk_l,
0835     .num_clks       = ARRAY_SIZE(sdm845_ufs_phy_clk_l),
0836     .vreg_list      = qmp_phy_vreg_l,
0837     .num_vregs      = ARRAY_SIZE(qmp_phy_vreg_l),
0838     .regs           = sm8150_ufsphy_regs_layout,
0839 
0840     .start_ctrl     = SERDES_START,
0841     .pwrdn_ctrl     = SW_PWRDN,
0842     .phy_status     = PHYSTATUS,
0843 
0844     .is_dual_lane_phy   = true,
0845 };
0846 
0847 static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {
0848     .type           = PHY_TYPE_UFS,
0849     .nlanes         = 2,
0850 
0851     .serdes_tbl     = sm8350_ufsphy_serdes_tbl,
0852     .serdes_tbl_num     = ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
0853     .tx_tbl         = sm8350_ufsphy_tx_tbl,
0854     .tx_tbl_num     = ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
0855     .rx_tbl         = sm8350_ufsphy_rx_tbl,
0856     .rx_tbl_num     = ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
0857     .pcs_tbl        = sm8350_ufsphy_pcs_tbl,
0858     .pcs_tbl_num        = ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
0859     .clk_list       = sm8450_ufs_phy_clk_l,
0860     .num_clks       = ARRAY_SIZE(sm8450_ufs_phy_clk_l),
0861     .vreg_list      = qmp_phy_vreg_l,
0862     .num_vregs      = ARRAY_SIZE(qmp_phy_vreg_l),
0863     .regs           = sm8150_ufsphy_regs_layout,
0864 
0865     .start_ctrl     = SERDES_START,
0866     .pwrdn_ctrl     = SW_PWRDN,
0867     .phy_status     = PHYSTATUS,
0868 
0869     .is_dual_lane_phy   = true,
0870 };
0871 
0872 static void qcom_qmp_phy_ufs_configure_lane(void __iomem *base,
0873                     const unsigned int *regs,
0874                     const struct qmp_phy_init_tbl tbl[],
0875                     int num,
0876                     u8 lane_mask)
0877 {
0878     int i;
0879     const struct qmp_phy_init_tbl *t = tbl;
0880 
0881     if (!t)
0882         return;
0883 
0884     for (i = 0; i < num; i++, t++) {
0885         if (!(t->lane_mask & lane_mask))
0886             continue;
0887 
0888         if (t->in_layout)
0889             writel(t->val, base + regs[t->offset]);
0890         else
0891             writel(t->val, base + t->offset);
0892     }
0893 }
0894 
0895 static void qcom_qmp_phy_ufs_configure(void __iomem *base,
0896                    const unsigned int *regs,
0897                    const struct qmp_phy_init_tbl tbl[],
0898                    int num)
0899 {
0900     qcom_qmp_phy_ufs_configure_lane(base, regs, tbl, num, 0xff);
0901 }
0902 
0903 static int qcom_qmp_phy_ufs_serdes_init(struct qmp_phy *qphy)
0904 {
0905     const struct qmp_phy_cfg *cfg = qphy->cfg;
0906     void __iomem *serdes = qphy->serdes;
0907     const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
0908     int serdes_tbl_num = cfg->serdes_tbl_num;
0909 
0910     qcom_qmp_phy_ufs_configure(serdes, cfg->regs, serdes_tbl, serdes_tbl_num);
0911 
0912     return 0;
0913 }
0914 
0915 static int qcom_qmp_phy_ufs_com_init(struct qmp_phy *qphy)
0916 {
0917     struct qcom_qmp *qmp = qphy->qmp;
0918     const struct qmp_phy_cfg *cfg = qphy->cfg;
0919     void __iomem *pcs = qphy->pcs;
0920     int ret;
0921 
0922     /* turn on regulator supplies */
0923     ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
0924     if (ret) {
0925         dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
0926         return ret;
0927     }
0928 
0929     ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
0930     if (ret)
0931         goto err_disable_regulators;
0932 
0933     if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL])
0934         qphy_setbits(pcs,
0935                  cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
0936                  cfg->pwrdn_ctrl);
0937     else
0938         qphy_setbits(pcs, QPHY_V2_PCS_POWER_DOWN_CONTROL,
0939                  cfg->pwrdn_ctrl);
0940 
0941     return 0;
0942 
0943 err_disable_regulators:
0944     regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
0945 
0946     return ret;
0947 }
0948 
0949 static int qcom_qmp_phy_ufs_com_exit(struct qmp_phy *qphy)
0950 {
0951     struct qcom_qmp *qmp = qphy->qmp;
0952     const struct qmp_phy_cfg *cfg = qphy->cfg;
0953 
0954     reset_control_assert(qmp->ufs_reset);
0955 
0956     clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
0957 
0958     regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
0959 
0960     return 0;
0961 }
0962 
0963 static int qcom_qmp_phy_ufs_init(struct phy *phy)
0964 {
0965     struct qmp_phy *qphy = phy_get_drvdata(phy);
0966     struct qcom_qmp *qmp = qphy->qmp;
0967     const struct qmp_phy_cfg *cfg = qphy->cfg;
0968     int ret;
0969     dev_vdbg(qmp->dev, "Initializing QMP phy\n");
0970 
0971     if (cfg->no_pcs_sw_reset) {
0972         /*
0973          * Get UFS reset, which is delayed until now to avoid a
0974          * circular dependency where UFS needs its PHY, but the PHY
0975          * needs this UFS reset.
0976          */
0977         if (!qmp->ufs_reset) {
0978             qmp->ufs_reset =
0979                 devm_reset_control_get_exclusive(qmp->dev,
0980                                  "ufsphy");
0981 
0982             if (IS_ERR(qmp->ufs_reset)) {
0983                 ret = PTR_ERR(qmp->ufs_reset);
0984                 dev_err(qmp->dev,
0985                     "failed to get UFS reset: %d\n",
0986                     ret);
0987 
0988                 qmp->ufs_reset = NULL;
0989                 return ret;
0990             }
0991         }
0992 
0993         ret = reset_control_assert(qmp->ufs_reset);
0994         if (ret)
0995             return ret;
0996     }
0997 
0998     ret = qcom_qmp_phy_ufs_com_init(qphy);
0999     if (ret)
1000         return ret;
1001 
1002     return 0;
1003 }
1004 
1005 static int qcom_qmp_phy_ufs_power_on(struct phy *phy)
1006 {
1007     struct qmp_phy *qphy = phy_get_drvdata(phy);
1008     struct qcom_qmp *qmp = qphy->qmp;
1009     const struct qmp_phy_cfg *cfg = qphy->cfg;
1010     void __iomem *tx = qphy->tx;
1011     void __iomem *rx = qphy->rx;
1012     void __iomem *pcs = qphy->pcs;
1013     void __iomem *status;
1014     unsigned int mask, val, ready;
1015     int ret;
1016 
1017     qcom_qmp_phy_ufs_serdes_init(qphy);
1018 
1019     /* Tx, Rx, and PCS configurations */
1020     qcom_qmp_phy_ufs_configure_lane(tx, cfg->regs,
1021                     cfg->tx_tbl, cfg->tx_tbl_num, 1);
1022 
1023     /* Configuration for other LANE for USB-DP combo PHY */
1024     if (cfg->is_dual_lane_phy) {
1025         qcom_qmp_phy_ufs_configure_lane(qphy->tx2, cfg->regs,
1026                         cfg->tx_tbl, cfg->tx_tbl_num, 2);
1027     }
1028 
1029     qcom_qmp_phy_ufs_configure_lane(rx, cfg->regs,
1030                     cfg->rx_tbl, cfg->rx_tbl_num, 1);
1031 
1032     if (cfg->is_dual_lane_phy) {
1033         qcom_qmp_phy_ufs_configure_lane(qphy->rx2, cfg->regs,
1034                         cfg->rx_tbl, cfg->rx_tbl_num, 2);
1035     }
1036 
1037     qcom_qmp_phy_ufs_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num);
1038 
1039     ret = reset_control_deassert(qmp->ufs_reset);
1040     if (ret)
1041         return ret;
1042 
1043     /* Pull PHY out of reset state */
1044     if (!cfg->no_pcs_sw_reset)
1045         qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
1046     /* start SerDes and Phy-Coding-Sublayer */
1047     qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
1048 
1049     status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
1050     mask = PCS_READY;
1051     ready = PCS_READY;
1052 
1053     ret = readl_poll_timeout(status, val, (val & mask) == ready, 10,
1054                  PHY_INIT_COMPLETE_TIMEOUT);
1055     if (ret) {
1056         dev_err(qmp->dev, "phy initialization timed-out\n");
1057         return ret;
1058     }
1059 
1060     return 0;
1061 }
1062 
1063 static int qcom_qmp_phy_ufs_power_off(struct phy *phy)
1064 {
1065     struct qmp_phy *qphy = phy_get_drvdata(phy);
1066     const struct qmp_phy_cfg *cfg = qphy->cfg;
1067 
1068     /* PHY reset */
1069     if (!cfg->no_pcs_sw_reset)
1070         qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
1071 
1072     /* stop SerDes and Phy-Coding-Sublayer */
1073     qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
1074 
1075     /* Put PHY into POWER DOWN state: active low */
1076     if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]) {
1077         qphy_clrbits(qphy->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
1078                  cfg->pwrdn_ctrl);
1079     } else {
1080         qphy_clrbits(qphy->pcs, QPHY_V2_PCS_POWER_DOWN_CONTROL,
1081                 cfg->pwrdn_ctrl);
1082     }
1083 
1084     return 0;
1085 }
1086 
1087 static int qcom_qmp_phy_ufs_exit(struct phy *phy)
1088 {
1089     struct qmp_phy *qphy = phy_get_drvdata(phy);
1090 
1091     qcom_qmp_phy_ufs_com_exit(qphy);
1092 
1093     return 0;
1094 }
1095 
1096 static int qcom_qmp_phy_ufs_enable(struct phy *phy)
1097 {
1098     int ret;
1099 
1100     ret = qcom_qmp_phy_ufs_init(phy);
1101     if (ret)
1102         return ret;
1103 
1104     ret = qcom_qmp_phy_ufs_power_on(phy);
1105     if (ret)
1106         qcom_qmp_phy_ufs_exit(phy);
1107 
1108     return ret;
1109 }
1110 
1111 static int qcom_qmp_phy_ufs_disable(struct phy *phy)
1112 {
1113     int ret;
1114 
1115     ret = qcom_qmp_phy_ufs_power_off(phy);
1116     if (ret)
1117         return ret;
1118     return qcom_qmp_phy_ufs_exit(phy);
1119 }
1120 
1121 static int qcom_qmp_phy_ufs_set_mode(struct phy *phy,
1122                  enum phy_mode mode, int submode)
1123 {
1124     struct qmp_phy *qphy = phy_get_drvdata(phy);
1125 
1126     qphy->mode = mode;
1127 
1128     return 0;
1129 }
1130 
1131 static int qcom_qmp_phy_ufs_vreg_init(struct device *dev, const struct qmp_phy_cfg *cfg)
1132 {
1133     struct qcom_qmp *qmp = dev_get_drvdata(dev);
1134     int num = cfg->num_vregs;
1135     int i;
1136 
1137     qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
1138     if (!qmp->vregs)
1139         return -ENOMEM;
1140 
1141     for (i = 0; i < num; i++)
1142         qmp->vregs[i].supply = cfg->vreg_list[i];
1143 
1144     return devm_regulator_bulk_get(dev, num, qmp->vregs);
1145 }
1146 
1147 static int qcom_qmp_phy_ufs_clk_init(struct device *dev, const struct qmp_phy_cfg *cfg)
1148 {
1149     struct qcom_qmp *qmp = dev_get_drvdata(dev);
1150     int num = cfg->num_clks;
1151     int i;
1152 
1153     qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
1154     if (!qmp->clks)
1155         return -ENOMEM;
1156 
1157     for (i = 0; i < num; i++)
1158         qmp->clks[i].id = cfg->clk_list[i];
1159 
1160     return devm_clk_bulk_get(dev, num, qmp->clks);
1161 }
1162 
1163 static const struct phy_ops qcom_qmp_ufs_ops = {
1164     .power_on   = qcom_qmp_phy_ufs_enable,
1165     .power_off  = qcom_qmp_phy_ufs_disable,
1166     .set_mode   = qcom_qmp_phy_ufs_set_mode,
1167     .owner      = THIS_MODULE,
1168 };
1169 
1170 static
1171 int qcom_qmp_phy_ufs_create(struct device *dev, struct device_node *np, int id,
1172             void __iomem *serdes, const struct qmp_phy_cfg *cfg)
1173 {
1174     struct qcom_qmp *qmp = dev_get_drvdata(dev);
1175     struct phy *generic_phy;
1176     struct qmp_phy *qphy;
1177     int ret;
1178 
1179     qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
1180     if (!qphy)
1181         return -ENOMEM;
1182 
1183     qphy->cfg = cfg;
1184     qphy->serdes = serdes;
1185     /*
1186      * Get memory resources for each phy lane:
1187      * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
1188      * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
1189      * For single lane PHYs: pcs_misc (optional) -> 3.
1190      */
1191     qphy->tx = of_iomap(np, 0);
1192     if (!qphy->tx)
1193         return -ENOMEM;
1194 
1195     qphy->rx = of_iomap(np, 1);
1196     if (!qphy->rx)
1197         return -ENOMEM;
1198 
1199     qphy->pcs = of_iomap(np, 2);
1200     if (!qphy->pcs)
1201         return -ENOMEM;
1202 
1203     /*
1204      * If this is a dual-lane PHY, then there should be registers for the
1205      * second lane. Some old device trees did not specify this, so fall
1206      * back to old legacy behavior of assuming they can be reached at an
1207      * offset from the first lane.
1208      */
1209     if (cfg->is_dual_lane_phy) {
1210         qphy->tx2 = of_iomap(np, 3);
1211         qphy->rx2 = of_iomap(np, 4);
1212         if (!qphy->tx2 || !qphy->rx2) {
1213             dev_warn(dev,
1214                  "Underspecified device tree, falling back to legacy register regions\n");
1215 
1216             /* In the old version, pcs_misc is at index 3. */
1217             qphy->pcs_misc = qphy->tx2;
1218             qphy->tx2 = qphy->tx + QMP_PHY_LEGACY_LANE_STRIDE;
1219             qphy->rx2 = qphy->rx + QMP_PHY_LEGACY_LANE_STRIDE;
1220 
1221         } else {
1222             qphy->pcs_misc = of_iomap(np, 5);
1223         }
1224 
1225     } else {
1226         qphy->pcs_misc = of_iomap(np, 3);
1227     }
1228 
1229     if (!qphy->pcs_misc)
1230         dev_vdbg(dev, "PHY pcs_misc-reg not used\n");
1231 
1232     generic_phy = devm_phy_create(dev, np, &qcom_qmp_ufs_ops);
1233     if (IS_ERR(generic_phy)) {
1234         ret = PTR_ERR(generic_phy);
1235         dev_err(dev, "failed to create qphy %d\n", ret);
1236         return ret;
1237     }
1238 
1239     qphy->phy = generic_phy;
1240     qphy->index = id;
1241     qphy->qmp = qmp;
1242     qmp->phys[id] = qphy;
1243     phy_set_drvdata(generic_phy, qphy);
1244 
1245     return 0;
1246 }
1247 
1248 static const struct of_device_id qcom_qmp_phy_ufs_of_match_table[] = {
1249     {
1250         .compatible = "qcom,msm8996-qmp-ufs-phy",
1251         .data = &msm8996_ufs_cfg,
1252     }, {
1253         .compatible = "qcom,msm8998-qmp-ufs-phy",
1254         .data = &sdm845_ufsphy_cfg,
1255     }, {
1256         .compatible = "qcom,sc8180x-qmp-ufs-phy",
1257         .data = &sm8150_ufsphy_cfg,
1258     }, {
1259         .compatible = "qcom,sc8280xp-qmp-ufs-phy",
1260         .data = &sm8350_ufsphy_cfg,
1261     }, {
1262         .compatible = "qcom,sdm845-qmp-ufs-phy",
1263         .data = &sdm845_ufsphy_cfg,
1264     }, {
1265         .compatible = "qcom,sm6115-qmp-ufs-phy",
1266         .data = &sm6115_ufsphy_cfg,
1267     }, {
1268         .compatible = "qcom,sm6350-qmp-ufs-phy",
1269         .data = &sdm845_ufsphy_cfg,
1270     }, {
1271         .compatible = "qcom,sm8150-qmp-ufs-phy",
1272         .data = &sm8150_ufsphy_cfg,
1273     }, {
1274         .compatible = "qcom,sm8250-qmp-ufs-phy",
1275         .data = &sm8150_ufsphy_cfg,
1276     }, {
1277         .compatible = "qcom,sm8350-qmp-ufs-phy",
1278         .data = &sm8350_ufsphy_cfg,
1279     }, {
1280         .compatible = "qcom,sm8450-qmp-ufs-phy",
1281         .data = &sm8450_ufsphy_cfg,
1282     },
1283     { },
1284 };
1285 MODULE_DEVICE_TABLE(of, qcom_qmp_phy_ufs_of_match_table);
1286 
1287 static int qcom_qmp_phy_ufs_probe(struct platform_device *pdev)
1288 {
1289     struct qcom_qmp *qmp;
1290     struct device *dev = &pdev->dev;
1291     struct device_node *child;
1292     struct phy_provider *phy_provider;
1293     void __iomem *serdes;
1294     const struct qmp_phy_cfg *cfg = NULL;
1295     int num, id;
1296     int ret;
1297 
1298     qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
1299     if (!qmp)
1300         return -ENOMEM;
1301 
1302     qmp->dev = dev;
1303     dev_set_drvdata(dev, qmp);
1304 
1305     /* Get the specific init parameters of QMP phy */
1306     cfg = of_device_get_match_data(dev);
1307     if (!cfg)
1308         return -EINVAL;
1309 
1310     /* per PHY serdes; usually located at base address */
1311     serdes = devm_platform_ioremap_resource(pdev, 0);
1312     if (IS_ERR(serdes))
1313         return PTR_ERR(serdes);
1314 
1315     ret = qcom_qmp_phy_ufs_clk_init(dev, cfg);
1316     if (ret)
1317         return ret;
1318 
1319     ret = qcom_qmp_phy_ufs_vreg_init(dev, cfg);
1320     if (ret) {
1321         if (ret != -EPROBE_DEFER)
1322             dev_err(dev, "failed to get regulator supplies: %d\n",
1323                 ret);
1324         return ret;
1325     }
1326 
1327     num = of_get_available_child_count(dev->of_node);
1328     /* do we have a rogue child node ? */
1329     if (num > 1)
1330         return -EINVAL;
1331 
1332     qmp->phys = devm_kcalloc(dev, num, sizeof(*qmp->phys), GFP_KERNEL);
1333     if (!qmp->phys)
1334         return -ENOMEM;
1335 
1336     pm_runtime_set_active(dev);
1337     pm_runtime_enable(dev);
1338     /*
1339      * Prevent runtime pm from being ON by default. Users can enable
1340      * it using power/control in sysfs.
1341      */
1342     pm_runtime_forbid(dev);
1343 
1344     id = 0;
1345     for_each_available_child_of_node(dev->of_node, child) {
1346         /* Create per-lane phy */
1347         ret = qcom_qmp_phy_ufs_create(dev, child, id, serdes, cfg);
1348         if (ret) {
1349             dev_err(dev, "failed to create lane%d phy, %d\n",
1350                 id, ret);
1351             goto err_node_put;
1352         }
1353 
1354         id++;
1355     }
1356 
1357     phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
1358     if (!IS_ERR(phy_provider))
1359         dev_info(dev, "Registered Qcom-QMP phy\n");
1360     else
1361         pm_runtime_disable(dev);
1362 
1363     return PTR_ERR_OR_ZERO(phy_provider);
1364 
1365 err_node_put:
1366     pm_runtime_disable(dev);
1367     of_node_put(child);
1368     return ret;
1369 }
1370 
1371 static struct platform_driver qcom_qmp_phy_ufs_driver = {
1372     .probe      = qcom_qmp_phy_ufs_probe,
1373     .driver = {
1374         .name   = "qcom-qmp-ufs-phy",
1375         .of_match_table = qcom_qmp_phy_ufs_of_match_table,
1376     },
1377 };
1378 
1379 module_platform_driver(qcom_qmp_phy_ufs_driver);
1380 
1381 MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
1382 MODULE_DESCRIPTION("Qualcomm QMP UFS PHY driver");
1383 MODULE_LICENSE("GPL v2");