1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
7 #include <linux/clk-provider.h>
8 #include <linux/delay.h>
11 #include <linux/iopoll.h>
12 #include <linux/kernel.h>
13 #include <linux/mfd/syscon.h>
14 #include <linux/module.h>
16 #include <linux/of_address.h>
17 #include <linux/phy/phy.h>
18 #include <linux/platform_device.h>
19 #include <linux/regmap.h>
20 #include <linux/regulator/consumer.h>
21 #include <linux/reset.h>
22 #include <linux/slab.h>
23 #include <linux/usb/typec.h>
24 #include <linux/usb/typec_mux.h>
26 #include "phy-qcom-qmp.h"
27 #include "phy-qcom-qmp-pcs-misc-v3.h"
29 /* QPHY_SW_RESET bit */
30 #define SW_RESET BIT(0)
31 /* QPHY_POWER_DOWN_CONTROL */
32 #define SW_PWRDN BIT(0)
33 /* QPHY_START_CONTROL bits */
34 #define SERDES_START BIT(0)
35 #define PCS_START BIT(1)
36 /* QPHY_PCS_STATUS bit */
37 #define PHYSTATUS BIT(6)
39 /* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
40 /* DP PHY soft reset */
41 #define SW_DPPHY_RESET BIT(0)
42 /* mux to select DP PHY reset control, 0:HW control, 1: software reset */
43 #define SW_DPPHY_RESET_MUX BIT(1)
44 /* USB3 PHY soft reset */
45 #define SW_USB3PHY_RESET BIT(2)
46 /* mux to select USB3 PHY reset control, 0:HW control, 1: software reset */
47 #define SW_USB3PHY_RESET_MUX BIT(3)
49 /* QPHY_V3_DP_COM_PHY_MODE_CTRL register bits */
50 #define USB3_MODE BIT(0) /* enables USB3 mode */
51 #define DP_MODE BIT(1) /* enables DP mode */
53 /* QPHY_PCS_AUTONOMOUS_MODE_CTRL register bits */
54 #define ARCVR_DTCT_EN BIT(0)
55 #define ALFPS_DTCT_EN BIT(1)
56 #define ARCVR_DTCT_EVENT_SEL BIT(4)
58 /* QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR register bits */
59 #define IRQ_CLEAR BIT(0)
61 #define PHY_INIT_COMPLETE_TIMEOUT 10000
63 struct qmp_phy_init_tbl {
67 * mask of lanes for which this register is written
68 * for cases when second lane needs different values
73 #define QMP_PHY_INIT_CFG(o, v) \
80 #define QMP_PHY_INIT_CFG_LANE(o, v, l) \
87 /* set of registers with offsets different per-PHY */
88 enum qphy_reg_layout {
93 QPHY_PCS_AUTONOMOUS_MODE_CTRL,
94 QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR,
95 QPHY_PCS_POWER_DOWN_CONTROL,
96 /* Keep last to ensure regs_layout arrays are properly initialized */
100 static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = {
101 [QPHY_SW_RESET] = QPHY_V3_PCS_SW_RESET,
102 [QPHY_START_CTRL] = QPHY_V3_PCS_START_CONTROL,
103 [QPHY_PCS_STATUS] = QPHY_V3_PCS_PCS_STATUS,
104 [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL,
105 [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR,
106 [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V3_PCS_POWER_DOWN_CONTROL,
109 static const unsigned int qmp_v3_usb3phy_regs_layout_qcm2290[QPHY_LAYOUT_SIZE] = {
110 [QPHY_SW_RESET] = QPHY_V3_PCS_SW_RESET,
111 [QPHY_START_CTRL] = QPHY_V3_PCS_START_CONTROL,
112 [QPHY_PCS_STATUS] = QPHY_V3_PCS_PCS_STATUS,
113 [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL,
114 [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR,
115 [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V3_PCS_POWER_DOWN_CONTROL,
118 static const struct qmp_phy_init_tbl msm8998_usb3_serdes_tbl[] = {
119 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT, 0x30),
120 QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN, 0x04),
121 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14),
122 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL, 0x06),
123 QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2, 0x08),
124 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG, 0x06),
125 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL, 0x01),
126 QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL, 0x80),
127 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0, 0x82),
128 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0, 0xab),
129 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0, 0xea),
130 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0, 0x02),
131 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0, 0x06),
132 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0, 0x16),
133 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0, 0x36),
134 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
135 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0, 0x3f),
136 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0, 0x01),
137 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0, 0xc9),
138 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0, 0x0a),
139 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0, 0x00),
140 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0, 0x34),
141 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0, 0x15),
142 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN, 0x04),
143 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN, 0x00),
144 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG, 0x00),
145 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP, 0x00),
146 QMP_PHY_INIT_CFG(QSERDES_V3_COM_BG_TIMER, 0x0a),
147 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07),
148 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_INITVAL, 0x80),
149 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_MODE, 0x01),
150 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER, 0x01),
151 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1, 0x31),
152 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2, 0x01),
153 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1, 0x00),
154 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2, 0x00),
155 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1, 0x85),
156 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2, 0x07),
159 static const struct qmp_phy_init_tbl msm8998_usb3_tx_tbl[] = {
160 QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
161 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
162 QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0x16),
163 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
166 static const struct qmp_phy_init_tbl msm8998_usb3_rx_tbl[] = {
167 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
168 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0f),
169 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
170 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
171 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x07),
172 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
173 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x43),
174 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x1c),
175 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
176 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00),
177 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00),
178 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x80),
179 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a),
180 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06),
181 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00),
182 QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x03),
183 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x05),
186 static const struct qmp_phy_init_tbl msm8998_usb3_pcs_tbl[] = {
187 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
188 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
189 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
190 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x40),
191 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
192 QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
193 QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
194 QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
195 QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2, 0x1b),
196 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
197 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1, 0x9f),
198 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2, 0xb7),
199 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3, 0x4e),
200 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4, 0x65),
201 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS, 0x6b),
202 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x15),
203 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0d),
204 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1, 0x15),
205 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1, 0x0d),
206 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2, 0x15),
207 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2, 0x0d),
208 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3, 0x15),
209 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3, 0x0d),
210 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4, 0x15),
211 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4, 0x0d),
212 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS, 0x15),
213 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS, 0x0d),
214 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL, 0x02),
215 QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
216 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
217 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
218 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
219 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
220 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
221 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x8a),
222 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
223 QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
224 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
227 static const struct qmp_phy_init_tbl qcm2290_usb3_serdes_tbl[] = {
228 QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x14),
229 QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08),
230 QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30),
231 QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06),
232 QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL, 0x00),
233 QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL2, 0x08),
234 QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM, 0x0f),
235 QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01),
236 QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x00),
237 QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x82),
238 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x55),
239 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x55),
240 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x03),
241 QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b),
242 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16),
243 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28),
244 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x80),
245 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00),
246 QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x0a),
247 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x15),
248 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x34),
249 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00),
250 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN, 0x00),
251 QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x00),
252 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG, 0x00),
253 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00),
254 QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x0a),
255 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER, 0x01),
256 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1, 0x31),
257 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2, 0x01),
258 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1, 0x00),
259 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2, 0x00),
260 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1, 0xde),
261 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2, 0x07),
262 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f),
263 QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x06),
264 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_INITVAL, 0x80),
265 QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM, 0x01),
268 static const struct qmp_phy_init_tbl qcm2290_usb3_tx_tbl[] = {
269 QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN, 0x10),
270 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2, 0x12),
271 QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1, 0xc6),
272 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX, 0x00),
273 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX, 0x00),
276 static const struct qmp_phy_init_tbl qcm2290_usb3_rx_tbl[] = {
277 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN, 0x0b),
278 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_PI_CONTROLS, 0x80),
279 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_LOW, 0x00),
280 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x00),
281 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FO_GAIN, 0x0a),
282 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_GAIN, 0x06),
283 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x75),
284 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2, 0x02),
285 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4e),
286 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4, 0x18),
287 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x77),
288 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2, 0x80),
289 QMP_PHY_INIT_CFG(QSERDES_V3_RX_VGA_CAL_CNTRL2, 0x0a),
290 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL, 0x03),
291 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL, 0x16),
292 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_ENABLES, 0x00),
293 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_MODE_00, 0x00),
296 static const struct qmp_phy_init_tbl qcm2290_usb3_pcs_tbl[] = {
297 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0, 0x9f),
298 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0, 0x17),
299 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0, 0x0f),
300 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2, 0x83),
301 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1, 0x02),
302 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L, 0x09),
303 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL, 0xa2),
304 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE, 0x85),
305 QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1, 0xd1),
306 QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2, 0x1f),
307 QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3, 0x47),
308 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME, 0x75),
309 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME, 0x13),
310 QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK, 0x86),
311 QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK, 0x04),
312 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME, 0x44),
313 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7),
314 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03),
315 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L, 0x40),
316 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H, 0x00),
317 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88),
320 struct qmp_usbc_offsets {
326 /* for PHYs with >= 2 lanes */
331 /* struct qmp_phy_cfg - per-PHY initialization config */
333 const struct qmp_usbc_offsets *offsets;
335 /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
336 const struct qmp_phy_init_tbl *serdes_tbl;
338 const struct qmp_phy_init_tbl *tx_tbl;
340 const struct qmp_phy_init_tbl *rx_tbl;
342 const struct qmp_phy_init_tbl *pcs_tbl;
345 /* regulators to be requested */
346 const char * const *vreg_list;
349 /* array of registers with different offsets */
350 const unsigned int *regs;
352 /* true, if PHY needs delay after POWER_DOWN */
353 bool has_pwrdn_delay;
359 const struct qmp_phy_cfg *cfg;
361 void __iomem *serdes;
363 void __iomem *pcs_misc;
369 struct regmap *tcsr_map;
372 struct clk *pipe_clk;
373 struct clk_bulk_data *clks;
376 struct reset_control_bulk_data *resets;
377 struct regulator_bulk_data *vregs;
379 struct mutex phy_mutex;
382 unsigned int usb_init_count;
386 struct clk_fixed_rate pipe_clk_fixed;
388 struct typec_switch_dev *sw;
389 enum typec_orientation orientation;
392 static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
396 reg = readl(base + offset);
398 writel(reg, base + offset);
400 /* ensure that above write is through */
401 readl(base + offset);
404 static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val)
408 reg = readl(base + offset);
410 writel(reg, base + offset);
412 /* ensure that above write is through */
413 readl(base + offset);
416 /* list of clocks required by phy */
417 static const char * const qmp_usbc_phy_clk_l[] = {
418 "aux", "cfg_ahb", "ref", "com_aux",
422 static const char * const usb3phy_legacy_reset_l[] = {
426 static const char * const usb3phy_reset_l[] = {
430 /* list of regulators */
431 static const char * const qmp_phy_vreg_l[] = {
432 "vdda-phy", "vdda-pll",
435 static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = {
445 static const struct qmp_phy_cfg msm8998_usb3phy_cfg = {
446 .offsets = &qmp_usbc_offsets_v3_qcm2290,
448 .serdes_tbl = msm8998_usb3_serdes_tbl,
449 .serdes_tbl_num = ARRAY_SIZE(msm8998_usb3_serdes_tbl),
450 .tx_tbl = msm8998_usb3_tx_tbl,
451 .tx_tbl_num = ARRAY_SIZE(msm8998_usb3_tx_tbl),
452 .rx_tbl = msm8998_usb3_rx_tbl,
453 .rx_tbl_num = ARRAY_SIZE(msm8998_usb3_rx_tbl),
454 .pcs_tbl = msm8998_usb3_pcs_tbl,
455 .pcs_tbl_num = ARRAY_SIZE(msm8998_usb3_pcs_tbl),
456 .vreg_list = qmp_phy_vreg_l,
457 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
458 .regs = qmp_v3_usb3phy_regs_layout,
461 static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = {
462 .offsets = &qmp_usbc_offsets_v3_qcm2290,
464 .serdes_tbl = qcm2290_usb3_serdes_tbl,
465 .serdes_tbl_num = ARRAY_SIZE(qcm2290_usb3_serdes_tbl),
466 .tx_tbl = qcm2290_usb3_tx_tbl,
467 .tx_tbl_num = ARRAY_SIZE(qcm2290_usb3_tx_tbl),
468 .rx_tbl = qcm2290_usb3_rx_tbl,
469 .rx_tbl_num = ARRAY_SIZE(qcm2290_usb3_rx_tbl),
470 .pcs_tbl = qcm2290_usb3_pcs_tbl,
471 .pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl),
472 .vreg_list = qmp_phy_vreg_l,
473 .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l),
474 .regs = qmp_v3_usb3phy_regs_layout_qcm2290,
477 static void qmp_usbc_configure_lane(void __iomem *base,
478 const struct qmp_phy_init_tbl tbl[],
483 const struct qmp_phy_init_tbl *t = tbl;
488 for (i = 0; i < num; i++, t++) {
489 if (!(t->lane_mask & lane_mask))
492 writel(t->val, base + t->offset);
496 static void qmp_usbc_configure(void __iomem *base,
497 const struct qmp_phy_init_tbl tbl[],
500 qmp_usbc_configure_lane(base, tbl, num, 0xff);
503 static int qmp_usbc_init(struct phy *phy)
505 struct qmp_usbc *qmp = phy_get_drvdata(phy);
506 const struct qmp_phy_cfg *cfg = qmp->cfg;
507 void __iomem *pcs = qmp->pcs;
511 ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs);
513 dev_err(qmp->dev, "failed to enable regulators, err=%d\n", ret);
517 ret = reset_control_bulk_assert(qmp->num_resets, qmp->resets);
519 dev_err(qmp->dev, "reset assert failed\n");
520 goto err_disable_regulators;
523 ret = reset_control_bulk_deassert(qmp->num_resets, qmp->resets);
525 dev_err(qmp->dev, "reset deassert failed\n");
526 goto err_disable_regulators;
529 ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks);
531 goto err_assert_reset;
533 qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN);
535 #define SW_PORTSELECT_VAL BIT(0)
536 #define SW_PORTSELECT_MUX BIT(1)
537 /* Use software based port select and switch on typec orientation */
538 val = SW_PORTSELECT_MUX;
539 if (qmp->orientation == TYPEC_ORIENTATION_REVERSE)
540 val |= SW_PORTSELECT_VAL;
541 writel(val, qmp->pcs_misc);
546 reset_control_bulk_assert(qmp->num_resets, qmp->resets);
547 err_disable_regulators:
548 regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
553 static int qmp_usbc_exit(struct phy *phy)
555 struct qmp_usbc *qmp = phy_get_drvdata(phy);
556 const struct qmp_phy_cfg *cfg = qmp->cfg;
558 reset_control_bulk_assert(qmp->num_resets, qmp->resets);
560 clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
562 regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
567 static int qmp_usbc_power_on(struct phy *phy)
569 struct qmp_usbc *qmp = phy_get_drvdata(phy);
570 const struct qmp_phy_cfg *cfg = qmp->cfg;
571 void __iomem *status;
575 qmp_usbc_configure(qmp->serdes, cfg->serdes_tbl, cfg->serdes_tbl_num);
577 ret = clk_prepare_enable(qmp->pipe_clk);
579 dev_err(qmp->dev, "pipe_clk enable failed err=%d\n", ret);
583 /* Tx, Rx, and PCS configurations */
584 qmp_usbc_configure_lane(qmp->tx, cfg->tx_tbl, cfg->tx_tbl_num, 1);
585 qmp_usbc_configure_lane(qmp->rx, cfg->rx_tbl, cfg->rx_tbl_num, 1);
587 qmp_usbc_configure_lane(qmp->tx2, cfg->tx_tbl, cfg->tx_tbl_num, 2);
588 qmp_usbc_configure_lane(qmp->rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2);
590 qmp_usbc_configure(qmp->pcs, cfg->pcs_tbl, cfg->pcs_tbl_num);
592 if (cfg->has_pwrdn_delay)
593 usleep_range(10, 20);
595 /* Pull PHY out of reset state */
596 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
598 /* start SerDes and Phy-Coding-Sublayer */
599 qphy_setbits(qmp->pcs, cfg->regs[QPHY_START_CTRL], SERDES_START | PCS_START);
601 status = qmp->pcs + cfg->regs[QPHY_PCS_STATUS];
602 ret = readl_poll_timeout(status, val, !(val & PHYSTATUS), 200,
603 PHY_INIT_COMPLETE_TIMEOUT);
605 dev_err(qmp->dev, "phy initialization timed-out\n");
606 goto err_disable_pipe_clk;
611 err_disable_pipe_clk:
612 clk_disable_unprepare(qmp->pipe_clk);
617 static int qmp_usbc_power_off(struct phy *phy)
619 struct qmp_usbc *qmp = phy_get_drvdata(phy);
620 const struct qmp_phy_cfg *cfg = qmp->cfg;
622 clk_disable_unprepare(qmp->pipe_clk);
625 qphy_setbits(qmp->pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
627 /* stop SerDes and Phy-Coding-Sublayer */
628 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_START_CTRL],
629 SERDES_START | PCS_START);
631 /* Put PHY into POWER DOWN state: active low */
632 qphy_clrbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL],
638 static int qmp_usbc_enable(struct phy *phy)
640 struct qmp_usbc *qmp = phy_get_drvdata(phy);
643 mutex_lock(&qmp->phy_mutex);
645 ret = qmp_usbc_init(phy);
649 ret = qmp_usbc_power_on(phy);
655 qmp->usb_init_count++;
657 mutex_unlock(&qmp->phy_mutex);
662 static int qmp_usbc_disable(struct phy *phy)
664 struct qmp_usbc *qmp = phy_get_drvdata(phy);
667 qmp->usb_init_count--;
668 ret = qmp_usbc_power_off(phy);
671 return qmp_usbc_exit(phy);
674 static int qmp_usbc_set_mode(struct phy *phy, enum phy_mode mode, int submode)
676 struct qmp_usbc *qmp = phy_get_drvdata(phy);
683 static const struct phy_ops qmp_usbc_phy_ops = {
684 .init = qmp_usbc_enable,
685 .exit = qmp_usbc_disable,
686 .set_mode = qmp_usbc_set_mode,
687 .owner = THIS_MODULE,
690 static void qmp_usbc_enable_autonomous_mode(struct qmp_usbc *qmp)
692 const struct qmp_phy_cfg *cfg = qmp->cfg;
693 void __iomem *pcs = qmp->pcs;
696 if (qmp->mode == PHY_MODE_USB_HOST_SS ||
697 qmp->mode == PHY_MODE_USB_DEVICE_SS)
698 intr_mask = ARCVR_DTCT_EN | ALFPS_DTCT_EN;
700 intr_mask = ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL;
702 /* Clear any pending interrupts status */
703 qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
704 /* Writing 1 followed by 0 clears the interrupt */
705 qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
707 qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
708 ARCVR_DTCT_EN | ALFPS_DTCT_EN | ARCVR_DTCT_EVENT_SEL);
710 /* Enable required PHY autonomous mode interrupts */
711 qphy_setbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask);
713 /* Enable i/o clamp_n for autonomous mode */
714 if (qmp->tcsr_map && qmp->vls_clamp_reg)
715 regmap_write(qmp->tcsr_map, qmp->vls_clamp_reg, 1);
718 static void qmp_usbc_disable_autonomous_mode(struct qmp_usbc *qmp)
720 const struct qmp_phy_cfg *cfg = qmp->cfg;
721 void __iomem *pcs = qmp->pcs;
723 /* Disable i/o clamp_n on resume for normal mode */
724 if (qmp->tcsr_map && qmp->vls_clamp_reg)
725 regmap_write(qmp->tcsr_map, qmp->vls_clamp_reg, 0);
727 qphy_clrbits(pcs, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL],
728 ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN);
730 qphy_setbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
731 /* Writing 1 followed by 0 clears the interrupt */
732 qphy_clrbits(pcs, cfg->regs[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR], IRQ_CLEAR);
735 static int __maybe_unused qmp_usbc_runtime_suspend(struct device *dev)
737 struct qmp_usbc *qmp = dev_get_drvdata(dev);
739 dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode);
741 if (!qmp->phy->init_count) {
742 dev_vdbg(dev, "PHY not initialized, bailing out\n");
746 qmp_usbc_enable_autonomous_mode(qmp);
748 clk_disable_unprepare(qmp->pipe_clk);
749 clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
754 static int __maybe_unused qmp_usbc_runtime_resume(struct device *dev)
756 struct qmp_usbc *qmp = dev_get_drvdata(dev);
759 dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode);
761 if (!qmp->phy->init_count) {
762 dev_vdbg(dev, "PHY not initialized, bailing out\n");
766 ret = clk_bulk_prepare_enable(qmp->num_clks, qmp->clks);
770 ret = clk_prepare_enable(qmp->pipe_clk);
772 dev_err(dev, "pipe_clk enable failed, err=%d\n", ret);
773 clk_bulk_disable_unprepare(qmp->num_clks, qmp->clks);
777 qmp_usbc_disable_autonomous_mode(qmp);
782 static const struct dev_pm_ops qmp_usbc_pm_ops = {
783 SET_RUNTIME_PM_OPS(qmp_usbc_runtime_suspend,
784 qmp_usbc_runtime_resume, NULL)
787 static int qmp_usbc_vreg_init(struct qmp_usbc *qmp)
789 const struct qmp_phy_cfg *cfg = qmp->cfg;
790 struct device *dev = qmp->dev;
791 int num = cfg->num_vregs;
794 qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL);
798 for (i = 0; i < num; i++)
799 qmp->vregs[i].supply = cfg->vreg_list[i];
801 return devm_regulator_bulk_get(dev, num, qmp->vregs);
804 static int qmp_usbc_reset_init(struct qmp_usbc *qmp,
805 const char *const *reset_list,
808 struct device *dev = qmp->dev;
812 qmp->resets = devm_kcalloc(dev, num_resets,
813 sizeof(*qmp->resets), GFP_KERNEL);
817 for (i = 0; i < num_resets; i++)
818 qmp->resets[i].id = reset_list[i];
820 qmp->num_resets = num_resets;
822 ret = devm_reset_control_bulk_get_exclusive(dev, num_resets, qmp->resets);
824 return dev_err_probe(dev, ret, "failed to get resets\n");
829 static int qmp_usbc_clk_init(struct qmp_usbc *qmp)
831 struct device *dev = qmp->dev;
832 int num = ARRAY_SIZE(qmp_usbc_phy_clk_l);
835 qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
839 for (i = 0; i < num; i++)
840 qmp->clks[i].id = qmp_usbc_phy_clk_l[i];
844 return devm_clk_bulk_get_optional(dev, num, qmp->clks);
847 static void phy_clk_release_provider(void *res)
849 of_clk_del_provider(res);
853 * Register a fixed rate pipe clock.
855 * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
856 * controls it. The <s>_pipe_clk coming out of the GCC is requested
857 * by the PHY driver for its operations.
858 * We register the <s>_pipe_clksrc here. The gcc driver takes care
859 * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
860 * Below picture shows this relationship.
863 * | PHY block |<<---------------------------------------+
865 * | +-------+ | +-----+ |
866 * I/P---^-->| PLL |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
867 * clk | +-------+ | +-----+
870 static int phy_pipe_clk_register(struct qmp_usbc *qmp, struct device_node *np)
872 struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed;
873 struct clk_init_data init = { };
876 ret = of_property_read_string(np, "clock-output-names", &init.name);
878 dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np);
882 init.ops = &clk_fixed_rate_ops;
884 /* controllers using QMP phys use 125MHz pipe clock interface */
885 fixed->fixed_rate = 125000000;
886 fixed->hw.init = &init;
888 ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
892 ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw);
897 * Roll a devm action because the clock provider is the child node, but
898 * the child node is not actually a device.
900 return devm_add_action_or_reset(qmp->dev, phy_clk_release_provider, np);
903 #if IS_ENABLED(CONFIG_TYPEC)
904 static int qmp_usbc_typec_switch_set(struct typec_switch_dev *sw,
905 enum typec_orientation orientation)
907 struct qmp_usbc *qmp = typec_switch_get_drvdata(sw);
909 if (orientation == qmp->orientation || orientation == TYPEC_ORIENTATION_NONE)
912 mutex_lock(&qmp->phy_mutex);
913 qmp->orientation = orientation;
915 if (qmp->usb_init_count) {
916 qmp_usbc_power_off(qmp->phy);
917 qmp_usbc_exit(qmp->phy);
919 qmp_usbc_init(qmp->phy);
920 qmp_usbc_power_on(qmp->phy);
923 mutex_unlock(&qmp->phy_mutex);
928 static void qmp_usbc_typec_unregister(void *data)
930 struct qmp_usbc *qmp = data;
932 typec_switch_unregister(qmp->sw);
935 static int qmp_usbc_typec_switch_register(struct qmp_usbc *qmp)
937 struct typec_switch_desc sw_desc = {};
938 struct device *dev = qmp->dev;
940 sw_desc.drvdata = qmp;
941 sw_desc.fwnode = dev->fwnode;
942 sw_desc.set = qmp_usbc_typec_switch_set;
943 qmp->sw = typec_switch_register(dev, &sw_desc);
944 if (IS_ERR(qmp->sw)) {
945 dev_err(dev, "Unable to register typec switch: %pe\n", qmp->sw);
946 return PTR_ERR(qmp->sw);
949 return devm_add_action_or_reset(dev, qmp_usbc_typec_unregister, qmp);
952 static int qmp_usbc_typec_switch_register(struct qmp_usbc *qmp)
958 static int qmp_usbc_parse_dt_legacy(struct qmp_usbc *qmp, struct device_node *np)
960 struct platform_device *pdev = to_platform_device(qmp->dev);
961 struct device *dev = qmp->dev;
964 qmp->serdes = devm_platform_ioremap_resource(pdev, 0);
965 if (IS_ERR(qmp->serdes))
966 return PTR_ERR(qmp->serdes);
969 * Get memory resources for the PHY:
970 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
971 * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
972 * For single lane PHYs: pcs_misc (optional) -> 3.
974 qmp->tx = devm_of_iomap(dev, np, 0, NULL);
976 return PTR_ERR(qmp->tx);
978 qmp->rx = devm_of_iomap(dev, np, 1, NULL);
980 return PTR_ERR(qmp->rx);
982 qmp->pcs = devm_of_iomap(dev, np, 2, NULL);
983 if (IS_ERR(qmp->pcs))
984 return PTR_ERR(qmp->pcs);
986 qmp->tx2 = devm_of_iomap(dev, np, 3, NULL);
987 if (IS_ERR(qmp->tx2))
988 return PTR_ERR(qmp->tx2);
990 qmp->rx2 = devm_of_iomap(dev, np, 4, NULL);
991 if (IS_ERR(qmp->rx2))
992 return PTR_ERR(qmp->rx2);
994 qmp->pcs_misc = devm_of_iomap(dev, np, 5, NULL);
995 if (IS_ERR(qmp->pcs_misc)) {
996 dev_vdbg(dev, "PHY pcs_misc-reg not used\n");
997 qmp->pcs_misc = NULL;
1000 qmp->pipe_clk = devm_get_clk_from_child(dev, np, NULL);
1001 if (IS_ERR(qmp->pipe_clk)) {
1002 return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
1003 "failed to get pipe clock\n");
1006 ret = devm_clk_bulk_get_all(qmp->dev, &qmp->clks);
1010 qmp->num_clks = ret;
1012 ret = qmp_usbc_reset_init(qmp, usb3phy_legacy_reset_l,
1013 ARRAY_SIZE(usb3phy_legacy_reset_l));
1020 static int qmp_usbc_parse_dt(struct qmp_usbc *qmp)
1022 struct platform_device *pdev = to_platform_device(qmp->dev);
1023 const struct qmp_phy_cfg *cfg = qmp->cfg;
1024 const struct qmp_usbc_offsets *offs = cfg->offsets;
1025 struct device *dev = qmp->dev;
1032 base = devm_platform_ioremap_resource(pdev, 0);
1034 return PTR_ERR(base);
1036 qmp->serdes = base + offs->serdes;
1037 qmp->pcs = base + offs->pcs;
1039 qmp->pcs_misc = base + offs->pcs_misc;
1040 qmp->tx = base + offs->tx;
1041 qmp->rx = base + offs->rx;
1043 qmp->tx2 = base + offs->tx2;
1044 qmp->rx2 = base + offs->rx2;
1046 ret = qmp_usbc_clk_init(qmp);
1050 qmp->pipe_clk = devm_clk_get(dev, "pipe");
1051 if (IS_ERR(qmp->pipe_clk)) {
1052 return dev_err_probe(dev, PTR_ERR(qmp->pipe_clk),
1053 "failed to get pipe clock\n");
1056 ret = qmp_usbc_reset_init(qmp, usb3phy_reset_l,
1057 ARRAY_SIZE(usb3phy_reset_l));
1064 static int qmp_usbc_parse_vls_clamp(struct qmp_usbc *qmp)
1066 struct of_phandle_args tcsr_args;
1067 struct device *dev = qmp->dev;
1070 /* for backwards compatibility ignore if there is no property */
1071 ret = of_parse_phandle_with_fixed_args(dev->of_node, "qcom,tcsr-reg", 1, 0,
1076 return dev_err_probe(dev, ret, "Failed to parse qcom,tcsr-reg\n");
1078 qmp->tcsr_map = syscon_node_to_regmap(tcsr_args.np);
1079 of_node_put(tcsr_args.np);
1080 if (IS_ERR(qmp->tcsr_map))
1081 return PTR_ERR(qmp->tcsr_map);
1083 qmp->vls_clamp_reg = tcsr_args.args[0];
1088 static int qmp_usbc_probe(struct platform_device *pdev)
1090 struct device *dev = &pdev->dev;
1091 struct phy_provider *phy_provider;
1092 struct device_node *np;
1093 struct qmp_usbc *qmp;
1096 qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
1102 qmp->orientation = TYPEC_ORIENTATION_NORMAL;
1104 qmp->cfg = of_device_get_match_data(dev);
1108 mutex_init(&qmp->phy_mutex);
1110 ret = qmp_usbc_vreg_init(qmp);
1114 ret = qmp_usbc_typec_switch_register(qmp);
1118 ret = qmp_usbc_parse_vls_clamp(qmp);
1122 /* Check for legacy binding with child node. */
1123 np = of_get_child_by_name(dev->of_node, "phy");
1125 ret = qmp_usbc_parse_dt_legacy(qmp, np);
1127 np = of_node_get(dev->of_node);
1128 ret = qmp_usbc_parse_dt(qmp);
1133 pm_runtime_set_active(dev);
1134 ret = devm_pm_runtime_enable(dev);
1138 * Prevent runtime pm from being ON by default. Users can enable
1139 * it using power/control in sysfs.
1141 pm_runtime_forbid(dev);
1143 ret = phy_pipe_clk_register(qmp, np);
1147 qmp->phy = devm_phy_create(dev, np, &qmp_usbc_phy_ops);
1148 if (IS_ERR(qmp->phy)) {
1149 ret = PTR_ERR(qmp->phy);
1150 dev_err(dev, "failed to create PHY: %d\n", ret);
1154 phy_set_drvdata(qmp->phy, qmp);
1158 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
1160 return PTR_ERR_OR_ZERO(phy_provider);
1167 static const struct of_device_id qmp_usbc_of_match_table[] = {
1169 .compatible = "qcom,msm8998-qmp-usb3-phy",
1170 .data = &msm8998_usb3phy_cfg,
1172 .compatible = "qcom,qcm2290-qmp-usb3-phy",
1173 .data = &qcm2290_usb3phy_cfg,
1175 .compatible = "qcom,sm6115-qmp-usb3-phy",
1176 .data = &qcm2290_usb3phy_cfg,
1180 MODULE_DEVICE_TABLE(of, qmp_usbc_of_match_table);
1182 static struct platform_driver qmp_usbc_driver = {
1183 .probe = qmp_usbc_probe,
1185 .name = "qcom-qmp-usbc-phy",
1186 .pm = &qmp_usbc_pm_ops,
1187 .of_match_table = qmp_usbc_of_match_table,
1191 module_platform_driver(qmp_usbc_driver);
1193 MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
1194 MODULE_DESCRIPTION("Qualcomm QMP USB-C PHY driver");
1195 MODULE_LICENSE("GPL");