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/module.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>
23 #include "phy-qcom-qmp.h"
24 #include "phy-qcom-qmp-pcs-misc-v3.h"
25 #include "phy-qcom-qmp-pcs-usb-v4.h"
26 #include "phy-qcom-qmp-pcs-usb-v5.h"
28 #include "phy-qcom-qmp-dp-com-v3.h"
30 /* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */
31 /* DP PHY soft reset */
32 #define SW_DPPHY_RESET BIT(0)
33 /* mux to select DP PHY reset control, 0:HW control, 1: software reset */
34 #define SW_DPPHY_RESET_MUX BIT(1)
35 /* USB3 PHY soft reset */
36 #define SW_USB3PHY_RESET BIT(2)
37 /* mux to select USB3 PHY reset control, 0:HW control, 1: software reset */
38 #define SW_USB3PHY_RESET_MUX BIT(3)
40 /* QPHY_V3_DP_COM_PHY_MODE_CTRL register bits */
41 #define USB3_MODE BIT(0) /* enables USB3 mode */
42 #define DP_MODE BIT(1) /* enables DP mode */
44 #define PHY_INIT_COMPLETE_TIMEOUT 10000
46 struct qmp_phy_init_tbl
{
50 * mask of lanes for which this register is written
51 * for cases when second lane needs different values
56 #define QMP_PHY_INIT_CFG(o, v) \
63 #define QMP_PHY_INIT_CFG_LANE(o, v, l) \
70 /* set of registers with offsets different per-PHY */
71 enum qphy_reg_layout
{
76 QPHY_PCS_AUTONOMOUS_MODE_CTRL
,
77 QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR
,
78 QPHY_PCS_POWER_DOWN_CONTROL
,
79 /* Keep last to ensure regs_layout arrays are properly initialized */
83 static const unsigned int qmp_v3_usb3phy_regs_layout
[QPHY_LAYOUT_SIZE
] = {
84 [QPHY_SW_RESET
] = QPHY_V3_PCS_SW_RESET
,
85 [QPHY_START_CTRL
] = QPHY_V3_PCS_START_CONTROL
,
86 [QPHY_PCS_STATUS
] = QPHY_V3_PCS_PCS_STATUS
,
87 [QPHY_PCS_AUTONOMOUS_MODE_CTRL
] = QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL
,
88 [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR
] = QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR
,
89 [QPHY_PCS_POWER_DOWN_CONTROL
] = QPHY_V3_PCS_POWER_DOWN_CONTROL
,
92 static const unsigned int qmp_v4_usb3phy_regs_layout
[QPHY_LAYOUT_SIZE
] = {
93 [QPHY_SW_RESET
] = QPHY_V4_PCS_SW_RESET
,
94 [QPHY_START_CTRL
] = QPHY_V4_PCS_START_CONTROL
,
95 [QPHY_PCS_STATUS
] = QPHY_V4_PCS_PCS_STATUS1
,
96 [QPHY_PCS_POWER_DOWN_CONTROL
] = QPHY_V4_PCS_POWER_DOWN_CONTROL
,
99 [QPHY_PCS_AUTONOMOUS_MODE_CTRL
] = QPHY_V4_PCS_USB3_AUTONOMOUS_MODE_CTRL
,
100 [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR
] = QPHY_V4_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR
,
103 static const unsigned int qmp_v5_usb3phy_regs_layout
[QPHY_LAYOUT_SIZE
] = {
104 [QPHY_SW_RESET
] = QPHY_V5_PCS_SW_RESET
,
105 [QPHY_START_CTRL
] = QPHY_V5_PCS_START_CONTROL
,
106 [QPHY_PCS_STATUS
] = QPHY_V5_PCS_PCS_STATUS1
,
107 [QPHY_PCS_POWER_DOWN_CONTROL
] = QPHY_V5_PCS_POWER_DOWN_CONTROL
,
110 [QPHY_PCS_AUTONOMOUS_MODE_CTRL
] = QPHY_V5_PCS_USB3_AUTONOMOUS_MODE_CTRL
,
111 [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR
] = QPHY_V5_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR
,
114 static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl
[] = {
115 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO
, 0x07),
116 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL
, 0x14),
117 QMP_PHY_INIT_CFG(QSERDES_V3_COM_BIAS_EN_CLKBUFLR_EN
, 0x08),
118 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CLK_SELECT
, 0x30),
119 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYS_CLK_CTRL
, 0x02),
120 QMP_PHY_INIT_CFG(QSERDES_V3_COM_RESETSM_CNTRL2
, 0x08),
121 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CMN_CONFIG
, 0x16),
122 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SVS_MODE_CLK_SEL
, 0x01),
123 QMP_PHY_INIT_CFG(QSERDES_V3_COM_HSCLK_SEL
, 0x80),
124 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DEC_START_MODE0
, 0x82),
125 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START1_MODE0
, 0xab),
126 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START2_MODE0
, 0xea),
127 QMP_PHY_INIT_CFG(QSERDES_V3_COM_DIV_FRAC_START3_MODE0
, 0x02),
128 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CP_CTRL_MODE0
, 0x06),
129 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_RCTRL_MODE0
, 0x16),
130 QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_CCTRL_MODE0
, 0x36),
131 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN1_MODE0
, 0x00),
132 QMP_PHY_INIT_CFG(QSERDES_V3_COM_INTEGLOOP_GAIN0_MODE0
, 0x3f),
133 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE2_MODE0
, 0x01),
134 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE1_MODE0
, 0xc9),
135 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORECLK_DIV_MODE0
, 0x0a),
136 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP3_MODE0
, 0x00),
137 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP2_MODE0
, 0x34),
138 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP1_MODE0
, 0x15),
139 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_EN
, 0x04),
140 QMP_PHY_INIT_CFG(QSERDES_V3_COM_CORE_CLK_EN
, 0x00),
141 QMP_PHY_INIT_CFG(QSERDES_V3_COM_LOCK_CMP_CFG
, 0x00),
142 QMP_PHY_INIT_CFG(QSERDES_V3_COM_VCO_TUNE_MAP
, 0x00),
143 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_BUF_ENABLE
, 0x0a),
144 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_EN_CENTER
, 0x01),
145 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER1
, 0x31),
146 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_PER2
, 0x01),
147 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER1
, 0x00),
148 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_ADJ_PER2
, 0x00),
149 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE1
, 0x85),
150 QMP_PHY_INIT_CFG(QSERDES_V3_COM_SSC_STEP_SIZE2
, 0x07),
153 static const struct qmp_phy_init_tbl qmp_v3_usb3_tx_tbl
[] = {
154 QMP_PHY_INIT_CFG(QSERDES_V3_TX_HIGHZ_DRVR_EN
, 0x10),
155 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RCV_DETECT_LVL_2
, 0x12),
156 QMP_PHY_INIT_CFG(QSERDES_V3_TX_LANE_MODE_1
, 0x16),
157 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_RX
, 0x09),
158 QMP_PHY_INIT_CFG(QSERDES_V3_TX_RES_CODE_LANE_OFFSET_TX
, 0x06),
161 static const struct qmp_phy_init_tbl qmp_v3_usb3_rx_tbl
[] = {
162 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_FASTLOCK_FO_GAIN
, 0x0b),
163 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL2
, 0x0f),
164 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL3
, 0x4e),
165 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQU_ADAPTOR_CNTRL4
, 0x18),
166 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1
, 0x77),
167 QMP_PHY_INIT_CFG(QSERDES_V3_RX_RX_OFFSET_ADAPTOR_CNTRL2
, 0x80),
168 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_CNTRL
, 0x03),
169 QMP_PHY_INIT_CFG(QSERDES_V3_RX_SIGDET_DEGLITCH_CNTRL
, 0x16),
170 QMP_PHY_INIT_CFG(QSERDES_V3_RX_UCDR_SO_SATURATION_AND_ENABLE
, 0x75),
173 static const struct qmp_phy_init_tbl qmp_v3_usb3_pcs_tbl
[] = {
175 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL2
, 0x83),
176 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_L
, 0x09),
177 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNT_VAL_H_TOL
, 0xa2),
178 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_MAN_CODE
, 0x40),
179 QMP_PHY_INIT_CFG(QPHY_V3_PCS_FLL_CNTRL1
, 0x02),
181 /* Lock Det settings */
182 QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG1
, 0xd1),
183 QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG2
, 0x1f),
184 QMP_PHY_INIT_CFG(QPHY_V3_PCS_LOCK_DETECT_CONFIG3
, 0x47),
185 QMP_PHY_INIT_CFG(QPHY_V3_PCS_POWER_STATE_CONFIG2
, 0x1b),
187 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL
, 0xba),
188 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V0
, 0x9f),
189 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V1
, 0x9f),
190 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V2
, 0xb7),
191 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V3
, 0x4e),
192 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_V4
, 0x65),
193 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXMGN_LS
, 0x6b),
194 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V0
, 0x15),
195 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V0
, 0x0d),
196 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V1
, 0x15),
197 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V1
, 0x0d),
198 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V2
, 0x15),
199 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V2
, 0x0d),
200 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V3
, 0x15),
201 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V3
, 0x1d),
202 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_V4
, 0x15),
203 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_V4
, 0x0d),
204 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M6DB_LS
, 0x15),
205 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TXDEEMPH_M3P5DB_LS
, 0x0d),
207 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RATE_SLEW_CNTRL
, 0x02),
208 QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK
, 0x04),
209 QMP_PHY_INIT_CFG(QPHY_V3_PCS_TSYNC_RSYNC_TIME
, 0x44),
210 QMP_PHY_INIT_CFG(QPHY_V3_PCS_PWRUP_RESET_DLY_TIME_AUXCLK
, 0x04),
211 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_L
, 0xe7),
212 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_P1U2_H
, 0x03),
213 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_L
, 0x40),
214 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RCVR_DTCT_DLY_U3_H
, 0x00),
215 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_WAIT_TIME
, 0x75),
216 QMP_PHY_INIT_CFG(QPHY_V3_PCS_LFPS_TX_ECSTART_EQTLOCK
, 0x86),
217 QMP_PHY_INIT_CFG(QPHY_V3_PCS_RXEQTRAINING_RUN_TIME
, 0x13),
220 static const struct qmp_phy_init_tbl sm8150_usb3_serdes_tbl
[] = {
221 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_EN_CENTER
, 0x01),
222 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER1
, 0x31),
223 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_PER2
, 0x01),
224 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE0
, 0xde),
225 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE0
, 0x07),
226 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE1_MODE1
, 0xde),
227 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SSC_STEP_SIZE2_MODE1
, 0x07),
228 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_BUF_ENABLE
, 0x0a),
229 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CMN_IPTRIM
, 0x20),
230 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE0
, 0x06),
231 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CP_CTRL_MODE1
, 0x06),
232 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE0
, 0x16),
233 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_RCTRL_MODE1
, 0x16),
234 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE0
, 0x36),
235 QMP_PHY_INIT_CFG(QSERDES_V4_COM_PLL_CCTRL_MODE1
, 0x36),
236 QMP_PHY_INIT_CFG(QSERDES_V4_COM_SYSCLK_EN_SEL
, 0x1a),
237 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP_EN
, 0x04),
238 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE0
, 0x14),
239 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE0
, 0x34),
240 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP1_MODE1
, 0x34),
241 QMP_PHY_INIT_CFG(QSERDES_V4_COM_LOCK_CMP2_MODE1
, 0x82),
242 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE0
, 0x82),
243 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DEC_START_MODE1
, 0x82),
244 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE0
, 0xab),
245 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE0
, 0xea),
246 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE0
, 0x02),
247 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE_MAP
, 0x02),
248 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START1_MODE1
, 0xab),
249 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START2_MODE1
, 0xea),
250 QMP_PHY_INIT_CFG(QSERDES_V4_COM_DIV_FRAC_START3_MODE1
, 0x02),
251 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE0
, 0x24),
252 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE1_MODE1
, 0x24),
253 QMP_PHY_INIT_CFG(QSERDES_V4_COM_VCO_TUNE2_MODE1
, 0x02),
254 QMP_PHY_INIT_CFG(QSERDES_V4_COM_HSCLK_SEL
, 0x01),
255 QMP_PHY_INIT_CFG(QSERDES_V4_COM_CORECLK_DIV_MODE1
, 0x08),
256 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE0
, 0xca),
257 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE0
, 0x1e),
258 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE1_MODE1
, 0xca),
259 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_CMP_CODE2_MODE1
, 0x1e),
260 QMP_PHY_INIT_CFG(QSERDES_V4_COM_BIN_VCOCAL_HSCLK_SEL
, 0x11),
263 static const struct qmp_phy_init_tbl sm8150_usb3_tx_tbl
[] = {
264 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX
, 0x00),
265 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX
, 0x00),
266 QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1
, 0xd5),
267 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2
, 0x12),
268 QMP_PHY_INIT_CFG(QSERDES_V4_TX_PI_QEC_CTRL
, 0x20),
271 static const struct qmp_phy_init_tbl sm8150_usb3_rx_tbl
[] = {
272 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN
, 0x05),
273 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN
, 0x2f),
274 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE
, 0x7f),
275 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW
, 0xff),
276 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH
, 0x0f),
277 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS
, 0x99),
278 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1
, 0x04),
279 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2
, 0x08),
280 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1
, 0x05),
281 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2
, 0x05),
282 QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1
, 0x54),
283 QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2
, 0x0e),
284 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2
, 0x0f),
285 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3
, 0x4a),
286 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4
, 0x0a),
287 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW
, 0xc0),
288 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH
, 0x00),
289 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1
, 0x77),
290 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL
, 0x04),
291 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL
, 0x0e),
292 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_LOW
, 0xbf),
293 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH
, 0xbf),
294 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2
, 0x3f),
295 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3
, 0x7f),
296 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4
, 0x94),
297 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW
, 0xdc),
298 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH
, 0xdc),
299 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2
, 0x5c),
300 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3
, 0x0b),
301 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4
, 0xb3),
302 QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER
, 0x04),
303 QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET
, 0x38),
304 QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE
, 0xa0),
305 QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1
, 0x0c),
306 QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL
, 0x1f),
307 QMP_PHY_INIT_CFG(QSERDES_V4_RX_VTH_CODE
, 0x10),
310 static const struct qmp_phy_init_tbl sm8150_usb3_pcs_tbl
[] = {
311 /* Lock Det settings */
312 QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1
, 0xd0),
313 QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2
, 0x07),
314 QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6
, 0x13),
316 QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1
, 0x21),
317 QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL
, 0xaa),
318 QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME
, 0x0a),
319 QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1
, 0x88),
320 QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2
, 0x13),
321 QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG
, 0x0c),
322 QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1
, 0x4b),
323 QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5
, 0x10),
326 static const struct qmp_phy_init_tbl sm8150_usb3_pcs_usb_tbl
[] = {
327 QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL
, 0xf8),
328 QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2
, 0x07),
331 static const struct qmp_phy_init_tbl sm8250_usb3_tx_tbl
[] = {
332 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_TX
, 0x60),
333 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_RX
, 0x60),
334 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_TX
, 0x11),
335 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RES_CODE_LANE_OFFSET_RX
, 0x02),
336 QMP_PHY_INIT_CFG(QSERDES_V4_TX_LANE_MODE_1
, 0xd5),
337 QMP_PHY_INIT_CFG(QSERDES_V4_TX_RCV_DETECT_LVL_2
, 0x12),
338 QMP_PHY_INIT_CFG_LANE(QSERDES_V4_TX_PI_QEC_CTRL
, 0x40, 1),
339 QMP_PHY_INIT_CFG_LANE(QSERDES_V4_TX_PI_QEC_CTRL
, 0x54, 2),
342 static const struct qmp_phy_init_tbl sm8250_usb3_rx_tbl
[] = {
343 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_GAIN
, 0x06),
344 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_FO_GAIN
, 0x2f),
345 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SO_SATURATION_AND_ENABLE
, 0x7f),
346 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_LOW
, 0xff),
347 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_FASTLOCK_COUNT_HIGH
, 0x0f),
348 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_PI_CONTROLS
, 0x99),
349 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH1
, 0x04),
350 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_THRESH2
, 0x08),
351 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN1
, 0x05),
352 QMP_PHY_INIT_CFG(QSERDES_V4_RX_UCDR_SB2_GAIN2
, 0x05),
353 QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL1
, 0x54),
354 QMP_PHY_INIT_CFG(QSERDES_V4_RX_VGA_CAL_CNTRL2
, 0x0c),
355 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL2
, 0x0f),
356 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL3
, 0x4a),
357 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQU_ADAPTOR_CNTRL4
, 0x0a),
358 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_LOW
, 0xc0),
359 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_IDAC_TSETTLE_HIGH
, 0x00),
360 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1
, 0x77),
361 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_CNTRL
, 0x04),
362 QMP_PHY_INIT_CFG(QSERDES_V4_RX_SIGDET_DEGLITCH_CNTRL
, 0x0e),
363 QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_LOW
, 0xff, 1),
364 QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_LOW
, 0x7f, 2),
365 QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_HIGH
, 0x7f, 1),
366 QMP_PHY_INIT_CFG_LANE(QSERDES_V4_RX_RX_MODE_00_HIGH
, 0xff, 2),
367 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH2
, 0x7f),
368 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH3
, 0x7f),
369 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_00_HIGH4
, 0x97),
370 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_LOW
, 0xdc),
371 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH
, 0xdc),
372 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH2
, 0x5c),
373 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH3
, 0x7b),
374 QMP_PHY_INIT_CFG(QSERDES_V4_RX_RX_MODE_01_HIGH4
, 0xb4),
375 QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_EN_TIMER
, 0x04),
376 QMP_PHY_INIT_CFG(QSERDES_V4_RX_DFE_CTLE_POST_CAL_OFFSET
, 0x38),
377 QMP_PHY_INIT_CFG(QSERDES_V4_RX_AUX_DATA_TCOARSE_TFINE
, 0xa0),
378 QMP_PHY_INIT_CFG(QSERDES_V4_RX_DCC_CTRL1
, 0x0c),
379 QMP_PHY_INIT_CFG(QSERDES_V4_RX_GM_CAL
, 0x1f),
380 QMP_PHY_INIT_CFG(QSERDES_V4_RX_VTH_CODE
, 0x10),
383 static const struct qmp_phy_init_tbl sm8250_usb3_pcs_tbl
[] = {
384 QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1
, 0xd0),
385 QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2
, 0x07),
386 QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3
, 0x20),
387 QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6
, 0x13),
388 QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1
, 0x21),
389 QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL
, 0xa9),
390 QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME
, 0x0a),
391 QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1
, 0x88),
392 QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2
, 0x13),
393 QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG
, 0x0c),
394 QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1
, 0x4b),
395 QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5
, 0x10),
398 static const struct qmp_phy_init_tbl sm8250_usb3_pcs_usb_tbl
[] = {
399 QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL
, 0xf8),
400 QMP_PHY_INIT_CFG(QPHY_V4_PCS_USB3_RXEQTRAINING_DFE_TIME_S2
, 0x07),
403 static const struct qmp_phy_init_tbl sm8350_usb3_tx_tbl
[] = {
404 QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_TX
, 0x00),
405 QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_RX
, 0x00),
406 QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_TX
, 0x16),
407 QMP_PHY_INIT_CFG(QSERDES_V5_TX_RES_CODE_LANE_OFFSET_RX
, 0x0e),
408 QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_1
, 0x35),
409 QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_3
, 0x3f),
410 QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_4
, 0x7f),
411 QMP_PHY_INIT_CFG(QSERDES_V5_TX_LANE_MODE_5
, 0x3f),
412 QMP_PHY_INIT_CFG(QSERDES_V5_TX_RCV_DETECT_LVL_2
, 0x12),
413 QMP_PHY_INIT_CFG(QSERDES_V5_TX_PI_QEC_CTRL
, 0x21),
416 static const struct qmp_phy_init_tbl sm8350_usb3_rx_tbl
[] = {
417 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FO_GAIN
, 0x0a),
418 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_GAIN
, 0x05),
419 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_FO_GAIN
, 0x2f),
420 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SO_SATURATION_AND_ENABLE
, 0x7f),
421 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_LOW
, 0xff),
422 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_FASTLOCK_COUNT_HIGH
, 0x0f),
423 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_PI_CONTROLS
, 0x99),
424 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH1
, 0x08),
425 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_THRESH2
, 0x08),
426 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN1
, 0x00),
427 QMP_PHY_INIT_CFG(QSERDES_V5_RX_UCDR_SB2_GAIN2
, 0x04),
428 QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL1
, 0x54),
429 QMP_PHY_INIT_CFG(QSERDES_V5_RX_VGA_CAL_CNTRL2
, 0x0f),
430 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL2
, 0x0f),
431 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL3
, 0x4a),
432 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQU_ADAPTOR_CNTRL4
, 0x0a),
433 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_LOW
, 0xc0),
434 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_IDAC_TSETTLE_HIGH
, 0x00),
435 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1
, 0x47),
436 QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_CNTRL
, 0x04),
437 QMP_PHY_INIT_CFG(QSERDES_V5_RX_SIGDET_DEGLITCH_CNTRL
, 0x0e),
438 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_LOW
, 0xbb),
439 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH
, 0x7b),
440 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH2
, 0xbb),
441 QMP_PHY_INIT_CFG_LANE(QSERDES_V5_RX_RX_MODE_00_HIGH3
, 0x3d, 1),
442 QMP_PHY_INIT_CFG_LANE(QSERDES_V5_RX_RX_MODE_00_HIGH3
, 0x3c, 2),
443 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_00_HIGH4
, 0xdb),
444 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_LOW
, 0x64),
445 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH
, 0x24),
446 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH2
, 0xd2),
447 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH3
, 0x13),
448 QMP_PHY_INIT_CFG(QSERDES_V5_RX_RX_MODE_01_HIGH4
, 0xa9),
449 QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_EN_TIMER
, 0x04),
450 QMP_PHY_INIT_CFG(QSERDES_V5_RX_DFE_CTLE_POST_CAL_OFFSET
, 0x38),
451 QMP_PHY_INIT_CFG(QSERDES_V5_RX_AUX_DATA_TCOARSE_TFINE
, 0xa0),
452 QMP_PHY_INIT_CFG(QSERDES_V5_RX_DCC_CTRL1
, 0x0c),
453 QMP_PHY_INIT_CFG(QSERDES_V5_RX_GM_CAL
, 0x00),
454 QMP_PHY_INIT_CFG(QSERDES_V5_RX_VTH_CODE
, 0x10),
457 static const struct qmp_phy_init_tbl sm8350_usb3_pcs_tbl
[] = {
458 QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_L
, 0xe7),
459 QMP_PHY_INIT_CFG(QPHY_V4_PCS_RCVR_DTCT_DLY_P1U2_H
, 0x03),
460 QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG1
, 0xd0),
461 QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG2
, 0x07),
462 QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG3
, 0x20),
463 QMP_PHY_INIT_CFG(QPHY_V4_PCS_LOCK_DETECT_CONFIG6
, 0x13),
464 QMP_PHY_INIT_CFG(QPHY_V4_PCS_REFGEN_REQ_CONFIG1
, 0x21),
465 QMP_PHY_INIT_CFG(QPHY_V4_PCS_RX_SIGDET_LVL
, 0xaa),
466 QMP_PHY_INIT_CFG(QPHY_V4_PCS_CDR_RESET_TIME
, 0x0a),
467 QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG1
, 0x88),
468 QMP_PHY_INIT_CFG(QPHY_V4_PCS_ALIGN_DETECT_CONFIG2
, 0x13),
469 QMP_PHY_INIT_CFG(QPHY_V4_PCS_PCS_TX_RX_CONFIG
, 0x0c),
470 QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG1
, 0x4b),
471 QMP_PHY_INIT_CFG(QPHY_V4_PCS_EQ_CONFIG5
, 0x10),
474 static const struct qmp_phy_init_tbl sm8350_usb3_pcs_usb_tbl
[] = {
475 QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_L
, 0x40),
476 QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RCVR_DTCT_DLY_U3_H
, 0x00),
477 QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_LFPS_DET_HIGH_COUNT_VAL
, 0xf8),
478 QMP_PHY_INIT_CFG(QPHY_V5_PCS_USB3_RXEQTRAINING_DFE_TIME_S2
, 0x07),
481 struct qmp_usb_legacy_offsets
{
489 /* struct qmp_phy_cfg - per-PHY initialization config */
491 const struct qmp_usb_legacy_offsets
*offsets
;
493 /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
494 const struct qmp_phy_init_tbl
*serdes_tbl
;
496 const struct qmp_phy_init_tbl
*tx_tbl
;
498 const struct qmp_phy_init_tbl
*rx_tbl
;
500 const struct qmp_phy_init_tbl
*pcs_tbl
;
502 const struct qmp_phy_init_tbl
*pcs_usb_tbl
;
505 /* clock ids to be requested */
506 const char * const *clk_list
;
508 /* resets to be requested */
509 const char * const *reset_list
;
511 /* regulators to be requested */
512 const char * const *vreg_list
;
515 /* array of registers with different offsets */
516 const unsigned int *regs
;
518 /* Offset from PCS to PCS_USB region */
519 unsigned int pcs_usb_offset
;
525 const struct qmp_phy_cfg
*cfg
;
527 void __iomem
*serdes
;
529 void __iomem
*pcs_misc
;
530 void __iomem
*pcs_usb
;
536 void __iomem
*dp_com
;
538 struct clk
*pipe_clk
;
539 struct clk_bulk_data
*clks
;
540 struct reset_control_bulk_data
*resets
;
541 struct regulator_bulk_data
*vregs
;
547 struct clk_fixed_rate pipe_clk_fixed
;
550 static inline void qphy_setbits(void __iomem
*base
, u32 offset
, u32 val
)
554 reg
= readl(base
+ offset
);
556 writel(reg
, base
+ offset
);
558 /* ensure that above write is through */
559 readl(base
+ offset
);
562 static inline void qphy_clrbits(void __iomem
*base
, u32 offset
, u32 val
)
566 reg
= readl(base
+ offset
);
568 writel(reg
, base
+ offset
);
570 /* ensure that above write is through */
571 readl(base
+ offset
);
574 /* list of clocks required by phy */
575 static const char * const qmp_v3_phy_clk_l
[] = {
576 "aux", "cfg_ahb", "ref", "com_aux",
579 static const char * const qmp_v4_ref_phy_clk_l
[] = {
580 "aux", "ref_clk_src", "ref", "com_aux",
583 /* the primary usb3 phy on sm8250 doesn't have a ref clock */
584 static const char * const qmp_v4_sm8250_usbphy_clk_l
[] = {
585 "aux", "ref_clk_src", "com_aux"
589 static const char * const msm8996_usb3phy_reset_l
[] = {
593 static const char * const sc7180_usb3phy_reset_l
[] = {
597 /* list of regulators */
598 static const char * const qmp_phy_vreg_l
[] = {
599 "vdda-phy", "vdda-pll",
602 static const struct qmp_phy_cfg qmp_v3_usb3phy_cfg
= {
603 .serdes_tbl
= qmp_v3_usb3_serdes_tbl
,
604 .serdes_tbl_num
= ARRAY_SIZE(qmp_v3_usb3_serdes_tbl
),
605 .tx_tbl
= qmp_v3_usb3_tx_tbl
,
606 .tx_tbl_num
= ARRAY_SIZE(qmp_v3_usb3_tx_tbl
),
607 .rx_tbl
= qmp_v3_usb3_rx_tbl
,
608 .rx_tbl_num
= ARRAY_SIZE(qmp_v3_usb3_rx_tbl
),
609 .pcs_tbl
= qmp_v3_usb3_pcs_tbl
,
610 .pcs_tbl_num
= ARRAY_SIZE(qmp_v3_usb3_pcs_tbl
),
611 .clk_list
= qmp_v3_phy_clk_l
,
612 .num_clks
= ARRAY_SIZE(qmp_v3_phy_clk_l
),
613 .reset_list
= msm8996_usb3phy_reset_l
,
614 .num_resets
= ARRAY_SIZE(msm8996_usb3phy_reset_l
),
615 .vreg_list
= qmp_phy_vreg_l
,
616 .num_vregs
= ARRAY_SIZE(qmp_phy_vreg_l
),
617 .regs
= qmp_v3_usb3phy_regs_layout
,
620 static const struct qmp_phy_cfg sc7180_usb3phy_cfg
= {
621 .serdes_tbl
= qmp_v3_usb3_serdes_tbl
,
622 .serdes_tbl_num
= ARRAY_SIZE(qmp_v3_usb3_serdes_tbl
),
623 .tx_tbl
= qmp_v3_usb3_tx_tbl
,
624 .tx_tbl_num
= ARRAY_SIZE(qmp_v3_usb3_tx_tbl
),
625 .rx_tbl
= qmp_v3_usb3_rx_tbl
,
626 .rx_tbl_num
= ARRAY_SIZE(qmp_v3_usb3_rx_tbl
),
627 .pcs_tbl
= qmp_v3_usb3_pcs_tbl
,
628 .pcs_tbl_num
= ARRAY_SIZE(qmp_v3_usb3_pcs_tbl
),
629 .clk_list
= qmp_v3_phy_clk_l
,
630 .num_clks
= ARRAY_SIZE(qmp_v3_phy_clk_l
),
631 .reset_list
= sc7180_usb3phy_reset_l
,
632 .num_resets
= ARRAY_SIZE(sc7180_usb3phy_reset_l
),
633 .vreg_list
= qmp_phy_vreg_l
,
634 .num_vregs
= ARRAY_SIZE(qmp_phy_vreg_l
),
635 .regs
= qmp_v3_usb3phy_regs_layout
,
638 static const struct qmp_phy_cfg sm8150_usb3phy_cfg
= {
639 .serdes_tbl
= sm8150_usb3_serdes_tbl
,
640 .serdes_tbl_num
= ARRAY_SIZE(sm8150_usb3_serdes_tbl
),
641 .tx_tbl
= sm8150_usb3_tx_tbl
,
642 .tx_tbl_num
= ARRAY_SIZE(sm8150_usb3_tx_tbl
),
643 .rx_tbl
= sm8150_usb3_rx_tbl
,
644 .rx_tbl_num
= ARRAY_SIZE(sm8150_usb3_rx_tbl
),
645 .pcs_tbl
= sm8150_usb3_pcs_tbl
,
646 .pcs_tbl_num
= ARRAY_SIZE(sm8150_usb3_pcs_tbl
),
647 .pcs_usb_tbl
= sm8150_usb3_pcs_usb_tbl
,
648 .pcs_usb_tbl_num
= ARRAY_SIZE(sm8150_usb3_pcs_usb_tbl
),
649 .clk_list
= qmp_v4_ref_phy_clk_l
,
650 .num_clks
= ARRAY_SIZE(qmp_v4_ref_phy_clk_l
),
651 .reset_list
= msm8996_usb3phy_reset_l
,
652 .num_resets
= ARRAY_SIZE(msm8996_usb3phy_reset_l
),
653 .vreg_list
= qmp_phy_vreg_l
,
654 .num_vregs
= ARRAY_SIZE(qmp_phy_vreg_l
),
655 .regs
= qmp_v4_usb3phy_regs_layout
,
656 .pcs_usb_offset
= 0x300,
659 static const struct qmp_phy_cfg sm8250_usb3phy_cfg
= {
660 .serdes_tbl
= sm8150_usb3_serdes_tbl
,
661 .serdes_tbl_num
= ARRAY_SIZE(sm8150_usb3_serdes_tbl
),
662 .tx_tbl
= sm8250_usb3_tx_tbl
,
663 .tx_tbl_num
= ARRAY_SIZE(sm8250_usb3_tx_tbl
),
664 .rx_tbl
= sm8250_usb3_rx_tbl
,
665 .rx_tbl_num
= ARRAY_SIZE(sm8250_usb3_rx_tbl
),
666 .pcs_tbl
= sm8250_usb3_pcs_tbl
,
667 .pcs_tbl_num
= ARRAY_SIZE(sm8250_usb3_pcs_tbl
),
668 .pcs_usb_tbl
= sm8250_usb3_pcs_usb_tbl
,
669 .pcs_usb_tbl_num
= ARRAY_SIZE(sm8250_usb3_pcs_usb_tbl
),
670 .clk_list
= qmp_v4_sm8250_usbphy_clk_l
,
671 .num_clks
= ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l
),
672 .reset_list
= msm8996_usb3phy_reset_l
,
673 .num_resets
= ARRAY_SIZE(msm8996_usb3phy_reset_l
),
674 .vreg_list
= qmp_phy_vreg_l
,
675 .num_vregs
= ARRAY_SIZE(qmp_phy_vreg_l
),
676 .regs
= qmp_v4_usb3phy_regs_layout
,
677 .pcs_usb_offset
= 0x300,
680 static const struct qmp_phy_cfg sm8350_usb3phy_cfg
= {
681 .serdes_tbl
= sm8150_usb3_serdes_tbl
,
682 .serdes_tbl_num
= ARRAY_SIZE(sm8150_usb3_serdes_tbl
),
683 .tx_tbl
= sm8350_usb3_tx_tbl
,
684 .tx_tbl_num
= ARRAY_SIZE(sm8350_usb3_tx_tbl
),
685 .rx_tbl
= sm8350_usb3_rx_tbl
,
686 .rx_tbl_num
= ARRAY_SIZE(sm8350_usb3_rx_tbl
),
687 .pcs_tbl
= sm8350_usb3_pcs_tbl
,
688 .pcs_tbl_num
= ARRAY_SIZE(sm8350_usb3_pcs_tbl
),
689 .pcs_usb_tbl
= sm8350_usb3_pcs_usb_tbl
,
690 .pcs_usb_tbl_num
= ARRAY_SIZE(sm8350_usb3_pcs_usb_tbl
),
691 .clk_list
= qmp_v4_sm8250_usbphy_clk_l
,
692 .num_clks
= ARRAY_SIZE(qmp_v4_sm8250_usbphy_clk_l
),
693 .reset_list
= msm8996_usb3phy_reset_l
,
694 .num_resets
= ARRAY_SIZE(msm8996_usb3phy_reset_l
),
695 .vreg_list
= qmp_phy_vreg_l
,
696 .num_vregs
= ARRAY_SIZE(qmp_phy_vreg_l
),
697 .regs
= qmp_v5_usb3phy_regs_layout
,
698 .pcs_usb_offset
= 0x300,
701 static void qmp_usb_legacy_configure_lane(void __iomem
*base
,
702 const struct qmp_phy_init_tbl tbl
[],
707 const struct qmp_phy_init_tbl
*t
= tbl
;
712 for (i
= 0; i
< num
; i
++, t
++) {
713 if (!(t
->lane_mask
& lane_mask
))
716 writel(t
->val
, base
+ t
->offset
);
720 static void qmp_usb_legacy_configure(void __iomem
*base
,
721 const struct qmp_phy_init_tbl tbl
[],
724 qmp_usb_legacy_configure_lane(base
, tbl
, num
, 0xff);
727 static int qmp_usb_legacy_serdes_init(struct qmp_usb
*qmp
)
729 const struct qmp_phy_cfg
*cfg
= qmp
->cfg
;
730 void __iomem
*serdes
= qmp
->serdes
;
731 const struct qmp_phy_init_tbl
*serdes_tbl
= cfg
->serdes_tbl
;
732 int serdes_tbl_num
= cfg
->serdes_tbl_num
;
734 qmp_usb_legacy_configure(serdes
, serdes_tbl
, serdes_tbl_num
);
739 static void qmp_usb_legacy_init_dp_com(struct phy
*phy
)
741 struct qmp_usb
*qmp
= phy_get_drvdata(phy
);
742 void __iomem
*dp_com
= qmp
->dp_com
;
744 qphy_setbits(dp_com
, QPHY_V3_DP_COM_POWER_DOWN_CTRL
,
746 /* override hardware control for reset of qmp phy */
747 qphy_setbits(dp_com
, QPHY_V3_DP_COM_RESET_OVRD_CTRL
,
748 SW_DPPHY_RESET_MUX
| SW_DPPHY_RESET
|
749 SW_USB3PHY_RESET_MUX
| SW_USB3PHY_RESET
);
751 /* Default type-c orientation, i.e CC1 */
752 qphy_setbits(dp_com
, QPHY_V3_DP_COM_TYPEC_CTRL
, 0x02);
754 qphy_setbits(dp_com
, QPHY_V3_DP_COM_PHY_MODE_CTRL
,
755 USB3_MODE
| DP_MODE
);
757 /* bring both QMP USB and QMP DP PHYs PCS block out of reset */
758 qphy_clrbits(dp_com
, QPHY_V3_DP_COM_RESET_OVRD_CTRL
,
759 SW_DPPHY_RESET_MUX
| SW_DPPHY_RESET
|
760 SW_USB3PHY_RESET_MUX
| SW_USB3PHY_RESET
);
762 qphy_clrbits(dp_com
, QPHY_V3_DP_COM_SWI_CTRL
, 0x03);
763 qphy_clrbits(dp_com
, QPHY_V3_DP_COM_SW_RESET
, SW_RESET
);
766 static int qmp_usb_legacy_init(struct phy
*phy
)
768 struct qmp_usb
*qmp
= phy_get_drvdata(phy
);
769 const struct qmp_phy_cfg
*cfg
= qmp
->cfg
;
770 void __iomem
*pcs
= qmp
->pcs
;
773 ret
= regulator_bulk_enable(cfg
->num_vregs
, qmp
->vregs
);
775 dev_err(qmp
->dev
, "failed to enable regulators, err=%d\n", ret
);
779 ret
= reset_control_bulk_assert(cfg
->num_resets
, qmp
->resets
);
781 dev_err(qmp
->dev
, "reset assert failed\n");
782 goto err_disable_regulators
;
785 ret
= reset_control_bulk_deassert(cfg
->num_resets
, qmp
->resets
);
787 dev_err(qmp
->dev
, "reset deassert failed\n");
788 goto err_disable_regulators
;
791 ret
= clk_bulk_prepare_enable(cfg
->num_clks
, qmp
->clks
);
793 goto err_assert_reset
;
795 qmp_usb_legacy_init_dp_com(phy
);
797 qphy_setbits(pcs
, cfg
->regs
[QPHY_PCS_POWER_DOWN_CONTROL
], SW_PWRDN
);
802 reset_control_bulk_assert(cfg
->num_resets
, qmp
->resets
);
803 err_disable_regulators
:
804 regulator_bulk_disable(cfg
->num_vregs
, qmp
->vregs
);
809 static int qmp_usb_legacy_exit(struct phy
*phy
)
811 struct qmp_usb
*qmp
= phy_get_drvdata(phy
);
812 const struct qmp_phy_cfg
*cfg
= qmp
->cfg
;
814 reset_control_bulk_assert(cfg
->num_resets
, qmp
->resets
);
816 clk_bulk_disable_unprepare(cfg
->num_clks
, qmp
->clks
);
818 regulator_bulk_disable(cfg
->num_vregs
, qmp
->vregs
);
823 static int qmp_usb_legacy_power_on(struct phy
*phy
)
825 struct qmp_usb
*qmp
= phy_get_drvdata(phy
);
826 const struct qmp_phy_cfg
*cfg
= qmp
->cfg
;
827 void __iomem
*tx
= qmp
->tx
;
828 void __iomem
*rx
= qmp
->rx
;
829 void __iomem
*pcs
= qmp
->pcs
;
830 void __iomem
*status
;
834 qmp_usb_legacy_serdes_init(qmp
);
836 ret
= clk_prepare_enable(qmp
->pipe_clk
);
838 dev_err(qmp
->dev
, "pipe_clk enable failed err=%d\n", ret
);
842 /* Tx, Rx, and PCS configurations */
843 qmp_usb_legacy_configure_lane(tx
, cfg
->tx_tbl
, cfg
->tx_tbl_num
, 1);
844 qmp_usb_legacy_configure_lane(rx
, cfg
->rx_tbl
, cfg
->rx_tbl_num
, 1);
846 qmp_usb_legacy_configure_lane(qmp
->tx2
, cfg
->tx_tbl
, cfg
->tx_tbl_num
, 2);
847 qmp_usb_legacy_configure_lane(qmp
->rx2
, cfg
->rx_tbl
, cfg
->rx_tbl_num
, 2);
849 qmp_usb_legacy_configure(pcs
, cfg
->pcs_tbl
, cfg
->pcs_tbl_num
);
851 usleep_range(10, 20);
853 /* Pull PHY out of reset state */
854 qphy_clrbits(pcs
, cfg
->regs
[QPHY_SW_RESET
], SW_RESET
);
856 /* start SerDes and Phy-Coding-Sublayer */
857 qphy_setbits(pcs
, cfg
->regs
[QPHY_START_CTRL
], SERDES_START
| PCS_START
);
859 status
= pcs
+ cfg
->regs
[QPHY_PCS_STATUS
];
860 ret
= readl_poll_timeout(status
, val
, !(val
& PHYSTATUS
), 200,
861 PHY_INIT_COMPLETE_TIMEOUT
);
863 dev_err(qmp
->dev
, "phy initialization timed-out\n");
864 goto err_disable_pipe_clk
;
869 err_disable_pipe_clk
:
870 clk_disable_unprepare(qmp
->pipe_clk
);
875 static int qmp_usb_legacy_power_off(struct phy
*phy
)
877 struct qmp_usb
*qmp
= phy_get_drvdata(phy
);
878 const struct qmp_phy_cfg
*cfg
= qmp
->cfg
;
880 clk_disable_unprepare(qmp
->pipe_clk
);
883 qphy_setbits(qmp
->pcs
, cfg
->regs
[QPHY_SW_RESET
], SW_RESET
);
885 /* stop SerDes and Phy-Coding-Sublayer */
886 qphy_clrbits(qmp
->pcs
, cfg
->regs
[QPHY_START_CTRL
],
887 SERDES_START
| PCS_START
);
889 /* Put PHY into POWER DOWN state: active low */
890 qphy_clrbits(qmp
->pcs
, cfg
->regs
[QPHY_PCS_POWER_DOWN_CONTROL
],
896 static int qmp_usb_legacy_enable(struct phy
*phy
)
900 ret
= qmp_usb_legacy_init(phy
);
904 ret
= qmp_usb_legacy_power_on(phy
);
906 qmp_usb_legacy_exit(phy
);
911 static int qmp_usb_legacy_disable(struct phy
*phy
)
915 ret
= qmp_usb_legacy_power_off(phy
);
918 return qmp_usb_legacy_exit(phy
);
921 static int qmp_usb_legacy_set_mode(struct phy
*phy
, enum phy_mode mode
, int submode
)
923 struct qmp_usb
*qmp
= phy_get_drvdata(phy
);
930 static const struct phy_ops qmp_usb_legacy_phy_ops
= {
931 .init
= qmp_usb_legacy_enable
,
932 .exit
= qmp_usb_legacy_disable
,
933 .set_mode
= qmp_usb_legacy_set_mode
,
934 .owner
= THIS_MODULE
,
937 static void qmp_usb_legacy_enable_autonomous_mode(struct qmp_usb
*qmp
)
939 const struct qmp_phy_cfg
*cfg
= qmp
->cfg
;
940 void __iomem
*pcs_usb
= qmp
->pcs_usb
?: qmp
->pcs
;
941 void __iomem
*pcs_misc
= qmp
->pcs_misc
;
944 if (qmp
->mode
== PHY_MODE_USB_HOST_SS
||
945 qmp
->mode
== PHY_MODE_USB_DEVICE_SS
)
946 intr_mask
= ARCVR_DTCT_EN
| ALFPS_DTCT_EN
;
948 intr_mask
= ARCVR_DTCT_EN
| ARCVR_DTCT_EVENT_SEL
;
950 /* Clear any pending interrupts status */
951 qphy_setbits(pcs_usb
, cfg
->regs
[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR
], IRQ_CLEAR
);
952 /* Writing 1 followed by 0 clears the interrupt */
953 qphy_clrbits(pcs_usb
, cfg
->regs
[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR
], IRQ_CLEAR
);
955 qphy_clrbits(pcs_usb
, cfg
->regs
[QPHY_PCS_AUTONOMOUS_MODE_CTRL
],
956 ARCVR_DTCT_EN
| ALFPS_DTCT_EN
| ARCVR_DTCT_EVENT_SEL
);
958 /* Enable required PHY autonomous mode interrupts */
959 qphy_setbits(pcs_usb
, cfg
->regs
[QPHY_PCS_AUTONOMOUS_MODE_CTRL
], intr_mask
);
961 /* Enable i/o clamp_n for autonomous mode */
963 qphy_clrbits(pcs_misc
, QPHY_V3_PCS_MISC_CLAMP_ENABLE
, CLAMP_EN
);
966 static void qmp_usb_legacy_disable_autonomous_mode(struct qmp_usb
*qmp
)
968 const struct qmp_phy_cfg
*cfg
= qmp
->cfg
;
969 void __iomem
*pcs_usb
= qmp
->pcs_usb
?: qmp
->pcs
;
970 void __iomem
*pcs_misc
= qmp
->pcs_misc
;
972 /* Disable i/o clamp_n on resume for normal mode */
974 qphy_setbits(pcs_misc
, QPHY_V3_PCS_MISC_CLAMP_ENABLE
, CLAMP_EN
);
976 qphy_clrbits(pcs_usb
, cfg
->regs
[QPHY_PCS_AUTONOMOUS_MODE_CTRL
],
977 ARCVR_DTCT_EN
| ARCVR_DTCT_EVENT_SEL
| ALFPS_DTCT_EN
);
979 qphy_setbits(pcs_usb
, cfg
->regs
[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR
], IRQ_CLEAR
);
980 /* Writing 1 followed by 0 clears the interrupt */
981 qphy_clrbits(pcs_usb
, cfg
->regs
[QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR
], IRQ_CLEAR
);
984 static int __maybe_unused
qmp_usb_legacy_runtime_suspend(struct device
*dev
)
986 struct qmp_usb
*qmp
= dev_get_drvdata(dev
);
987 const struct qmp_phy_cfg
*cfg
= qmp
->cfg
;
989 dev_vdbg(dev
, "Suspending QMP phy, mode:%d\n", qmp
->mode
);
991 if (!qmp
->phy
->init_count
) {
992 dev_vdbg(dev
, "PHY not initialized, bailing out\n");
996 qmp_usb_legacy_enable_autonomous_mode(qmp
);
998 clk_disable_unprepare(qmp
->pipe_clk
);
999 clk_bulk_disable_unprepare(cfg
->num_clks
, qmp
->clks
);
1004 static int __maybe_unused
qmp_usb_legacy_runtime_resume(struct device
*dev
)
1006 struct qmp_usb
*qmp
= dev_get_drvdata(dev
);
1007 const struct qmp_phy_cfg
*cfg
= qmp
->cfg
;
1010 dev_vdbg(dev
, "Resuming QMP phy, mode:%d\n", qmp
->mode
);
1012 if (!qmp
->phy
->init_count
) {
1013 dev_vdbg(dev
, "PHY not initialized, bailing out\n");
1017 ret
= clk_bulk_prepare_enable(cfg
->num_clks
, qmp
->clks
);
1021 ret
= clk_prepare_enable(qmp
->pipe_clk
);
1023 dev_err(dev
, "pipe_clk enable failed, err=%d\n", ret
);
1024 clk_bulk_disable_unprepare(cfg
->num_clks
, qmp
->clks
);
1028 qmp_usb_legacy_disable_autonomous_mode(qmp
);
1033 static const struct dev_pm_ops qmp_usb_legacy_pm_ops
= {
1034 SET_RUNTIME_PM_OPS(qmp_usb_legacy_runtime_suspend
,
1035 qmp_usb_legacy_runtime_resume
, NULL
)
1038 static int qmp_usb_legacy_vreg_init(struct qmp_usb
*qmp
)
1040 const struct qmp_phy_cfg
*cfg
= qmp
->cfg
;
1041 struct device
*dev
= qmp
->dev
;
1042 int num
= cfg
->num_vregs
;
1045 qmp
->vregs
= devm_kcalloc(dev
, num
, sizeof(*qmp
->vregs
), GFP_KERNEL
);
1049 for (i
= 0; i
< num
; i
++)
1050 qmp
->vregs
[i
].supply
= cfg
->vreg_list
[i
];
1052 return devm_regulator_bulk_get(dev
, num
, qmp
->vregs
);
1055 static int qmp_usb_legacy_reset_init(struct qmp_usb
*qmp
)
1057 const struct qmp_phy_cfg
*cfg
= qmp
->cfg
;
1058 struct device
*dev
= qmp
->dev
;
1062 qmp
->resets
= devm_kcalloc(dev
, cfg
->num_resets
,
1063 sizeof(*qmp
->resets
), GFP_KERNEL
);
1067 for (i
= 0; i
< cfg
->num_resets
; i
++)
1068 qmp
->resets
[i
].id
= cfg
->reset_list
[i
];
1070 ret
= devm_reset_control_bulk_get_exclusive(dev
, cfg
->num_resets
, qmp
->resets
);
1072 return dev_err_probe(dev
, ret
, "failed to get resets\n");
1077 static int qmp_usb_legacy_clk_init(struct qmp_usb
*qmp
)
1079 const struct qmp_phy_cfg
*cfg
= qmp
->cfg
;
1080 struct device
*dev
= qmp
->dev
;
1081 int num
= cfg
->num_clks
;
1084 qmp
->clks
= devm_kcalloc(dev
, num
, sizeof(*qmp
->clks
), GFP_KERNEL
);
1088 for (i
= 0; i
< num
; i
++)
1089 qmp
->clks
[i
].id
= cfg
->clk_list
[i
];
1091 return devm_clk_bulk_get(dev
, num
, qmp
->clks
);
1094 static void phy_clk_release_provider(void *res
)
1096 of_clk_del_provider(res
);
1100 * Register a fixed rate pipe clock.
1102 * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
1103 * controls it. The <s>_pipe_clk coming out of the GCC is requested
1104 * by the PHY driver for its operations.
1105 * We register the <s>_pipe_clksrc here. The gcc driver takes care
1106 * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
1107 * Below picture shows this relationship.
1110 * | PHY block |<<---------------------------------------+
1112 * | +-------+ | +-----+ |
1113 * I/P---^-->| PLL |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
1114 * clk | +-------+ | +-----+
1117 static int phy_pipe_clk_register(struct qmp_usb
*qmp
, struct device_node
*np
)
1119 struct clk_fixed_rate
*fixed
= &qmp
->pipe_clk_fixed
;
1120 struct clk_init_data init
= { };
1123 ret
= of_property_read_string(np
, "clock-output-names", &init
.name
);
1125 dev_err(qmp
->dev
, "%pOFn: No clock-output-names\n", np
);
1129 init
.ops
= &clk_fixed_rate_ops
;
1131 /* controllers using QMP phys use 125MHz pipe clock interface */
1132 fixed
->fixed_rate
= 125000000;
1133 fixed
->hw
.init
= &init
;
1135 ret
= devm_clk_hw_register(qmp
->dev
, &fixed
->hw
);
1139 ret
= of_clk_add_hw_provider(np
, of_clk_hw_simple_get
, &fixed
->hw
);
1144 * Roll a devm action because the clock provider is the child node, but
1145 * the child node is not actually a device.
1147 return devm_add_action_or_reset(qmp
->dev
, phy_clk_release_provider
, np
);
1150 static int qmp_usb_legacy_parse_dt_legacy(struct qmp_usb
*qmp
, struct device_node
*np
)
1152 struct platform_device
*pdev
= to_platform_device(qmp
->dev
);
1153 const struct qmp_phy_cfg
*cfg
= qmp
->cfg
;
1154 struct device
*dev
= qmp
->dev
;
1156 qmp
->serdes
= devm_platform_ioremap_resource(pdev
, 0);
1157 if (IS_ERR(qmp
->serdes
))
1158 return PTR_ERR(qmp
->serdes
);
1160 qmp
->dp_com
= devm_platform_ioremap_resource(pdev
, 1);
1161 if (IS_ERR(qmp
->dp_com
))
1162 return PTR_ERR(qmp
->dp_com
);
1165 * Get memory resources for the PHY:
1166 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
1167 * For dual lane PHYs: tx2 -> 3, rx2 -> 4, pcs_misc (optional) -> 5
1168 * For single lane PHYs: pcs_misc (optional) -> 3.
1170 qmp
->tx
= devm_of_iomap(dev
, np
, 0, NULL
);
1171 if (IS_ERR(qmp
->tx
))
1172 return PTR_ERR(qmp
->tx
);
1174 qmp
->rx
= devm_of_iomap(dev
, np
, 1, NULL
);
1175 if (IS_ERR(qmp
->rx
))
1176 return PTR_ERR(qmp
->rx
);
1178 qmp
->pcs
= devm_of_iomap(dev
, np
, 2, NULL
);
1179 if (IS_ERR(qmp
->pcs
))
1180 return PTR_ERR(qmp
->pcs
);
1182 if (cfg
->pcs_usb_offset
)
1183 qmp
->pcs_usb
= qmp
->pcs
+ cfg
->pcs_usb_offset
;
1185 qmp
->tx2
= devm_of_iomap(dev
, np
, 3, NULL
);
1186 if (IS_ERR(qmp
->tx2
))
1187 return PTR_ERR(qmp
->tx2
);
1189 qmp
->rx2
= devm_of_iomap(dev
, np
, 4, NULL
);
1190 if (IS_ERR(qmp
->rx2
))
1191 return PTR_ERR(qmp
->rx2
);
1193 qmp
->pcs_misc
= devm_of_iomap(dev
, np
, 5, NULL
);
1194 if (IS_ERR(qmp
->pcs_misc
)) {
1195 dev_vdbg(dev
, "PHY pcs_misc-reg not used\n");
1196 qmp
->pcs_misc
= NULL
;
1199 qmp
->pipe_clk
= devm_get_clk_from_child(dev
, np
, NULL
);
1200 if (IS_ERR(qmp
->pipe_clk
)) {
1201 return dev_err_probe(dev
, PTR_ERR(qmp
->pipe_clk
),
1202 "failed to get pipe clock\n");
1208 static int qmp_usb_legacy_parse_dt(struct qmp_usb
*qmp
)
1210 struct platform_device
*pdev
= to_platform_device(qmp
->dev
);
1211 const struct qmp_phy_cfg
*cfg
= qmp
->cfg
;
1212 const struct qmp_usb_legacy_offsets
*offs
= cfg
->offsets
;
1213 struct device
*dev
= qmp
->dev
;
1219 base
= devm_platform_ioremap_resource(pdev
, 0);
1221 return PTR_ERR(base
);
1223 qmp
->serdes
= base
+ offs
->serdes
;
1224 qmp
->pcs
= base
+ offs
->pcs
;
1225 qmp
->pcs_usb
= base
+ offs
->pcs_usb
;
1226 qmp
->tx
= base
+ offs
->tx
;
1227 qmp
->rx
= base
+ offs
->rx
;
1229 qmp
->pipe_clk
= devm_clk_get(dev
, "pipe");
1230 if (IS_ERR(qmp
->pipe_clk
)) {
1231 return dev_err_probe(dev
, PTR_ERR(qmp
->pipe_clk
),
1232 "failed to get pipe clock\n");
1238 static int qmp_usb_legacy_probe(struct platform_device
*pdev
)
1240 struct device
*dev
= &pdev
->dev
;
1241 struct phy_provider
*phy_provider
;
1242 struct device_node
*np
;
1243 struct qmp_usb
*qmp
;
1246 qmp
= devm_kzalloc(dev
, sizeof(*qmp
), GFP_KERNEL
);
1251 dev_set_drvdata(dev
, qmp
);
1253 qmp
->cfg
= of_device_get_match_data(dev
);
1257 ret
= qmp_usb_legacy_clk_init(qmp
);
1261 ret
= qmp_usb_legacy_reset_init(qmp
);
1265 ret
= qmp_usb_legacy_vreg_init(qmp
);
1269 /* Check for legacy binding with child node. */
1270 np
= of_get_next_available_child(dev
->of_node
, NULL
);
1272 ret
= qmp_usb_legacy_parse_dt_legacy(qmp
, np
);
1274 np
= of_node_get(dev
->of_node
);
1275 ret
= qmp_usb_legacy_parse_dt(qmp
);
1280 pm_runtime_set_active(dev
);
1281 ret
= devm_pm_runtime_enable(dev
);
1285 * Prevent runtime pm from being ON by default. Users can enable
1286 * it using power/control in sysfs.
1288 pm_runtime_forbid(dev
);
1290 ret
= phy_pipe_clk_register(qmp
, np
);
1294 qmp
->phy
= devm_phy_create(dev
, np
, &qmp_usb_legacy_phy_ops
);
1295 if (IS_ERR(qmp
->phy
)) {
1296 ret
= PTR_ERR(qmp
->phy
);
1297 dev_err(dev
, "failed to create PHY: %d\n", ret
);
1301 phy_set_drvdata(qmp
->phy
, qmp
);
1305 phy_provider
= devm_of_phy_provider_register(dev
, of_phy_simple_xlate
);
1307 return PTR_ERR_OR_ZERO(phy_provider
);
1314 static const struct of_device_id qmp_usb_legacy_of_match_table
[] = {
1316 .compatible
= "qcom,sc7180-qmp-usb3-phy",
1317 .data
= &sc7180_usb3phy_cfg
,
1319 .compatible
= "qcom,sc8180x-qmp-usb3-phy",
1320 .data
= &sm8150_usb3phy_cfg
,
1322 .compatible
= "qcom,sdm845-qmp-usb3-phy",
1323 .data
= &qmp_v3_usb3phy_cfg
,
1325 .compatible
= "qcom,sm8150-qmp-usb3-phy",
1326 .data
= &sm8150_usb3phy_cfg
,
1328 .compatible
= "qcom,sm8250-qmp-usb3-phy",
1329 .data
= &sm8250_usb3phy_cfg
,
1331 .compatible
= "qcom,sm8350-qmp-usb3-phy",
1332 .data
= &sm8350_usb3phy_cfg
,
1334 .compatible
= "qcom,sm8450-qmp-usb3-phy",
1335 .data
= &sm8350_usb3phy_cfg
,
1339 MODULE_DEVICE_TABLE(of
, qmp_usb_legacy_of_match_table
);
1341 static struct platform_driver qmp_usb_legacy_driver
= {
1342 .probe
= qmp_usb_legacy_probe
,
1344 .name
= "qcom-qmp-usb-legacy-phy",
1345 .pm
= &qmp_usb_legacy_pm_ops
,
1346 .of_match_table
= qmp_usb_legacy_of_match_table
,
1350 module_platform_driver(qmp_usb_legacy_driver
);
1352 MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
1353 MODULE_DESCRIPTION("Qualcomm QMP legacy USB+DP PHY driver");
1354 MODULE_LICENSE("GPL v2");