0001
0002
0003
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
0028 #define SW_RESET BIT(0)
0029
0030 #define SW_PWRDN BIT(0)
0031 #define REFCLK_DRV_DSBL BIT(1)
0032
0033 #define SERDES_START BIT(0)
0034 #define PCS_START BIT(1)
0035 #define PLL_READY_GATE_EN BIT(3)
0036
0037 #define PHYSTATUS BIT(6)
0038 #define PHYSTATUS_4_20 BIT(7)
0039
0040 #define PCS_READY BIT(0)
0041
0042
0043
0044 #define SW_DPPHY_RESET BIT(0)
0045
0046 #define SW_DPPHY_RESET_MUX BIT(1)
0047
0048 #define SW_USB3PHY_RESET BIT(2)
0049
0050 #define SW_USB3PHY_RESET_MUX BIT(3)
0051
0052
0053 #define USB3_MODE BIT(0)
0054 #define DP_MODE BIT(1)
0055
0056
0057 #define ARCVR_DTCT_EN BIT(0)
0058 #define ALFPS_DTCT_EN BIT(1)
0059 #define ARCVR_DTCT_EVENT_SEL BIT(4)
0060
0061
0062 #define IRQ_CLEAR BIT(0)
0063
0064
0065 #define RCVR_DETECT BIT(0)
0066
0067
0068 #define CLAMP_EN BIT(0)
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
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
0084
0085
0086 bool in_layout;
0087
0088
0089
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
0117 enum qphy_reg_layout {
0118
0119 QPHY_COM_SW_RESET,
0120 QPHY_COM_POWER_DOWN_CONTROL,
0121 QPHY_COM_START_CONTROL,
0122 QPHY_COM_PCS_READY_STATUS,
0123
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
0133 QPHY_PCS_MISC_TYPEC_CTRL,
0134
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
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),
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
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
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
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
0586 struct qmp_phy_cfg {
0587
0588 unsigned int type;
0589
0590 int nlanes;
0591
0592
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
0603 const char * const *clk_list;
0604 int num_clks;
0605
0606 const char * const *vreg_list;
0607 int num_vregs;
0608
0609
0610 const unsigned int *regs;
0611
0612 unsigned int start_ctrl;
0613 unsigned int pwrdn_ctrl;
0614
0615 unsigned int phy_status;
0616
0617
0618 bool is_dual_lane_phy;
0619
0620
0621 bool no_pcs_sw_reset;
0622 };
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
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
0657
0658
0659
0660
0661
0662
0663
0664
0665
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
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
0699 readl(base + offset);
0700 }
0701
0702
0703 static const char * const msm8996_ufs_phy_clk_l[] = {
0704 "ref",
0705 };
0706
0707
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
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
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
0974
0975
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
1020 qcom_qmp_phy_ufs_configure_lane(tx, cfg->regs,
1021 cfg->tx_tbl, cfg->tx_tbl_num, 1);
1022
1023
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
1044 if (!cfg->no_pcs_sw_reset)
1045 qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
1046
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
1069 if (!cfg->no_pcs_sw_reset)
1070 qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
1071
1072
1073 qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
1074
1075
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
1187
1188
1189
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
1205
1206
1207
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
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
1306 cfg = of_device_get_match_data(dev);
1307 if (!cfg)
1308 return -EINVAL;
1309
1310
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
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
1340
1341
1342 pm_runtime_forbid(dev);
1343
1344 id = 0;
1345 for_each_available_child_of_node(dev->of_node, child) {
1346
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");