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