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