1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2017, The Linux Foundation. All rights reserved.
4  */
5 
6 #include <linux/clk.h>
7 #include <linux/clk-provider.h>
8 #include <linux/delay.h>
9 #include <linux/err.h>
10 #include <linux/io.h>
11 #include <linux/iopoll.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/of.h>
15 #include <linux/of_device.h>
16 #include <linux/of_address.h>
17 #include <linux/phy/phy.h>
18 #include <linux/platform_device.h>
19 #include <linux/regulator/consumer.h>
20 #include <linux/reset.h>
21 #include <linux/slab.h>
22 
23 #include <dt-bindings/phy/phy.h>
24 
25 #include "phy-qcom-qmp.h"
26 
27 /* QPHY_SW_RESET bit */
28 #define SW_RESET				BIT(0)
29 /* QPHY_POWER_DOWN_CONTROL */
30 #define SW_PWRDN				BIT(0)
31 /* QPHY_START_CONTROL bits */
32 #define SERDES_START				BIT(0)
33 #define PCS_START				BIT(1)
34 /* QPHY_PCS_STATUS bit */
35 #define PHYSTATUS				BIT(6)
36 /* QPHY_PCS_READY_STATUS bit */
37 #define PCS_READY				BIT(0)
38 
39 #define PHY_INIT_COMPLETE_TIMEOUT		10000
40 
41 struct qmp_phy_init_tbl {
42 	unsigned int offset;
43 	unsigned int val;
44 	/*
45 	 * register part of layout ?
46 	 * if yes, then offset gives index in the reg-layout
47 	 */
48 	bool in_layout;
49 	/*
50 	 * mask of lanes for which this register is written
51 	 * for cases when second lane needs different values
52 	 */
53 	u8 lane_mask;
54 };
55 
56 #define QMP_PHY_INIT_CFG(o, v)		\
57 	{				\
58 		.offset = o,		\
59 		.val = v,		\
60 		.lane_mask = 0xff,	\
61 	}
62 
63 #define QMP_PHY_INIT_CFG_L(o, v)	\
64 	{				\
65 		.offset = o,		\
66 		.val = v,		\
67 		.in_layout = true,	\
68 		.lane_mask = 0xff,	\
69 	}
70 
71 #define QMP_PHY_INIT_CFG_LANE(o, v, l)	\
72 	{				\
73 		.offset = o,		\
74 		.val = v,		\
75 		.lane_mask = l,		\
76 	}
77 
78 /* set of registers with offsets different per-PHY */
79 enum qphy_reg_layout {
80 	/* PCS registers */
81 	QPHY_SW_RESET,
82 	QPHY_START_CTRL,
83 	QPHY_PCS_READY_STATUS,
84 	QPHY_PCS_POWER_DOWN_CONTROL,
85 	/* Keep last to ensure regs_layout arrays are properly initialized */
86 	QPHY_LAYOUT_SIZE
87 };
88 
89 static const unsigned int msm8996_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
90 	[QPHY_START_CTRL]		= 0x00,
91 	[QPHY_PCS_READY_STATUS]		= 0x168,
92 };
93 
94 static const unsigned int sdm845_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
95 	[QPHY_START_CTRL]		= 0x00,
96 	[QPHY_PCS_READY_STATUS]		= 0x160,
97 };
98 
99 static const unsigned int sm6115_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
100 	[QPHY_START_CTRL]		= 0x00,
101 	[QPHY_PCS_READY_STATUS]		= 0x168,
102 };
103 
104 static const unsigned int sm8150_ufsphy_regs_layout[QPHY_LAYOUT_SIZE] = {
105 	[QPHY_START_CTRL]		= QPHY_V4_PCS_UFS_PHY_START,
106 	[QPHY_PCS_READY_STATUS]		= QPHY_V4_PCS_UFS_READY_STATUS,
107 	[QPHY_SW_RESET]			= QPHY_V4_PCS_UFS_SW_RESET,
108 };
109 
110 static const struct qmp_phy_init_tbl msm8996_ufs_serdes_tbl[] = {
111 	QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
112 	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xd7),
113 	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
114 	QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
115 	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
116 	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
117 	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x05),
118 	QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
119 	QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
120 	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
121 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x10),
122 	QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
123 	QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
124 	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
125 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
126 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
127 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x54),
128 	QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
129 	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
130 	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
131 	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
132 	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
133 	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
134 	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
135 	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
136 	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
137 	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
138 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
139 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
140 	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
141 	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
142 	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
143 	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
144 	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
145 	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
146 	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
147 	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
148 	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
149 	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
150 	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
151 	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
152 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
153 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
154 	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
155 	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
156 	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
157 };
158 
159 static const struct qmp_phy_init_tbl msm8996_ufs_tx_tbl[] = {
160 	QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
161 	QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x02),
162 };
163 
164 static const struct qmp_phy_init_tbl msm8996_ufs_rx_tbl[] = {
165 	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
166 	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x02),
167 	QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x00),
168 	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x18),
169 	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
170 	QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5b),
171 	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xff),
172 	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3f),
173 	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xff),
174 	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x0f),
175 	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0E),
176 };
177 
178 static const struct qmp_phy_init_tbl sm6115_ufsphy_serdes_tbl[] = {
179 	QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e),
180 	QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
181 	QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
182 	QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x02),
183 	QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
184 	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
185 	QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
186 	QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
187 	QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV_MODE1, 0x0a),
188 	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x01),
189 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00),
190 	QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x20),
191 	QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
192 	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
193 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1, 0xff),
194 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2, 0x3f),
195 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x04),
196 	QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x05),
197 	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
198 	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00),
199 	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00),
200 	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x00),
201 	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
202 	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
203 	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
204 	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
205 	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
206 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x28),
207 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x02),
208 	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xff),
209 	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x0c),
210 	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
211 	QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE1, 0x98),
212 	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE1, 0x00),
213 	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE1, 0x00),
214 	QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE1, 0x00),
215 	QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE1, 0x0b),
216 	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE1, 0x16),
217 	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE1, 0x28),
218 	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE1, 0x80),
219 	QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
220 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE1, 0xd6),
221 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE1, 0x00),
222 	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE1, 0x32),
223 	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE1, 0x0f),
224 	QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE1, 0x00),
225 	QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
226 	QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
227 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL1, 0xff),
228 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_INITVAL2, 0x00),
229 
230 	/* Rate B */
231 	QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x44),
232 };
233 
234 static const struct qmp_phy_init_tbl sm6115_ufsphy_tx_tbl[] = {
235 	QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, 0x45),
236 	QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE, 0x06),
237 };
238 
239 static const struct qmp_phy_init_tbl sm6115_ufsphy_rx_tbl[] = {
240 	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL, 0x24),
241 	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL, 0x0F),
242 	QMP_PHY_INIT_CFG(QSERDES_RX_RX_INTERFACE_MODE, 0x40),
243 	QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL, 0x1E),
244 	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN, 0x0B),
245 	QMP_PHY_INIT_CFG(QSERDES_RX_RX_TERM_BW, 0x5B),
246 	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_LSB, 0xFF),
247 	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN1_MSB, 0x3F),
248 	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_LSB, 0xFF),
249 	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_GAIN2_MSB, 0x3F),
250 	QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0D),
251 	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
252 	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
253 	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SVS_SO_GAIN, 0x04),
254 	QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5B),
255 };
256 
257 static const struct qmp_phy_init_tbl sm6115_ufsphy_pcs_tbl[] = {
258 	QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_PWM_GEAR_BAND, 0x15),
259 	QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_SIGDET_CTRL2, 0x6d),
260 	QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_LARGE_AMP_DRV_LVL, 0x0f),
261 	QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_SMALL_AMP_DRV_LVL, 0x02),
262 	QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_MIN_STALL_NOCONFIG_TIME_CAP, 0x28),
263 	QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_SYM_RESYNC_CTRL, 0x03),
264 	QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_LARGE_AMP_POST_EMP_LVL, 0x12),
265 	QMP_PHY_INIT_CFG(QPHY_V2_PCS_TX_SMALL_AMP_POST_EMP_LVL, 0x0f),
266 	QMP_PHY_INIT_CFG(QPHY_V2_PCS_RX_MIN_HIBERN8_TIME, 0x9a), /* 8 us */
267 };
268 
269 static const struct qmp_phy_init_tbl sdm845_ufsphy_serdes_tbl[] = {
270 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x02),
271 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
272 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
273 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
274 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
275 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0xd5),
276 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL, 0x20),
277 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
278 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x00),
279 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x01),
280 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_CTRL, 0x00),
281 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
282 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x04),
283 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x05),
284 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL1, 0xff),
285 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_INITVAL2, 0x00),
286 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
287 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
288 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
289 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
290 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
291 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
292 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xda),
293 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
294 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0xff),
295 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x0c),
296 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE1, 0x98),
297 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE1, 0x06),
298 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE1, 0x16),
299 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE1, 0x36),
300 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE1, 0x3f),
301 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE1, 0x00),
302 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE1, 0xc1),
303 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE1, 0x00),
304 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE1, 0x32),
305 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE1, 0x0f),
306 
307 	/* Rate B */
308 	QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x44),
309 };
310 
311 static const struct qmp_phy_init_tbl sdm845_ufsphy_tx_tbl[] = {
312 	QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x06),
313 	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x04),
314 	QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x07),
315 };
316 
317 static const struct qmp_phy_init_tbl sdm845_ufsphy_rx_tbl[] = {
318 	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_LVL, 0x24),
319 	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x0f),
320 	QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
321 	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_INTERFACE_MODE, 0x40),
322 	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
323 	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_TERM_BW, 0x5b),
324 	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
325 	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
326 	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1b),
327 	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_HALF, 0x04),
328 	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN_QUARTER, 0x04),
329 	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SVS_SO_GAIN, 0x04),
330 	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
331 	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x81),
332 	QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
333 	QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x59),
334 };
335 
336 static const struct qmp_phy_init_tbl sdm845_ufsphy_pcs_tbl[] = {
337 	QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL2, 0x6e),
338 	QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
339 	QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
340 	QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SYM_RESYNC_CTRL, 0x03),
341 	QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
342 	QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_SIGDET_CTRL1, 0x0f),
343 	QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_RX_MIN_HIBERN8_TIME, 0x9a),
344 	QMP_PHY_INIT_CFG(QPHY_V3_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
345 };
346 
347 static const struct qmp_phy_init_tbl sm8150_ufsphy_serdes_tbl[] = {
348 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL, 0xd9),
349 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL, 0x11),
350 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_HS_SWITCH_SEL, 0x00),
351 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN, 0x01),
352 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x02),
353 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_IVCO, 0x0f),
354 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_INITVAL2, 0x00),
355 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
356 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0, 0x82),
357 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0, 0x06),
358 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0, 0x16),
359 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0, 0x36),
360 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0, 0xff),
361 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0, 0x0c),
362 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
363 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
364 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1, 0x98),
365 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1, 0x06),
366 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1, 0x16),
367 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1, 0x36),
368 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1, 0x32),
369 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1, 0x0f),
370 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
371 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
372 
373 	/* Rate B */
374 	QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP, 0x06),
375 };
376 
377 static const struct qmp_phy_init_tbl sm8150_ufsphy_tx_tbl[] = {
378 	QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
379 	QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
380 	QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
381 	QMP_PHY_INIT_CFG(QSERDES_V4_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
382 	QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1, 0x05),
383 	QMP_PHY_INIT_CFG(QSERDES_V4_TX_TRAN_DRVR_EMP_EN, 0x0c),
384 };
385 
386 static const struct qmp_phy_init_tbl sm8150_ufsphy_rx_tbl[] = {
387 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_LVL, 0x24),
388 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL, 0x0f),
389 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
390 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_BAND, 0x18),
391 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
392 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x4b),
393 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS, 0xf1),
394 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
395 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CTRL2, 0x80),
396 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FO_GAIN, 0x0c),
397 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN, 0x04),
398 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_TERM_BW, 0x1b),
399 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
400 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
401 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1d),
402 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
403 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_MEASURE_TIME, 0x10),
404 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
405 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
406 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW, 0x36),
407 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH, 0x36),
408 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2, 0xf6),
409 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3, 0x3b),
410 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4, 0x3d),
411 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW, 0xe0),
412 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH, 0xc8),
413 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2, 0xc8),
414 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3, 0x3b),
415 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4, 0xb1),
416 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_LOW, 0xe0),
417 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH, 0xc8),
418 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH2, 0xc8),
419 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH3, 0x3b),
420 	QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_10_HIGH4, 0xb1),
421 
422 };
423 
424 static const struct qmp_phy_init_tbl sm8150_ufsphy_pcs_tbl[] = {
425 	QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
426 	QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
427 	QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
428 	QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
429 	QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
430 	QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
431 	QMP_PHY_INIT_CFG(QPHY_V4_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
432 };
433 
434 static const struct qmp_phy_init_tbl sm8350_ufsphy_serdes_tbl[] = {
435 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_SYSCLK_EN_SEL, 0xd9),
436 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_SEL, 0x11),
437 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_HSCLK_HS_SWITCH_SEL, 0x00),
438 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP_EN, 0x42),
439 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x02),
440 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_IVCO, 0x0f),
441 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_INITVAL2, 0x00),
442 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_HSCLK_SEL, 0x11),
443 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE0, 0x82),
444 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE0, 0x14),
445 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE0, 0x18),
446 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE0, 0x18),
447 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE0, 0xff),
448 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE0, 0x19),
449 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xac),
450 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x1e),
451 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_DEC_START_MODE1, 0x98),
452 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_CP_CTRL_MODE1, 0x14),
453 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_RCTRL_MODE1, 0x18),
454 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_PLL_CCTRL_MODE1, 0x18),
455 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP1_MODE1, 0x65),
456 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_LOCK_CMP2_MODE1, 0x1e),
457 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0xdd),
458 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x23),
459 
460 	/* Rate B */
461 	QMP_PHY_INIT_CFG(QSERDES_V5_COM_VCO_TUNE_MAP, 0x06),
462 };
463 
464 static const struct qmp_phy_init_tbl sm8350_ufsphy_tx_tbl[] = {
465 	QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_1_DIVIDER_BAND0_1, 0x06),
466 	QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_2_DIVIDER_BAND0_1, 0x03),
467 	QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_3_DIVIDER_BAND0_1, 0x01),
468 	QMP_PHY_INIT_CFG(QSERDES_V5_TX_PWM_GEAR_4_DIVIDER_BAND0_1, 0x00),
469 	QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1, 0xf5),
470 	QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3, 0x3f),
471 	QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX, 0x09),
472 	QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX, 0x09),
473 	QMP_PHY_INIT_CFG(QSERDES_V5_TX_TRAN_DRVR_EMP_EN, 0x0c),
474 };
475 
476 static const struct qmp_phy_init_tbl sm8350_ufsphy_rx_tbl[] = {
477 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_LVL, 0x24),
478 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL, 0x0f),
479 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL, 0x1e),
480 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_BAND, 0x18),
481 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN, 0x0a),
482 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x5a),
483 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS, 0xf1),
484 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW, 0x80),
485 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CTRL2, 0x80),
486 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN, 0x0e),
487 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN, 0x04),
488 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_TERM_BW, 0x1b),
489 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL1, 0x04),
490 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2, 0x06),
491 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3, 0x04),
492 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4, 0x1a),
493 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x17),
494 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x00),
495 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_MEASURE_TIME, 0x10),
496 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW, 0xc0),
497 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH, 0x00),
498 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW, 0x6d),
499 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH, 0x6d),
500 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2, 0xed),
501 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH3, 0x3b),
502 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4, 0x3c),
503 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW, 0xe0),
504 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH, 0xc8),
505 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2, 0xc8),
506 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3, 0x3b),
507 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4, 0xb7),
508 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_LOW, 0xe0),
509 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH, 0xc8),
510 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH2, 0xc8),
511 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH3, 0x3b),
512 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_10_HIGH4, 0xb7),
513 	QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1, 0x0c),
514 };
515 
516 static const struct qmp_phy_init_tbl sm8350_ufsphy_pcs_tbl[] = {
517 	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL2, 0x6d),
518 	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0a),
519 	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_SMALL_AMP_DRV_LVL, 0x02),
520 	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_MID_TERM_CTRL1, 0x43),
521 	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_DEBUG_BUS_CLKSEL, 0x1f),
522 	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_MIN_HIBERN8_TIME, 0xff),
523 	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_PLL_CNTL, 0x03),
524 	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_MSB, 0x16),
525 	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TIMER_20US_CORECLK_STEPS_LSB, 0xd8),
526 	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_PWM_GEAR_BAND, 0xaa),
527 	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HS_GEAR_BAND, 0x06),
528 	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x03),
529 	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x03),
530 	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_RX_SIGDET_CTRL1, 0x0e),
531 	QMP_PHY_INIT_CFG(QPHY_V5_PCS_UFS_MULTI_LANE_CTRL1, 0x02),
532 };
533 
534 /* struct qmp_phy_cfg - per-PHY initialization config */
535 struct qmp_phy_cfg {
536 	int lanes;
537 
538 	/* Init sequence for PHY blocks - serdes, tx, rx, pcs */
539 	const struct qmp_phy_init_tbl *serdes_tbl;
540 	int serdes_tbl_num;
541 	const struct qmp_phy_init_tbl *tx_tbl;
542 	int tx_tbl_num;
543 	const struct qmp_phy_init_tbl *rx_tbl;
544 	int rx_tbl_num;
545 	const struct qmp_phy_init_tbl *pcs_tbl;
546 	int pcs_tbl_num;
547 
548 	/* clock ids to be requested */
549 	const char * const *clk_list;
550 	int num_clks;
551 	/* regulators to be requested */
552 	const char * const *vreg_list;
553 	int num_vregs;
554 
555 	/* array of registers with different offsets */
556 	const unsigned int *regs;
557 
558 	unsigned int start_ctrl;
559 	unsigned int pwrdn_ctrl;
560 	/* bit offset of PHYSTATUS in QPHY_PCS_STATUS register */
561 	unsigned int phy_status;
562 
563 	/* true, if PCS block has no separate SW_RESET register */
564 	bool no_pcs_sw_reset;
565 };
566 
567 /**
568  * struct qmp_phy - per-lane phy descriptor
569  *
570  * @phy: generic phy
571  * @cfg: phy specific configuration
572  * @serdes: iomapped memory space for phy's serdes (i.e. PLL)
573  * @tx: iomapped memory space for lane's tx
574  * @rx: iomapped memory space for lane's rx
575  * @pcs: iomapped memory space for lane's pcs
576  * @tx2: iomapped memory space for second lane's tx (in dual lane PHYs)
577  * @rx2: iomapped memory space for second lane's rx (in dual lane PHYs)
578  * @pcs_misc: iomapped memory space for lane's pcs_misc
579  * @qmp: QMP phy to which this lane belongs
580  */
581 struct qmp_phy {
582 	struct phy *phy;
583 	const struct qmp_phy_cfg *cfg;
584 	void __iomem *serdes;
585 	void __iomem *tx;
586 	void __iomem *rx;
587 	void __iomem *pcs;
588 	void __iomem *tx2;
589 	void __iomem *rx2;
590 	void __iomem *pcs_misc;
591 	struct qcom_qmp *qmp;
592 };
593 
594 /**
595  * struct qcom_qmp - structure holding QMP phy block attributes
596  *
597  * @dev: device
598  *
599  * @clks: array of clocks required by phy
600  * @resets: array of resets required by phy
601  * @vregs: regulator supplies bulk data
602  *
603  * @phys: array of per-lane phy descriptors
604  * @ufs_reset: optional UFS PHY reset handle
605  */
606 struct qcom_qmp {
607 	struct device *dev;
608 
609 	struct clk_bulk_data *clks;
610 	struct regulator_bulk_data *vregs;
611 
612 	struct qmp_phy **phys;
613 
614 	struct reset_control *ufs_reset;
615 };
616 
617 static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
618 {
619 	u32 reg;
620 
621 	reg = readl(base + offset);
622 	reg |= val;
623 	writel(reg, base + offset);
624 
625 	/* ensure that above write is through */
626 	readl(base + offset);
627 }
628 
629 static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
630 {
631 	u32 reg;
632 
633 	reg = readl(base + offset);
634 	reg &= ~val;
635 	writel(reg, base + offset);
636 
637 	/* ensure that above write is through */
638 	readl(base + offset);
639 }
640 
641 /* list of clocks required by phy */
642 static const char * const msm8996_ufs_phy_clk_l[] = {
643 	"ref",
644 };
645 
646 /* the primary usb3 phy on sm8250 doesn't have a ref clock */
647 static const char * const sm8450_ufs_phy_clk_l[] = {
648 	"qref", "ref", "ref_aux",
649 };
650 
651 static const char * const sdm845_ufs_phy_clk_l[] = {
652 	"ref", "ref_aux",
653 };
654 
655 /* list of regulators */
656 static const char * const qmp_phy_vreg_l[] = {
657 	"vdda-phy", "vdda-pll",
658 };
659 
660 static const struct qmp_phy_cfg msm8996_ufs_cfg = {
661 	.lanes			= 1,
662 
663 	.serdes_tbl		= msm8996_ufs_serdes_tbl,
664 	.serdes_tbl_num		= ARRAY_SIZE(msm8996_ufs_serdes_tbl),
665 	.tx_tbl			= msm8996_ufs_tx_tbl,
666 	.tx_tbl_num		= ARRAY_SIZE(msm8996_ufs_tx_tbl),
667 	.rx_tbl			= msm8996_ufs_rx_tbl,
668 	.rx_tbl_num		= ARRAY_SIZE(msm8996_ufs_rx_tbl),
669 
670 	.clk_list		= msm8996_ufs_phy_clk_l,
671 	.num_clks		= ARRAY_SIZE(msm8996_ufs_phy_clk_l),
672 
673 	.vreg_list		= qmp_phy_vreg_l,
674 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
675 
676 	.regs			= msm8996_ufsphy_regs_layout,
677 
678 	.start_ctrl		= SERDES_START,
679 	.pwrdn_ctrl		= SW_PWRDN,
680 	.phy_status		= PHYSTATUS,
681 
682 	.no_pcs_sw_reset	= true,
683 };
684 
685 static const struct qmp_phy_cfg sdm845_ufsphy_cfg = {
686 	.lanes			= 2,
687 
688 	.serdes_tbl		= sdm845_ufsphy_serdes_tbl,
689 	.serdes_tbl_num		= ARRAY_SIZE(sdm845_ufsphy_serdes_tbl),
690 	.tx_tbl			= sdm845_ufsphy_tx_tbl,
691 	.tx_tbl_num		= ARRAY_SIZE(sdm845_ufsphy_tx_tbl),
692 	.rx_tbl			= sdm845_ufsphy_rx_tbl,
693 	.rx_tbl_num		= ARRAY_SIZE(sdm845_ufsphy_rx_tbl),
694 	.pcs_tbl		= sdm845_ufsphy_pcs_tbl,
695 	.pcs_tbl_num		= ARRAY_SIZE(sdm845_ufsphy_pcs_tbl),
696 	.clk_list		= sdm845_ufs_phy_clk_l,
697 	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
698 	.vreg_list		= qmp_phy_vreg_l,
699 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
700 	.regs			= sdm845_ufsphy_regs_layout,
701 
702 	.start_ctrl		= SERDES_START,
703 	.pwrdn_ctrl		= SW_PWRDN,
704 	.phy_status		= PHYSTATUS,
705 
706 	.no_pcs_sw_reset	= true,
707 };
708 
709 static const struct qmp_phy_cfg sm6115_ufsphy_cfg = {
710 	.lanes			= 1,
711 
712 	.serdes_tbl		= sm6115_ufsphy_serdes_tbl,
713 	.serdes_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_serdes_tbl),
714 	.tx_tbl			= sm6115_ufsphy_tx_tbl,
715 	.tx_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_tx_tbl),
716 	.rx_tbl			= sm6115_ufsphy_rx_tbl,
717 	.rx_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_rx_tbl),
718 	.pcs_tbl		= sm6115_ufsphy_pcs_tbl,
719 	.pcs_tbl_num		= ARRAY_SIZE(sm6115_ufsphy_pcs_tbl),
720 	.clk_list		= sdm845_ufs_phy_clk_l,
721 	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
722 	.vreg_list		= qmp_phy_vreg_l,
723 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
724 	.regs			= sm6115_ufsphy_regs_layout,
725 
726 	.start_ctrl		= SERDES_START,
727 	.pwrdn_ctrl		= SW_PWRDN,
728 
729 	.no_pcs_sw_reset	= true,
730 };
731 
732 static const struct qmp_phy_cfg sm8150_ufsphy_cfg = {
733 	.lanes			= 2,
734 
735 	.serdes_tbl		= sm8150_ufsphy_serdes_tbl,
736 	.serdes_tbl_num		= ARRAY_SIZE(sm8150_ufsphy_serdes_tbl),
737 	.tx_tbl			= sm8150_ufsphy_tx_tbl,
738 	.tx_tbl_num		= ARRAY_SIZE(sm8150_ufsphy_tx_tbl),
739 	.rx_tbl			= sm8150_ufsphy_rx_tbl,
740 	.rx_tbl_num		= ARRAY_SIZE(sm8150_ufsphy_rx_tbl),
741 	.pcs_tbl		= sm8150_ufsphy_pcs_tbl,
742 	.pcs_tbl_num		= ARRAY_SIZE(sm8150_ufsphy_pcs_tbl),
743 	.clk_list		= sdm845_ufs_phy_clk_l,
744 	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
745 	.vreg_list		= qmp_phy_vreg_l,
746 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
747 	.regs			= sm8150_ufsphy_regs_layout,
748 
749 	.start_ctrl		= SERDES_START,
750 	.pwrdn_ctrl		= SW_PWRDN,
751 	.phy_status		= PHYSTATUS,
752 };
753 
754 static const struct qmp_phy_cfg sm8350_ufsphy_cfg = {
755 	.lanes			= 2,
756 
757 	.serdes_tbl		= sm8350_ufsphy_serdes_tbl,
758 	.serdes_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
759 	.tx_tbl			= sm8350_ufsphy_tx_tbl,
760 	.tx_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
761 	.rx_tbl			= sm8350_ufsphy_rx_tbl,
762 	.rx_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
763 	.pcs_tbl		= sm8350_ufsphy_pcs_tbl,
764 	.pcs_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
765 	.clk_list		= sdm845_ufs_phy_clk_l,
766 	.num_clks		= ARRAY_SIZE(sdm845_ufs_phy_clk_l),
767 	.vreg_list		= qmp_phy_vreg_l,
768 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
769 	.regs			= sm8150_ufsphy_regs_layout,
770 
771 	.start_ctrl		= SERDES_START,
772 	.pwrdn_ctrl		= SW_PWRDN,
773 	.phy_status		= PHYSTATUS,
774 };
775 
776 static const struct qmp_phy_cfg sm8450_ufsphy_cfg = {
777 	.lanes			= 2,
778 
779 	.serdes_tbl		= sm8350_ufsphy_serdes_tbl,
780 	.serdes_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_serdes_tbl),
781 	.tx_tbl			= sm8350_ufsphy_tx_tbl,
782 	.tx_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_tx_tbl),
783 	.rx_tbl			= sm8350_ufsphy_rx_tbl,
784 	.rx_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_rx_tbl),
785 	.pcs_tbl		= sm8350_ufsphy_pcs_tbl,
786 	.pcs_tbl_num		= ARRAY_SIZE(sm8350_ufsphy_pcs_tbl),
787 	.clk_list		= sm8450_ufs_phy_clk_l,
788 	.num_clks		= ARRAY_SIZE(sm8450_ufs_phy_clk_l),
789 	.vreg_list		= qmp_phy_vreg_l,
790 	.num_vregs		= ARRAY_SIZE(qmp_phy_vreg_l),
791 	.regs			= sm8150_ufsphy_regs_layout,
792 
793 	.start_ctrl		= SERDES_START,
794 	.pwrdn_ctrl		= SW_PWRDN,
795 	.phy_status		= PHYSTATUS,
796 };
797 
798 static void qmp_ufs_configure_lane(void __iomem *base,
799 					const unsigned int *regs,
800 					const struct qmp_phy_init_tbl tbl[],
801 					int num,
802 					u8 lane_mask)
803 {
804 	int i;
805 	const struct qmp_phy_init_tbl *t = tbl;
806 
807 	if (!t)
808 		return;
809 
810 	for (i = 0; i < num; i++, t++) {
811 		if (!(t->lane_mask & lane_mask))
812 			continue;
813 
814 		if (t->in_layout)
815 			writel(t->val, base + regs[t->offset]);
816 		else
817 			writel(t->val, base + t->offset);
818 	}
819 }
820 
821 static void qmp_ufs_configure(void __iomem *base,
822 				   const unsigned int *regs,
823 				   const struct qmp_phy_init_tbl tbl[],
824 				   int num)
825 {
826 	qmp_ufs_configure_lane(base, regs, tbl, num, 0xff);
827 }
828 
829 static int qmp_ufs_serdes_init(struct qmp_phy *qphy)
830 {
831 	const struct qmp_phy_cfg *cfg = qphy->cfg;
832 	void __iomem *serdes = qphy->serdes;
833 	const struct qmp_phy_init_tbl *serdes_tbl = cfg->serdes_tbl;
834 	int serdes_tbl_num = cfg->serdes_tbl_num;
835 
836 	qmp_ufs_configure(serdes, cfg->regs, serdes_tbl, serdes_tbl_num);
837 
838 	return 0;
839 }
840 
841 static int qmp_ufs_com_init(struct qmp_phy *qphy)
842 {
843 	struct qcom_qmp *qmp = qphy->qmp;
844 	const struct qmp_phy_cfg *cfg = qphy->cfg;
845 	void __iomem *pcs = qphy->pcs;
846 	int ret;
847 
848 	/* turn on regulator supplies */
849 	ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
850 	if (ret) {
851 		dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
852 		return ret;
853 	}
854 
855 	ret = clk_bulk_prepare_enable(cfg->num_clks, qmp->clks);
856 	if (ret)
857 		goto err_disable_regulators;
858 
859 	if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL])
860 		qphy_setbits(pcs,
861 			     cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
862 			     cfg->pwrdn_ctrl);
863 	else
864 		qphy_setbits(pcs, QPHY_V2_PCS_POWER_DOWN_CONTROL,
865 			     cfg->pwrdn_ctrl);
866 
867 	return 0;
868 
869 err_disable_regulators:
870 	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
871 
872 	return ret;
873 }
874 
875 static int qmp_ufs_com_exit(struct qmp_phy *qphy)
876 {
877 	struct qcom_qmp *qmp = qphy->qmp;
878 	const struct qmp_phy_cfg *cfg = qphy->cfg;
879 
880 	reset_control_assert(qmp->ufs_reset);
881 
882 	clk_bulk_disable_unprepare(cfg->num_clks, qmp->clks);
883 
884 	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
885 
886 	return 0;
887 }
888 
889 static int qmp_ufs_init(struct phy *phy)
890 {
891 	struct qmp_phy *qphy = phy_get_drvdata(phy);
892 	struct qcom_qmp *qmp = qphy->qmp;
893 	const struct qmp_phy_cfg *cfg = qphy->cfg;
894 	int ret;
895 	dev_vdbg(qmp->dev, "Initializing QMP phy\n");
896 
897 	if (cfg->no_pcs_sw_reset) {
898 		/*
899 		 * Get UFS reset, which is delayed until now to avoid a
900 		 * circular dependency where UFS needs its PHY, but the PHY
901 		 * needs this UFS reset.
902 		 */
903 		if (!qmp->ufs_reset) {
904 			qmp->ufs_reset =
905 				devm_reset_control_get_exclusive(qmp->dev,
906 								 "ufsphy");
907 
908 			if (IS_ERR(qmp->ufs_reset)) {
909 				ret = PTR_ERR(qmp->ufs_reset);
910 				dev_err(qmp->dev,
911 					"failed to get UFS reset: %d\n",
912 					ret);
913 
914 				qmp->ufs_reset = NULL;
915 				return ret;
916 			}
917 		}
918 
919 		ret = reset_control_assert(qmp->ufs_reset);
920 		if (ret)
921 			return ret;
922 	}
923 
924 	ret = qmp_ufs_com_init(qphy);
925 	if (ret)
926 		return ret;
927 
928 	return 0;
929 }
930 
931 static int qmp_ufs_power_on(struct phy *phy)
932 {
933 	struct qmp_phy *qphy = phy_get_drvdata(phy);
934 	struct qcom_qmp *qmp = qphy->qmp;
935 	const struct qmp_phy_cfg *cfg = qphy->cfg;
936 	void __iomem *tx = qphy->tx;
937 	void __iomem *rx = qphy->rx;
938 	void __iomem *pcs = qphy->pcs;
939 	void __iomem *status;
940 	unsigned int mask, val, ready;
941 	int ret;
942 
943 	qmp_ufs_serdes_init(qphy);
944 
945 	/* Tx, Rx, and PCS configurations */
946 	qmp_ufs_configure_lane(tx, cfg->regs, cfg->tx_tbl, cfg->tx_tbl_num, 1);
947 
948 	if (cfg->lanes >= 2) {
949 		qmp_ufs_configure_lane(qphy->tx2, cfg->regs,
950 					cfg->tx_tbl, cfg->tx_tbl_num, 2);
951 	}
952 
953 	qmp_ufs_configure_lane(rx, cfg->regs, cfg->rx_tbl, cfg->rx_tbl_num, 1);
954 
955 	if (cfg->lanes >= 2) {
956 		qmp_ufs_configure_lane(qphy->rx2, cfg->regs,
957 					cfg->rx_tbl, cfg->rx_tbl_num, 2);
958 	}
959 
960 	qmp_ufs_configure(pcs, cfg->regs, cfg->pcs_tbl, cfg->pcs_tbl_num);
961 
962 	ret = reset_control_deassert(qmp->ufs_reset);
963 	if (ret)
964 		return ret;
965 
966 	/* Pull PHY out of reset state */
967 	if (!cfg->no_pcs_sw_reset)
968 		qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
969 	/* start SerDes and Phy-Coding-Sublayer */
970 	qphy_setbits(pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
971 
972 	status = pcs + cfg->regs[QPHY_PCS_READY_STATUS];
973 	mask = PCS_READY;
974 	ready = PCS_READY;
975 
976 	ret = readl_poll_timeout(status, val, (val & mask) == ready, 10,
977 				 PHY_INIT_COMPLETE_TIMEOUT);
978 	if (ret) {
979 		dev_err(qmp->dev, "phy initialization timed-out\n");
980 		return ret;
981 	}
982 
983 	return 0;
984 }
985 
986 static int qmp_ufs_power_off(struct phy *phy)
987 {
988 	struct qmp_phy *qphy = phy_get_drvdata(phy);
989 	const struct qmp_phy_cfg *cfg = qphy->cfg;
990 
991 	/* PHY reset */
992 	if (!cfg->no_pcs_sw_reset)
993 		qphy_setbits(qphy->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
994 
995 	/* stop SerDes and Phy-Coding-Sublayer */
996 	qphy_clrbits(qphy->pcs, cfg->regs[QPHY_START_CTRL], cfg->start_ctrl);
997 
998 	/* Put PHY into POWER DOWN state: active low */
999 	if (cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL]) {
1000 		qphy_clrbits(qphy->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
1001 			     cfg->pwrdn_ctrl);
1002 	} else {
1003 		qphy_clrbits(qphy->pcs, QPHY_V2_PCS_POWER_DOWN_CONTROL,
1004 				cfg->pwrdn_ctrl);
1005 	}
1006 
1007 	return 0;
1008 }
1009 
1010 static int qmp_ufs_exit(struct phy *phy)
1011 {
1012 	struct qmp_phy *qphy = phy_get_drvdata(phy);
1013 
1014 	qmp_ufs_com_exit(qphy);
1015 
1016 	return 0;
1017 }
1018 
1019 static int qmp_ufs_enable(struct phy *phy)
1020 {
1021 	int ret;
1022 
1023 	ret = qmp_ufs_init(phy);
1024 	if (ret)
1025 		return ret;
1026 
1027 	ret = qmp_ufs_power_on(phy);
1028 	if (ret)
1029 		qmp_ufs_exit(phy);
1030 
1031 	return ret;
1032 }
1033 
1034 static int qmp_ufs_disable(struct phy *phy)
1035 {
1036 	int ret;
1037 
1038 	ret = qmp_ufs_power_off(phy);
1039 	if (ret)
1040 		return ret;
1041 	return qmp_ufs_exit(phy);
1042 }
1043 
1044 static int qmp_ufs_vreg_init(struct device *dev, const struct qmp_phy_cfg *cfg)
1045 {
1046 	struct qcom_qmp *qmp = dev_get_drvdata(dev);
1047 	int num = cfg->num_vregs;
1048 	int i;
1049 
1050 	qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
1051 	if (!qmp->vregs)
1052 		return -ENOMEM;
1053 
1054 	for (i = 0; i < num; i++)
1055 		qmp->vregs[i].supply = cfg->vreg_list[i];
1056 
1057 	return devm_regulator_bulk_get(dev, num, qmp->vregs);
1058 }
1059 
1060 static int qmp_ufs_clk_init(struct device *dev, const struct qmp_phy_cfg *cfg)
1061 {
1062 	struct qcom_qmp *qmp = dev_get_drvdata(dev);
1063 	int num = cfg->num_clks;
1064 	int i;
1065 
1066 	qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
1067 	if (!qmp->clks)
1068 		return -ENOMEM;
1069 
1070 	for (i = 0; i < num; i++)
1071 		qmp->clks[i].id = cfg->clk_list[i];
1072 
1073 	return devm_clk_bulk_get(dev, num, qmp->clks);
1074 }
1075 
1076 static const struct phy_ops qcom_qmp_ufs_ops = {
1077 	.power_on	= qmp_ufs_enable,
1078 	.power_off	= qmp_ufs_disable,
1079 	.owner		= THIS_MODULE,
1080 };
1081 
1082 static int qmp_ufs_create(struct device *dev, struct device_node *np, int id,
1083 			void __iomem *serdes, const struct qmp_phy_cfg *cfg)
1084 {
1085 	struct qcom_qmp *qmp = dev_get_drvdata(dev);
1086 	struct phy *generic_phy;
1087 	struct qmp_phy *qphy;
1088 	int ret;
1089 
1090 	qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
1091 	if (!qphy)
1092 		return -ENOMEM;
1093 
1094 	qphy->cfg = cfg;
1095 	qphy->serdes = serdes;
1096 	/*
1097 	 * Get memory resources for each phy lane:
1098 	 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
1099 	 * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
1100 	 * For single lane PHYs: pcs_misc (optional) -> 3.
1101 	 */
1102 	qphy->tx = devm_of_iomap(dev, np, 0, NULL);
1103 	if (IS_ERR(qphy->tx))
1104 		return PTR_ERR(qphy->tx);
1105 
1106 	qphy->rx = devm_of_iomap(dev, np, 1, NULL);
1107 	if (IS_ERR(qphy->rx))
1108 		return PTR_ERR(qphy->rx);
1109 
1110 	qphy->pcs = devm_of_iomap(dev, np, 2, NULL);
1111 	if (IS_ERR(qphy->pcs))
1112 		return PTR_ERR(qphy->pcs);
1113 
1114 	if (cfg->lanes >= 2) {
1115 		qphy->tx2 = devm_of_iomap(dev, np, 3, NULL);
1116 		if (IS_ERR(qphy->tx2))
1117 			return PTR_ERR(qphy->tx2);
1118 
1119 		qphy->rx2 = devm_of_iomap(dev, np, 4, NULL);
1120 		if (IS_ERR(qphy->rx2))
1121 			return PTR_ERR(qphy->rx2);
1122 
1123 		qphy->pcs_misc = devm_of_iomap(dev, np, 5, NULL);
1124 	} else {
1125 		qphy->pcs_misc = devm_of_iomap(dev, np, 3, NULL);
1126 	}
1127 
1128 	if (IS_ERR(qphy->pcs_misc))
1129 		dev_vdbg(dev, "PHY pcs_misc-reg not used\n");
1130 
1131 	generic_phy = devm_phy_create(dev, np, &qcom_qmp_ufs_ops);
1132 	if (IS_ERR(generic_phy)) {
1133 		ret = PTR_ERR(generic_phy);
1134 		dev_err(dev, "failed to create qphy %d\n", ret);
1135 		return ret;
1136 	}
1137 
1138 	qphy->phy = generic_phy;
1139 	qphy->qmp = qmp;
1140 	qmp->phys[id] = qphy;
1141 	phy_set_drvdata(generic_phy, qphy);
1142 
1143 	return 0;
1144 }
1145 
1146 static const struct of_device_id qmp_ufs_of_match_table[] = {
1147 	{
1148 		.compatible = "qcom,msm8996-qmp-ufs-phy",
1149 		.data = &msm8996_ufs_cfg,
1150 	}, {
1151 		.compatible = "qcom,msm8998-qmp-ufs-phy",
1152 		.data = &sdm845_ufsphy_cfg,
1153 	}, {
1154 		.compatible = "qcom,sc8180x-qmp-ufs-phy",
1155 		.data = &sm8150_ufsphy_cfg,
1156 	}, {
1157 		.compatible = "qcom,sc8280xp-qmp-ufs-phy",
1158 		.data = &sm8350_ufsphy_cfg,
1159 	}, {
1160 		.compatible = "qcom,sdm845-qmp-ufs-phy",
1161 		.data = &sdm845_ufsphy_cfg,
1162 	}, {
1163 		.compatible = "qcom,sm6115-qmp-ufs-phy",
1164 		.data = &sm6115_ufsphy_cfg,
1165 	}, {
1166 		.compatible = "qcom,sm6350-qmp-ufs-phy",
1167 		.data = &sdm845_ufsphy_cfg,
1168 	}, {
1169 		.compatible = "qcom,sm8150-qmp-ufs-phy",
1170 		.data = &sm8150_ufsphy_cfg,
1171 	}, {
1172 		.compatible = "qcom,sm8250-qmp-ufs-phy",
1173 		.data = &sm8150_ufsphy_cfg,
1174 	}, {
1175 		.compatible = "qcom,sm8350-qmp-ufs-phy",
1176 		.data = &sm8350_ufsphy_cfg,
1177 	}, {
1178 		.compatible = "qcom,sm8450-qmp-ufs-phy",
1179 		.data = &sm8450_ufsphy_cfg,
1180 	},
1181 	{ },
1182 };
1183 MODULE_DEVICE_TABLE(of, qmp_ufs_of_match_table);
1184 
1185 static int qmp_ufs_probe(struct platform_device *pdev)
1186 {
1187 	struct qcom_qmp *qmp;
1188 	struct device *dev = &pdev->dev;
1189 	struct device_node *child;
1190 	struct phy_provider *phy_provider;
1191 	void __iomem *serdes;
1192 	const struct qmp_phy_cfg *cfg = NULL;
1193 	int num, id;
1194 	int ret;
1195 
1196 	qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
1197 	if (!qmp)
1198 		return -ENOMEM;
1199 
1200 	qmp->dev = dev;
1201 	dev_set_drvdata(dev, qmp);
1202 
1203 	/* Get the specific init parameters of QMP phy */
1204 	cfg = of_device_get_match_data(dev);
1205 	if (!cfg)
1206 		return -EINVAL;
1207 
1208 	/* per PHY serdes; usually located at base address */
1209 	serdes = devm_platform_ioremap_resource(pdev, 0);
1210 	if (IS_ERR(serdes))
1211 		return PTR_ERR(serdes);
1212 
1213 	ret = qmp_ufs_clk_init(dev, cfg);
1214 	if (ret)
1215 		return ret;
1216 
1217 	ret = qmp_ufs_vreg_init(dev, cfg);
1218 	if (ret)
1219 		return dev_err_probe(dev, ret,
1220 				     "failed to get regulator supplies\n");
1221 
1222 	num = of_get_available_child_count(dev->of_node);
1223 	/* do we have a rogue child node ? */
1224 	if (num > 1)
1225 		return -EINVAL;
1226 
1227 	qmp->phys = devm_kcalloc(dev, num, sizeof(*qmp->phys), GFP_KERNEL);
1228 	if (!qmp->phys)
1229 		return -ENOMEM;
1230 
1231 	id = 0;
1232 	for_each_available_child_of_node(dev->of_node, child) {
1233 		/* Create per-lane phy */
1234 		ret = qmp_ufs_create(dev, child, id, serdes, cfg);
1235 		if (ret) {
1236 			dev_err(dev, "failed to create lane%d phy, %d\n",
1237 				id, ret);
1238 			goto err_node_put;
1239 		}
1240 
1241 		id++;
1242 	}
1243 
1244 	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
1245 
1246 	return PTR_ERR_OR_ZERO(phy_provider);
1247 
1248 err_node_put:
1249 	of_node_put(child);
1250 	return ret;
1251 }
1252 
1253 static struct platform_driver qmp_ufs_driver = {
1254 	.probe		= qmp_ufs_probe,
1255 	.driver = {
1256 		.name	= "qcom-qmp-ufs-phy",
1257 		.of_match_table = qmp_ufs_of_match_table,
1258 	},
1259 };
1260 
1261 module_platform_driver(qmp_ufs_driver);
1262 
1263 MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
1264 MODULE_DESCRIPTION("Qualcomm QMP UFS PHY driver");
1265 MODULE_LICENSE("GPL v2");
1266