2 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
15 #include <linux/clk.h>
16 #include <linux/clk-provider.h>
17 #include <linux/delay.h>
18 #include <linux/err.h>
20 #include <linux/iopoll.h>
21 #include <linux/kernel.h>
22 #include <linux/module.h>
24 #include <linux/of_device.h>
25 #include <linux/of_address.h>
26 #include <linux/phy/phy.h>
27 #include <linux/platform_device.h>
28 #include <linux/regulator/consumer.h>
29 #include <linux/reset.h>
30 #include <linux/slab.h>
32 #include <dt-bindings/phy/phy.h>
34 /* QMP PHY QSERDES COM registers */
35 #define QSERDES_COM_BG_TIMER 0x00c
36 #define QSERDES_COM_SSC_EN_CENTER 0x010
37 #define QSERDES_COM_SSC_ADJ_PER1 0x014
38 #define QSERDES_COM_SSC_ADJ_PER2 0x018
39 #define QSERDES_COM_SSC_PER1 0x01c
40 #define QSERDES_COM_SSC_PER2 0x020
41 #define QSERDES_COM_SSC_STEP_SIZE1 0x024
42 #define QSERDES_COM_SSC_STEP_SIZE2 0x028
43 #define QSERDES_COM_BIAS_EN_CLKBUFLR_EN 0x034
44 #define QSERDES_COM_CLK_ENABLE1 0x038
45 #define QSERDES_COM_SYS_CLK_CTRL 0x03c
46 #define QSERDES_COM_SYSCLK_BUF_ENABLE 0x040
47 #define QSERDES_COM_PLL_IVCO 0x048
48 #define QSERDES_COM_LOCK_CMP1_MODE0 0x04c
49 #define QSERDES_COM_LOCK_CMP2_MODE0 0x050
50 #define QSERDES_COM_LOCK_CMP3_MODE0 0x054
51 #define QSERDES_COM_LOCK_CMP1_MODE1 0x058
52 #define QSERDES_COM_LOCK_CMP2_MODE1 0x05c
53 #define QSERDES_COM_LOCK_CMP3_MODE1 0x060
54 #define QSERDES_COM_BG_TRIM 0x070
55 #define QSERDES_COM_CLK_EP_DIV 0x074
56 #define QSERDES_COM_CP_CTRL_MODE0 0x078
57 #define QSERDES_COM_CP_CTRL_MODE1 0x07c
58 #define QSERDES_COM_PLL_RCTRL_MODE0 0x084
59 #define QSERDES_COM_PLL_RCTRL_MODE1 0x088
60 #define QSERDES_COM_PLL_CCTRL_MODE0 0x090
61 #define QSERDES_COM_PLL_CCTRL_MODE1 0x094
62 #define QSERDES_COM_BIAS_EN_CTRL_BY_PSM 0x0a8
63 #define QSERDES_COM_SYSCLK_EN_SEL 0x0ac
64 #define QSERDES_COM_RESETSM_CNTRL 0x0b4
65 #define QSERDES_COM_RESTRIM_CTRL 0x0bc
66 #define QSERDES_COM_RESCODE_DIV_NUM 0x0c4
67 #define QSERDES_COM_LOCK_CMP_EN 0x0c8
68 #define QSERDES_COM_LOCK_CMP_CFG 0x0cc
69 #define QSERDES_COM_DEC_START_MODE0 0x0d0
70 #define QSERDES_COM_DEC_START_MODE1 0x0d4
71 #define QSERDES_COM_DIV_FRAC_START1_MODE0 0x0dc
72 #define QSERDES_COM_DIV_FRAC_START2_MODE0 0x0e0
73 #define QSERDES_COM_DIV_FRAC_START3_MODE0 0x0e4
74 #define QSERDES_COM_DIV_FRAC_START1_MODE1 0x0e8
75 #define QSERDES_COM_DIV_FRAC_START2_MODE1 0x0ec
76 #define QSERDES_COM_DIV_FRAC_START3_MODE1 0x0f0
77 #define QSERDES_COM_INTEGLOOP_GAIN0_MODE0 0x108
78 #define QSERDES_COM_INTEGLOOP_GAIN1_MODE0 0x10c
79 #define QSERDES_COM_INTEGLOOP_GAIN0_MODE1 0x110
80 #define QSERDES_COM_INTEGLOOP_GAIN1_MODE1 0x114
81 #define QSERDES_COM_VCO_TUNE_CTRL 0x124
82 #define QSERDES_COM_VCO_TUNE_MAP 0x128
83 #define QSERDES_COM_VCO_TUNE1_MODE0 0x12c
84 #define QSERDES_COM_VCO_TUNE2_MODE0 0x130
85 #define QSERDES_COM_VCO_TUNE1_MODE1 0x134
86 #define QSERDES_COM_VCO_TUNE2_MODE1 0x138
87 #define QSERDES_COM_VCO_TUNE_TIMER1 0x144
88 #define QSERDES_COM_VCO_TUNE_TIMER2 0x148
89 #define QSERDES_COM_BG_CTRL 0x170
90 #define QSERDES_COM_CLK_SELECT 0x174
91 #define QSERDES_COM_HSCLK_SEL 0x178
92 #define QSERDES_COM_CORECLK_DIV 0x184
93 #define QSERDES_COM_CORE_CLK_EN 0x18c
94 #define QSERDES_COM_C_READY_STATUS 0x190
95 #define QSERDES_COM_CMN_CONFIG 0x194
96 #define QSERDES_COM_SVS_MODE_CLK_SEL 0x19c
97 #define QSERDES_COM_DEBUG_BUS0 0x1a0
98 #define QSERDES_COM_DEBUG_BUS1 0x1a4
99 #define QSERDES_COM_DEBUG_BUS2 0x1a8
100 #define QSERDES_COM_DEBUG_BUS3 0x1ac
101 #define QSERDES_COM_DEBUG_BUS_SEL 0x1b0
102 #define QSERDES_COM_CORECLK_DIV_MODE1 0x1bc
104 /* QMP PHY TX registers */
105 #define QSERDES_TX_RES_CODE_LANE_OFFSET 0x054
106 #define QSERDES_TX_DEBUG_BUS_SEL 0x064
107 #define QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN 0x068
108 #define QSERDES_TX_LANE_MODE 0x094
109 #define QSERDES_TX_RCV_DETECT_LVL_2 0x0ac
111 /* QMP PHY RX registers */
112 #define QSERDES_RX_UCDR_SO_GAIN_HALF 0x010
113 #define QSERDES_RX_UCDR_SO_GAIN 0x01c
114 #define QSERDES_RX_UCDR_FASTLOCK_FO_GAIN 0x040
115 #define QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE 0x048
116 #define QSERDES_RX_RX_TERM_BW 0x090
117 #define QSERDES_RX_RX_EQ_GAIN1_LSB 0x0c4
118 #define QSERDES_RX_RX_EQ_GAIN1_MSB 0x0c8
119 #define QSERDES_RX_RX_EQ_GAIN2_LSB 0x0cc
120 #define QSERDES_RX_RX_EQ_GAIN2_MSB 0x0d0
121 #define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 0x0d8
122 #define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 0x0dc
123 #define QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 0x0e0
124 #define QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x108
125 #define QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x10c
126 #define QSERDES_RX_SIGDET_ENABLES 0x110
127 #define QSERDES_RX_SIGDET_CNTRL 0x114
128 #define QSERDES_RX_SIGDET_LVL 0x118
129 #define QSERDES_RX_SIGDET_DEGLITCH_CNTRL 0x11c
130 #define QSERDES_RX_RX_BAND 0x120
131 #define QSERDES_RX_RX_INTERFACE_MODE 0x12c
133 /* QMP PHY PCS registers */
134 #define QPHY_POWER_DOWN_CONTROL 0x04
135 #define QPHY_TXDEEMPH_M6DB_V0 0x24
136 #define QPHY_TXDEEMPH_M3P5DB_V0 0x28
137 #define QPHY_ENDPOINT_REFCLK_DRIVE 0x54
138 #define QPHY_RX_IDLE_DTCT_CNTRL 0x58
139 #define QPHY_POWER_STATE_CONFIG1 0x60
140 #define QPHY_POWER_STATE_CONFIG2 0x64
141 #define QPHY_POWER_STATE_CONFIG4 0x6c
142 #define QPHY_LOCK_DETECT_CONFIG1 0x80
143 #define QPHY_LOCK_DETECT_CONFIG2 0x84
144 #define QPHY_LOCK_DETECT_CONFIG3 0x88
145 #define QPHY_PWRUP_RESET_DLY_TIME_AUXCLK 0xa0
146 #define QPHY_LP_WAKEUP_DLY_TIME_AUXCLK 0xa4
147 #define QPHY_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB 0x1A8
148 #define QPHY_OSC_DTCT_ACTIONS 0x1AC
149 #define QPHY_RX_SIGDET_LVL 0x1D8
150 #define QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB 0x1DC
151 #define QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB 0x1E0
153 /* QPHY_SW_RESET bit */
154 #define SW_RESET BIT(0)
155 /* QPHY_POWER_DOWN_CONTROL */
156 #define SW_PWRDN BIT(0)
157 #define REFCLK_DRV_DSBL BIT(1)
158 /* QPHY_START_CONTROL bits */
159 #define SERDES_START BIT(0)
160 #define PCS_START BIT(1)
161 #define PLL_READY_GATE_EN BIT(3)
162 /* QPHY_PCS_STATUS bit */
163 #define PHYSTATUS BIT(6)
164 /* QPHY_COM_PCS_READY_STATUS bit */
165 #define PCS_READY BIT(0)
167 #define PHY_INIT_COMPLETE_TIMEOUT 1000
168 #define POWER_DOWN_DELAY_US_MIN 10
169 #define POWER_DOWN_DELAY_US_MAX 11
171 #define MAX_PROP_NAME 32
173 struct qmp_phy_init_tbl
{
177 * register part of layout ?
178 * if yes, then offset gives index in the reg-layout
183 #define QMP_PHY_INIT_CFG(o, v) \
189 #define QMP_PHY_INIT_CFG_L(o, v) \
196 /* set of registers with offsets different per-PHY */
197 enum qphy_reg_layout
{
198 /* Common block control registers */
200 QPHY_COM_POWER_DOWN_CONTROL
,
201 QPHY_COM_START_CONTROL
,
202 QPHY_COM_PCS_READY_STATUS
,
204 QPHY_PLL_LOCK_CHK_DLY_TIME
,
208 QPHY_FLL_CNT_VAL_H_TOL
,
212 QPHY_PCS_READY_STATUS
,
215 static const unsigned int pciephy_regs_layout
[] = {
216 [QPHY_COM_SW_RESET
] = 0x400,
217 [QPHY_COM_POWER_DOWN_CONTROL
] = 0x404,
218 [QPHY_COM_START_CONTROL
] = 0x408,
219 [QPHY_COM_PCS_READY_STATUS
] = 0x448,
220 [QPHY_PLL_LOCK_CHK_DLY_TIME
] = 0xa8,
221 [QPHY_FLL_CNTRL1
] = 0xc4,
222 [QPHY_FLL_CNTRL2
] = 0xc8,
223 [QPHY_FLL_CNT_VAL_L
] = 0xcc,
224 [QPHY_FLL_CNT_VAL_H_TOL
] = 0xd0,
225 [QPHY_FLL_MAN_CODE
] = 0xd4,
226 [QPHY_SW_RESET
] = 0x00,
227 [QPHY_START_CTRL
] = 0x08,
228 [QPHY_PCS_READY_STATUS
] = 0x174,
231 static const unsigned int usb3phy_regs_layout
[] = {
232 [QPHY_FLL_CNTRL1
] = 0xc0,
233 [QPHY_FLL_CNTRL2
] = 0xc4,
234 [QPHY_FLL_CNT_VAL_L
] = 0xc8,
235 [QPHY_FLL_CNT_VAL_H_TOL
] = 0xcc,
236 [QPHY_FLL_MAN_CODE
] = 0xd0,
237 [QPHY_SW_RESET
] = 0x00,
238 [QPHY_START_CTRL
] = 0x08,
239 [QPHY_PCS_READY_STATUS
] = 0x17c,
242 static const struct qmp_phy_init_tbl msm8996_pcie_serdes_tbl
[] = {
243 QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN
, 0x1c),
244 QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1
, 0x10),
245 QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT
, 0x33),
246 QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG
, 0x06),
247 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN
, 0x42),
248 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP
, 0x00),
249 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1
, 0xff),
250 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2
, 0x1f),
251 QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL
, 0x01),
252 QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL
, 0x01),
253 QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN
, 0x00),
254 QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV
, 0x0a),
255 QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER
, 0x09),
256 QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0
, 0x82),
257 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0
, 0x03),
258 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0
, 0x55),
259 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0
, 0x55),
260 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0
, 0x00),
261 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0
, 0x1a),
262 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0
, 0x0a),
263 QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT
, 0x33),
264 QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL
, 0x02),
265 QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE
, 0x1f),
266 QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL
, 0x04),
267 QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0
, 0x0b),
268 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0
, 0x16),
269 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0
, 0x28),
270 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0
, 0x00),
271 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0
, 0x80),
272 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER
, 0x01),
273 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1
, 0x31),
274 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2
, 0x01),
275 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1
, 0x02),
276 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2
, 0x00),
277 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1
, 0x2f),
278 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2
, 0x19),
279 QMP_PHY_INIT_CFG(QSERDES_COM_RESCODE_DIV_NUM
, 0x15),
280 QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM
, 0x0f),
281 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO
, 0x0f),
282 QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV
, 0x19),
283 QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1
, 0x10),
284 QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL
, 0x00),
285 QMP_PHY_INIT_CFG(QSERDES_COM_RESCODE_DIV_NUM
, 0x40),
288 static const struct qmp_phy_init_tbl msm8996_pcie_tx_tbl
[] = {
289 QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN
, 0x45),
290 QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE
, 0x06),
293 static const struct qmp_phy_init_tbl msm8996_pcie_rx_tbl
[] = {
294 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES
, 0x1c),
295 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2
, 0x01),
296 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3
, 0x00),
297 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4
, 0xdb),
298 QMP_PHY_INIT_CFG(QSERDES_RX_RX_BAND
, 0x18),
299 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN
, 0x04),
300 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN_HALF
, 0x04),
301 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE
, 0x4b),
302 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL
, 0x14),
303 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL
, 0x19),
306 static const struct qmp_phy_init_tbl msm8996_pcie_pcs_tbl
[] = {
307 QMP_PHY_INIT_CFG(QPHY_RX_IDLE_DTCT_CNTRL
, 0x4c),
308 QMP_PHY_INIT_CFG(QPHY_PWRUP_RESET_DLY_TIME_AUXCLK
, 0x00),
309 QMP_PHY_INIT_CFG(QPHY_LP_WAKEUP_DLY_TIME_AUXCLK
, 0x01),
311 QMP_PHY_INIT_CFG_L(QPHY_PLL_LOCK_CHK_DLY_TIME
, 0x05),
313 QMP_PHY_INIT_CFG(QPHY_ENDPOINT_REFCLK_DRIVE
, 0x05),
314 QMP_PHY_INIT_CFG(QPHY_POWER_DOWN_CONTROL
, 0x02),
315 QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG4
, 0x00),
316 QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG1
, 0xa3),
317 QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M3P5DB_V0
, 0x0e),
320 static const struct qmp_phy_init_tbl msm8996_usb3_serdes_tbl
[] = {
321 QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL
, 0x14),
322 QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN
, 0x08),
323 QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT
, 0x30),
324 QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG
, 0x06),
325 QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL
, 0x01),
326 QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL
, 0x00),
327 QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM
, 0x0f),
328 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO
, 0x0f),
329 QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL
, 0x04),
330 /* PLL and Loop filter settings */
331 QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0
, 0x82),
332 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0
, 0x55),
333 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0
, 0x55),
334 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0
, 0x03),
335 QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0
, 0x0b),
336 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0
, 0x16),
337 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0
, 0x28),
338 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0
, 0x80),
339 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL
, 0x00),
340 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0
, 0x15),
341 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0
, 0x34),
342 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0
, 0x00),
343 QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN
, 0x00),
344 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_CFG
, 0x00),
345 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP
, 0x00),
346 QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER
, 0x0a),
348 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER
, 0x01),
349 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1
, 0x31),
350 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2
, 0x01),
351 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1
, 0x00),
352 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2
, 0x00),
353 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1
, 0xde),
354 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2
, 0x07),
357 static const struct qmp_phy_init_tbl msm8996_usb3_tx_tbl
[] = {
358 QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN
, 0x45),
359 QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2
, 0x12),
360 QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE
, 0x06),
363 static const struct qmp_phy_init_tbl msm8996_usb3_rx_tbl
[] = {
364 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_FASTLOCK_FO_GAIN
, 0x0b),
365 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN
, 0x04),
366 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2
, 0x02),
367 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3
, 0x4c),
368 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4
, 0xbb),
369 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1
, 0x77),
370 QMP_PHY_INIT_CFG(QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2
, 0x80),
371 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL
, 0x03),
372 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_LVL
, 0x18),
373 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL
, 0x16),
376 static const struct qmp_phy_init_tbl msm8996_usb3_pcs_tbl
[] = {
378 QMP_PHY_INIT_CFG_L(QPHY_FLL_CNTRL2
, 0x03),
379 QMP_PHY_INIT_CFG_L(QPHY_FLL_CNTRL1
, 0x02),
380 QMP_PHY_INIT_CFG_L(QPHY_FLL_CNT_VAL_L
, 0x09),
381 QMP_PHY_INIT_CFG_L(QPHY_FLL_CNT_VAL_H_TOL
, 0x42),
382 QMP_PHY_INIT_CFG_L(QPHY_FLL_MAN_CODE
, 0x85),
384 /* Lock Det settings */
385 QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG1
, 0xd1),
386 QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG2
, 0x1f),
387 QMP_PHY_INIT_CFG(QPHY_LOCK_DETECT_CONFIG3
, 0x47),
388 QMP_PHY_INIT_CFG(QPHY_POWER_STATE_CONFIG2
, 0x08),
391 static const struct qmp_phy_init_tbl ipq8074_pcie_serdes_tbl
[] = {
392 QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN
, 0x18),
393 QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1
, 0x10),
394 QMP_PHY_INIT_CFG(QSERDES_COM_BG_TRIM
, 0xf),
395 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP_EN
, 0x1),
396 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP
, 0x0),
397 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER1
, 0x1f),
398 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_TIMER2
, 0x3f),
399 QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG
, 0x6),
400 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO
, 0xf),
401 QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL
, 0x0),
402 QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL
, 0x1),
403 QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN
, 0x20),
404 QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV
, 0xa),
405 QMP_PHY_INIT_CFG(QSERDES_COM_RESETSM_CNTRL
, 0x20),
406 QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER
, 0xa),
407 QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL
, 0xa),
408 QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0
, 0x82),
409 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0
, 0x3),
410 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0
, 0x55),
411 QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0
, 0x55),
412 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0
, 0x0),
413 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0
, 0xD),
414 QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0
, 0xD04),
415 QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT
, 0x33),
416 QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL
, 0x2),
417 QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE
, 0x1f),
418 QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0
, 0xb),
419 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0
, 0x16),
420 QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0
, 0x28),
421 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0
, 0x0),
422 QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0
, 0x80),
423 QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CTRL_BY_PSM
, 0x1),
424 QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL
, 0xa),
425 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_EN_CENTER
, 0x1),
426 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER1
, 0x31),
427 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_PER2
, 0x1),
428 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER1
, 0x2),
429 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_ADJ_PER2
, 0x0),
430 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE1
, 0x2f),
431 QMP_PHY_INIT_CFG(QSERDES_COM_SSC_STEP_SIZE2
, 0x19),
432 QMP_PHY_INIT_CFG(QSERDES_COM_CLK_EP_DIV
, 0x19),
433 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_CNTRL
, 0x7),
436 static const struct qmp_phy_init_tbl ipq8074_pcie_tx_tbl
[] = {
437 QMP_PHY_INIT_CFG(QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN
, 0x45),
438 QMP_PHY_INIT_CFG(QSERDES_TX_LANE_MODE
, 0x6),
439 QMP_PHY_INIT_CFG(QSERDES_TX_RES_CODE_LANE_OFFSET
, 0x2),
440 QMP_PHY_INIT_CFG(QSERDES_TX_RCV_DETECT_LVL_2
, 0x12),
443 static const struct qmp_phy_init_tbl ipq8074_pcie_rx_tbl
[] = {
444 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_ENABLES
, 0x1c),
445 QMP_PHY_INIT_CFG(QSERDES_RX_SIGDET_DEGLITCH_CNTRL
, 0x14),
446 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2
, 0x1),
447 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3
, 0x0),
448 QMP_PHY_INIT_CFG(QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4
, 0xdb),
449 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_SATURATION_AND_ENABLE
, 0x4b),
450 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN
, 0x4),
451 QMP_PHY_INIT_CFG(QSERDES_RX_UCDR_SO_GAIN_HALF
, 0x4),
454 static const struct qmp_phy_init_tbl ipq8074_pcie_pcs_tbl
[] = {
455 QMP_PHY_INIT_CFG(QPHY_ENDPOINT_REFCLK_DRIVE
, 0x4),
456 QMP_PHY_INIT_CFG(QPHY_OSC_DTCT_ACTIONS
, 0x0),
457 QMP_PHY_INIT_CFG(QPHY_PWRUP_RESET_DLY_TIME_AUXCLK
, 0x40),
458 QMP_PHY_INIT_CFG(QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_MSB
, 0x0),
459 QMP_PHY_INIT_CFG(QPHY_L1SS_WAKEUP_DLY_TIME_AUXCLK_LSB
, 0x40),
460 QMP_PHY_INIT_CFG(QPHY_PLL_LOCK_CHK_DLY_TIME_AUXCLK_LSB
, 0x0),
461 QMP_PHY_INIT_CFG(QPHY_LP_WAKEUP_DLY_TIME_AUXCLK
, 0x40),
462 QMP_PHY_INIT_CFG_L(QPHY_PLL_LOCK_CHK_DLY_TIME
, 0x73),
463 QMP_PHY_INIT_CFG(QPHY_RX_SIGDET_LVL
, 0x99),
464 QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M6DB_V0
, 0x15),
465 QMP_PHY_INIT_CFG(QPHY_TXDEEMPH_M3P5DB_V0
, 0xe),
466 QMP_PHY_INIT_CFG_L(QPHY_SW_RESET
, 0x0),
467 QMP_PHY_INIT_CFG_L(QPHY_START_CTRL
, 0x3),
470 /* struct qmp_phy_cfg - per-PHY initialization config */
472 /* phy-type - PCIE/UFS/USB */
474 /* number of lanes provided by phy */
477 /* Init sequence for PHY blocks - serdes, tx, rx, pcs */
478 const struct qmp_phy_init_tbl
*serdes_tbl
;
480 const struct qmp_phy_init_tbl
*tx_tbl
;
482 const struct qmp_phy_init_tbl
*rx_tbl
;
484 const struct qmp_phy_init_tbl
*pcs_tbl
;
487 /* clock ids to be requested */
488 const char * const *clk_list
;
490 /* resets to be requested */
491 const char * const *reset_list
;
493 /* regulators to be requested */
494 const char * const *vreg_list
;
497 /* array of registers with different offsets */
498 const unsigned int *regs
;
500 unsigned int start_ctrl
;
501 unsigned int pwrdn_ctrl
;
502 unsigned int mask_pcs_ready
;
503 unsigned int mask_com_pcs_ready
;
505 /* true, if PHY has a separate PHY_COM control block */
506 bool has_phy_com_ctrl
;
507 /* true, if PHY has a reset for individual lanes */
509 /* true, if PHY needs delay after POWER_DOWN */
510 bool has_pwrdn_delay
;
511 /* power_down delay in usec */
517 * struct qmp_phy - per-lane phy descriptor
520 * @tx: iomapped memory space for lane's tx
521 * @rx: iomapped memory space for lane's rx
522 * @pcs: iomapped memory space for lane's pcs
523 * @pipe_clk: pipe lock
525 * @qmp: QMP phy to which this lane belongs
526 * @lane_rst: lane's reset controller
533 struct clk
*pipe_clk
;
535 struct qcom_qmp
*qmp
;
536 struct reset_control
*lane_rst
;
540 * struct qcom_qmp - structure holding QMP phy block attributes
543 * @serdes: iomapped memory space for phy's serdes
545 * @clks: array of clocks required by phy
546 * @resets: array of resets required by phy
547 * @vregs: regulator supplies bulk data
549 * @cfg: phy specific configuration
550 * @phys: array of per-lane phy descriptors
551 * @phy_mutex: mutex lock for PHY common block initialization
552 * @init_count: phy common block initialization count
556 void __iomem
*serdes
;
559 struct reset_control
**resets
;
560 struct regulator_bulk_data
*vregs
;
562 const struct qmp_phy_cfg
*cfg
;
563 struct qmp_phy
**phys
;
565 struct mutex phy_mutex
;
569 static inline void qphy_setbits(void __iomem
*base
, u32 offset
, u32 val
)
573 reg
= readl(base
+ offset
);
575 writel(reg
, base
+ offset
);
577 /* ensure that above write is through */
578 readl(base
+ offset
);
581 static inline void qphy_clrbits(void __iomem
*base
, u32 offset
, u32 val
)
585 reg
= readl(base
+ offset
);
587 writel(reg
, base
+ offset
);
589 /* ensure that above write is through */
590 readl(base
+ offset
);
593 /* list of clocks required by phy */
594 static const char * const msm8996_phy_clk_l
[] = {
595 "aux", "cfg_ahb", "ref",
599 static const char * const msm8996_pciephy_reset_l
[] = {
600 "phy", "common", "cfg",
603 static const char * const msm8996_usb3phy_reset_l
[] = {
607 /* list of regulators */
608 static const char * const msm8996_phy_vreg_l
[] = {
609 "vdda-phy", "vdda-pll",
612 static const struct qmp_phy_cfg msm8996_pciephy_cfg
= {
613 .type
= PHY_TYPE_PCIE
,
616 .serdes_tbl
= msm8996_pcie_serdes_tbl
,
617 .serdes_tbl_num
= ARRAY_SIZE(msm8996_pcie_serdes_tbl
),
618 .tx_tbl
= msm8996_pcie_tx_tbl
,
619 .tx_tbl_num
= ARRAY_SIZE(msm8996_pcie_tx_tbl
),
620 .rx_tbl
= msm8996_pcie_rx_tbl
,
621 .rx_tbl_num
= ARRAY_SIZE(msm8996_pcie_rx_tbl
),
622 .pcs_tbl
= msm8996_pcie_pcs_tbl
,
623 .pcs_tbl_num
= ARRAY_SIZE(msm8996_pcie_pcs_tbl
),
624 .clk_list
= msm8996_phy_clk_l
,
625 .num_clks
= ARRAY_SIZE(msm8996_phy_clk_l
),
626 .reset_list
= msm8996_pciephy_reset_l
,
627 .num_resets
= ARRAY_SIZE(msm8996_pciephy_reset_l
),
628 .vreg_list
= msm8996_phy_vreg_l
,
629 .num_vregs
= ARRAY_SIZE(msm8996_phy_vreg_l
),
630 .regs
= pciephy_regs_layout
,
632 .start_ctrl
= PCS_START
| PLL_READY_GATE_EN
,
633 .pwrdn_ctrl
= SW_PWRDN
| REFCLK_DRV_DSBL
,
634 .mask_com_pcs_ready
= PCS_READY
,
636 .has_phy_com_ctrl
= true,
637 .has_lane_rst
= true,
638 .has_pwrdn_delay
= true,
639 .pwrdn_delay_min
= POWER_DOWN_DELAY_US_MIN
,
640 .pwrdn_delay_max
= POWER_DOWN_DELAY_US_MAX
,
643 static const struct qmp_phy_cfg msm8996_usb3phy_cfg
= {
644 .type
= PHY_TYPE_USB3
,
647 .serdes_tbl
= msm8996_usb3_serdes_tbl
,
648 .serdes_tbl_num
= ARRAY_SIZE(msm8996_usb3_serdes_tbl
),
649 .tx_tbl
= msm8996_usb3_tx_tbl
,
650 .tx_tbl_num
= ARRAY_SIZE(msm8996_usb3_tx_tbl
),
651 .rx_tbl
= msm8996_usb3_rx_tbl
,
652 .rx_tbl_num
= ARRAY_SIZE(msm8996_usb3_rx_tbl
),
653 .pcs_tbl
= msm8996_usb3_pcs_tbl
,
654 .pcs_tbl_num
= ARRAY_SIZE(msm8996_usb3_pcs_tbl
),
655 .clk_list
= msm8996_phy_clk_l
,
656 .num_clks
= ARRAY_SIZE(msm8996_phy_clk_l
),
657 .reset_list
= msm8996_usb3phy_reset_l
,
658 .num_resets
= ARRAY_SIZE(msm8996_usb3phy_reset_l
),
659 .vreg_list
= msm8996_phy_vreg_l
,
660 .num_vregs
= ARRAY_SIZE(msm8996_phy_vreg_l
),
661 .regs
= usb3phy_regs_layout
,
663 .start_ctrl
= SERDES_START
| PCS_START
,
664 .pwrdn_ctrl
= SW_PWRDN
,
665 .mask_pcs_ready
= PHYSTATUS
,
669 static const char * const ipq8074_pciephy_reset_l
[] = {
673 static const struct qmp_phy_cfg ipq8074_pciephy_cfg
= {
674 .type
= PHY_TYPE_PCIE
,
677 .serdes_tbl
= ipq8074_pcie_serdes_tbl
,
678 .serdes_tbl_num
= ARRAY_SIZE(ipq8074_pcie_serdes_tbl
),
679 .tx_tbl
= ipq8074_pcie_tx_tbl
,
680 .tx_tbl_num
= ARRAY_SIZE(ipq8074_pcie_tx_tbl
),
681 .rx_tbl
= ipq8074_pcie_rx_tbl
,
682 .rx_tbl_num
= ARRAY_SIZE(ipq8074_pcie_rx_tbl
),
683 .pcs_tbl
= ipq8074_pcie_pcs_tbl
,
684 .pcs_tbl_num
= ARRAY_SIZE(ipq8074_pcie_pcs_tbl
),
687 .reset_list
= ipq8074_pciephy_reset_l
,
688 .num_resets
= ARRAY_SIZE(ipq8074_pciephy_reset_l
),
691 .regs
= pciephy_regs_layout
,
693 .start_ctrl
= SERDES_START
| PCS_START
,
694 .pwrdn_ctrl
= SW_PWRDN
| REFCLK_DRV_DSBL
,
695 .mask_pcs_ready
= PHYSTATUS
,
697 .has_phy_com_ctrl
= false,
698 .has_lane_rst
= false,
699 .has_pwrdn_delay
= true,
700 .pwrdn_delay_min
= 995, /* us */
701 .pwrdn_delay_max
= 1005, /* us */
704 static void qcom_qmp_phy_configure(void __iomem
*base
,
705 const unsigned int *regs
,
706 const struct qmp_phy_init_tbl tbl
[],
710 const struct qmp_phy_init_tbl
*t
= tbl
;
715 for (i
= 0; i
< num
; i
++, t
++) {
717 writel(t
->val
, base
+ regs
[t
->offset
]);
719 writel(t
->val
, base
+ t
->offset
);
723 static int qcom_qmp_phy_poweron(struct phy
*phy
)
725 struct qmp_phy
*qphy
= phy_get_drvdata(phy
);
726 struct qcom_qmp
*qmp
= qphy
->qmp
;
727 int num
= qmp
->cfg
->num_vregs
;
730 dev_vdbg(&phy
->dev
, "Powering on QMP phy\n");
732 /* turn on regulator supplies */
733 ret
= regulator_bulk_enable(num
, qmp
->vregs
);
735 dev_err(qmp
->dev
, "failed to enable regulators, err=%d\n", ret
);
739 ret
= clk_prepare_enable(qphy
->pipe_clk
);
741 dev_err(qmp
->dev
, "pipe_clk enable failed, err=%d\n", ret
);
742 regulator_bulk_disable(num
, qmp
->vregs
);
749 static int qcom_qmp_phy_poweroff(struct phy
*phy
)
751 struct qmp_phy
*qphy
= phy_get_drvdata(phy
);
752 struct qcom_qmp
*qmp
= qphy
->qmp
;
754 clk_disable_unprepare(qphy
->pipe_clk
);
756 regulator_bulk_disable(qmp
->cfg
->num_vregs
, qmp
->vregs
);
761 static int qcom_qmp_phy_com_init(struct qcom_qmp
*qmp
)
763 const struct qmp_phy_cfg
*cfg
= qmp
->cfg
;
764 void __iomem
*serdes
= qmp
->serdes
;
767 mutex_lock(&qmp
->phy_mutex
);
768 if (qmp
->init_count
++) {
769 mutex_unlock(&qmp
->phy_mutex
);
773 for (i
= 0; i
< cfg
->num_resets
; i
++) {
774 ret
= reset_control_deassert(qmp
->resets
[i
]);
776 dev_err(qmp
->dev
, "%s reset deassert failed\n",
777 qmp
->cfg
->reset_list
[i
]);
782 if (cfg
->has_phy_com_ctrl
)
783 qphy_setbits(serdes
, cfg
->regs
[QPHY_COM_POWER_DOWN_CONTROL
],
786 /* Serdes configuration */
787 qcom_qmp_phy_configure(serdes
, cfg
->regs
, cfg
->serdes_tbl
,
788 cfg
->serdes_tbl_num
);
790 if (cfg
->has_phy_com_ctrl
) {
791 void __iomem
*status
;
792 unsigned int mask
, val
;
794 qphy_clrbits(serdes
, cfg
->regs
[QPHY_COM_SW_RESET
], SW_RESET
);
795 qphy_setbits(serdes
, cfg
->regs
[QPHY_COM_START_CONTROL
],
796 SERDES_START
| PCS_START
);
798 status
= serdes
+ cfg
->regs
[QPHY_COM_PCS_READY_STATUS
];
799 mask
= cfg
->mask_com_pcs_ready
;
801 ret
= readl_poll_timeout(status
, val
, (val
& mask
), 10,
802 PHY_INIT_COMPLETE_TIMEOUT
);
805 "phy common block init timed-out\n");
810 mutex_unlock(&qmp
->phy_mutex
);
816 reset_control_assert(qmp
->resets
[i
]);
817 mutex_unlock(&qmp
->phy_mutex
);
822 static int qcom_qmp_phy_com_exit(struct qcom_qmp
*qmp
)
824 const struct qmp_phy_cfg
*cfg
= qmp
->cfg
;
825 void __iomem
*serdes
= qmp
->serdes
;
826 int i
= cfg
->num_resets
;
828 mutex_lock(&qmp
->phy_mutex
);
829 if (--qmp
->init_count
) {
830 mutex_unlock(&qmp
->phy_mutex
);
834 if (cfg
->has_phy_com_ctrl
) {
835 qphy_setbits(serdes
, cfg
->regs
[QPHY_COM_START_CONTROL
],
836 SERDES_START
| PCS_START
);
837 qphy_clrbits(serdes
, cfg
->regs
[QPHY_COM_SW_RESET
],
839 qphy_setbits(serdes
, cfg
->regs
[QPHY_COM_POWER_DOWN_CONTROL
],
844 reset_control_assert(qmp
->resets
[i
]);
846 mutex_unlock(&qmp
->phy_mutex
);
851 /* PHY Initialization */
852 static int qcom_qmp_phy_init(struct phy
*phy
)
854 struct qmp_phy
*qphy
= phy_get_drvdata(phy
);
855 struct qcom_qmp
*qmp
= qphy
->qmp
;
856 const struct qmp_phy_cfg
*cfg
= qmp
->cfg
;
857 void __iomem
*tx
= qphy
->tx
;
858 void __iomem
*rx
= qphy
->rx
;
859 void __iomem
*pcs
= qphy
->pcs
;
860 void __iomem
*status
;
861 unsigned int mask
, val
;
864 dev_vdbg(qmp
->dev
, "Initializing QMP phy\n");
866 for (i
= 0; i
< qmp
->cfg
->num_clks
; i
++) {
867 ret
= clk_prepare_enable(qmp
->clks
[i
]);
869 dev_err(qmp
->dev
, "failed to enable %s clk, err=%d\n",
870 qmp
->cfg
->clk_list
[i
], ret
);
875 ret
= qcom_qmp_phy_com_init(qmp
);
879 if (cfg
->has_lane_rst
) {
880 ret
= reset_control_deassert(qphy
->lane_rst
);
882 dev_err(qmp
->dev
, "lane%d reset deassert failed\n",
888 /* Tx, Rx, and PCS configurations */
889 qcom_qmp_phy_configure(tx
, cfg
->regs
, cfg
->tx_tbl
, cfg
->tx_tbl_num
);
890 qcom_qmp_phy_configure(rx
, cfg
->regs
, cfg
->rx_tbl
, cfg
->rx_tbl_num
);
891 qcom_qmp_phy_configure(pcs
, cfg
->regs
, cfg
->pcs_tbl
, cfg
->pcs_tbl_num
);
894 * Pull out PHY from POWER DOWN state.
895 * This is active low enable signal to power-down PHY.
897 qphy_setbits(pcs
, QPHY_POWER_DOWN_CONTROL
, cfg
->pwrdn_ctrl
);
899 if (cfg
->has_pwrdn_delay
)
900 usleep_range(cfg
->pwrdn_delay_min
, cfg
->pwrdn_delay_max
);
902 /* start SerDes and Phy-Coding-Sublayer */
903 qphy_setbits(pcs
, cfg
->regs
[QPHY_START_CTRL
], cfg
->start_ctrl
);
905 /* Pull PHY out of reset state */
906 qphy_clrbits(pcs
, cfg
->regs
[QPHY_SW_RESET
], SW_RESET
);
908 status
= pcs
+ cfg
->regs
[QPHY_PCS_READY_STATUS
];
909 mask
= cfg
->mask_pcs_ready
;
911 ret
= readl_poll_timeout(status
, val
, !(val
& mask
), 1,
912 PHY_INIT_COMPLETE_TIMEOUT
);
914 dev_err(qmp
->dev
, "phy initialization timed-out\n");
921 if (cfg
->has_lane_rst
)
922 reset_control_assert(qphy
->lane_rst
);
924 qcom_qmp_phy_com_exit(qmp
);
927 clk_disable_unprepare(qmp
->clks
[i
]);
932 static int qcom_qmp_phy_exit(struct phy
*phy
)
934 struct qmp_phy
*qphy
= phy_get_drvdata(phy
);
935 struct qcom_qmp
*qmp
= qphy
->qmp
;
936 const struct qmp_phy_cfg
*cfg
= qmp
->cfg
;
937 int i
= cfg
->num_clks
;
940 qphy_setbits(qphy
->pcs
, cfg
->regs
[QPHY_SW_RESET
], SW_RESET
);
942 /* stop SerDes and Phy-Coding-Sublayer */
943 qphy_clrbits(qphy
->pcs
, cfg
->regs
[QPHY_START_CTRL
], cfg
->start_ctrl
);
945 /* Put PHY into POWER DOWN state: active low */
946 qphy_clrbits(qphy
->pcs
, QPHY_POWER_DOWN_CONTROL
, cfg
->pwrdn_ctrl
);
948 if (cfg
->has_lane_rst
)
949 reset_control_assert(qphy
->lane_rst
);
951 qcom_qmp_phy_com_exit(qmp
);
954 clk_disable_unprepare(qmp
->clks
[i
]);
959 static int qcom_qmp_phy_vreg_init(struct device
*dev
)
961 struct qcom_qmp
*qmp
= dev_get_drvdata(dev
);
962 int num
= qmp
->cfg
->num_vregs
;
965 qmp
->vregs
= devm_kcalloc(dev
, num
, sizeof(*qmp
->vregs
), GFP_KERNEL
);
969 for (i
= 0; i
< num
; i
++)
970 qmp
->vregs
[i
].supply
= qmp
->cfg
->vreg_list
[i
];
972 return devm_regulator_bulk_get(dev
, num
, qmp
->vregs
);
975 static int qcom_qmp_phy_reset_init(struct device
*dev
)
977 struct qcom_qmp
*qmp
= dev_get_drvdata(dev
);
980 qmp
->resets
= devm_kcalloc(dev
, qmp
->cfg
->num_resets
,
981 sizeof(*qmp
->resets
), GFP_KERNEL
);
985 for (i
= 0; i
< qmp
->cfg
->num_resets
; i
++) {
986 struct reset_control
*rst
;
987 const char *name
= qmp
->cfg
->reset_list
[i
];
989 rst
= devm_reset_control_get(dev
, name
);
991 dev_err(dev
, "failed to get %s reset\n", name
);
994 qmp
->resets
[i
] = rst
;
1000 static int qcom_qmp_phy_clk_init(struct device
*dev
)
1002 struct qcom_qmp
*qmp
= dev_get_drvdata(dev
);
1005 qmp
->clks
= devm_kcalloc(dev
, qmp
->cfg
->num_clks
,
1006 sizeof(*qmp
->clks
), GFP_KERNEL
);
1010 for (i
= 0; i
< qmp
->cfg
->num_clks
; i
++) {
1012 const char *name
= qmp
->cfg
->clk_list
[i
];
1014 _clk
= devm_clk_get(dev
, name
);
1016 ret
= PTR_ERR(_clk
);
1017 if (ret
!= -EPROBE_DEFER
)
1018 dev_err(dev
, "failed to get %s clk, %d\n",
1022 qmp
->clks
[i
] = _clk
;
1029 * Register a fixed rate pipe clock.
1031 * The <s>_pipe_clksrc generated by PHY goes to the GCC that gate
1032 * controls it. The <s>_pipe_clk coming out of the GCC is requested
1033 * by the PHY driver for its operations.
1034 * We register the <s>_pipe_clksrc here. The gcc driver takes care
1035 * of assigning this <s>_pipe_clksrc as parent to <s>_pipe_clk.
1036 * Below picture shows this relationship.
1039 * | PHY block |<<---------------------------------------+
1041 * | +-------+ | +-----+ |
1042 * I/P---^-->| PLL |---^--->pipe_clksrc--->| GCC |--->pipe_clk---+
1043 * clk | +-------+ | +-----+
1046 static int phy_pipe_clk_register(struct qcom_qmp
*qmp
, struct device_node
*np
)
1048 struct clk_fixed_rate
*fixed
;
1049 struct clk_init_data init
= { };
1052 if ((qmp
->cfg
->type
!= PHY_TYPE_USB3
) &&
1053 (qmp
->cfg
->type
!= PHY_TYPE_PCIE
)) {
1054 /* not all phys register pipe clocks, so return success */
1058 ret
= of_property_read_string(np
, "clock-output-names", &init
.name
);
1060 dev_err(qmp
->dev
, "%s: No clock-output-names\n", np
->name
);
1064 fixed
= devm_kzalloc(qmp
->dev
, sizeof(*fixed
), GFP_KERNEL
);
1068 init
.ops
= &clk_fixed_rate_ops
;
1070 /* controllers using QMP phys use 125MHz pipe clock interface */
1071 fixed
->fixed_rate
= 125000000;
1072 fixed
->hw
.init
= &init
;
1074 return devm_clk_hw_register(qmp
->dev
, &fixed
->hw
);
1077 static const struct phy_ops qcom_qmp_phy_gen_ops
= {
1078 .init
= qcom_qmp_phy_init
,
1079 .exit
= qcom_qmp_phy_exit
,
1080 .power_on
= qcom_qmp_phy_poweron
,
1081 .power_off
= qcom_qmp_phy_poweroff
,
1082 .owner
= THIS_MODULE
,
1086 int qcom_qmp_phy_create(struct device
*dev
, struct device_node
*np
, int id
)
1088 struct qcom_qmp
*qmp
= dev_get_drvdata(dev
);
1089 struct phy
*generic_phy
;
1090 struct qmp_phy
*qphy
;
1091 char prop_name
[MAX_PROP_NAME
];
1094 qphy
= devm_kzalloc(dev
, sizeof(*qphy
), GFP_KERNEL
);
1099 * Get memory resources for each phy lane:
1100 * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
1102 qphy
->tx
= of_iomap(np
, 0);
1106 qphy
->rx
= of_iomap(np
, 1);
1110 qphy
->pcs
= of_iomap(np
, 2);
1115 * Get PHY's Pipe clock, if any. USB3 and PCIe are PIPE3
1116 * based phys, so they essentially have pipe clock. So,
1117 * we return error in case phy is USB3 or PIPE type.
1118 * Otherwise, we initialize pipe clock to NULL for
1119 * all phys that don't need this.
1121 snprintf(prop_name
, sizeof(prop_name
), "pipe%d", id
);
1122 qphy
->pipe_clk
= of_clk_get_by_name(np
, prop_name
);
1123 if (IS_ERR(qphy
->pipe_clk
)) {
1124 if (qmp
->cfg
->type
== PHY_TYPE_PCIE
||
1125 qmp
->cfg
->type
== PHY_TYPE_USB3
) {
1126 ret
= PTR_ERR(qphy
->pipe_clk
);
1127 if (ret
!= -EPROBE_DEFER
)
1129 "failed to get lane%d pipe_clk, %d\n",
1133 qphy
->pipe_clk
= NULL
;
1136 /* Get lane reset, if any */
1137 if (qmp
->cfg
->has_lane_rst
) {
1138 snprintf(prop_name
, sizeof(prop_name
), "lane%d", id
);
1139 qphy
->lane_rst
= of_reset_control_get(np
, prop_name
);
1140 if (IS_ERR(qphy
->lane_rst
)) {
1141 dev_err(dev
, "failed to get lane%d reset\n", id
);
1142 return PTR_ERR(qphy
->lane_rst
);
1146 generic_phy
= devm_phy_create(dev
, np
, &qcom_qmp_phy_gen_ops
);
1147 if (IS_ERR(generic_phy
)) {
1148 ret
= PTR_ERR(generic_phy
);
1149 dev_err(dev
, "failed to create qphy %d\n", ret
);
1153 qphy
->phy
= generic_phy
;
1156 qmp
->phys
[id
] = qphy
;
1157 phy_set_drvdata(generic_phy
, qphy
);
1162 static const struct of_device_id qcom_qmp_phy_of_match_table
[] = {
1164 .compatible
= "qcom,msm8996-qmp-pcie-phy",
1165 .data
= &msm8996_pciephy_cfg
,
1167 .compatible
= "qcom,msm8996-qmp-usb3-phy",
1168 .data
= &msm8996_usb3phy_cfg
,
1170 .compatible
= "qcom,ipq8074-qmp-pcie-phy",
1171 .data
= &ipq8074_pciephy_cfg
,
1175 MODULE_DEVICE_TABLE(of
, qcom_qmp_phy_of_match_table
);
1177 static int qcom_qmp_phy_probe(struct platform_device
*pdev
)
1179 struct qcom_qmp
*qmp
;
1180 struct device
*dev
= &pdev
->dev
;
1181 struct resource
*res
;
1182 struct device_node
*child
;
1183 struct phy_provider
*phy_provider
;
1188 qmp
= devm_kzalloc(dev
, sizeof(*qmp
), GFP_KERNEL
);
1193 dev_set_drvdata(dev
, qmp
);
1195 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
1196 base
= devm_ioremap_resource(dev
, res
);
1198 return PTR_ERR(base
);
1200 /* per PHY serdes; usually located at base address */
1203 mutex_init(&qmp
->phy_mutex
);
1205 /* Get the specific init parameters of QMP phy */
1206 qmp
->cfg
= of_device_get_match_data(dev
);
1208 ret
= qcom_qmp_phy_clk_init(dev
);
1212 ret
= qcom_qmp_phy_reset_init(dev
);
1216 ret
= qcom_qmp_phy_vreg_init(dev
);
1218 dev_err(dev
, "failed to get regulator supplies\n");
1222 num
= of_get_available_child_count(dev
->of_node
);
1223 /* do we have a rogue child node ? */
1224 if (num
> qmp
->cfg
->nlanes
)
1227 qmp
->phys
= devm_kcalloc(dev
, num
, sizeof(*qmp
->phys
), GFP_KERNEL
);
1232 for_each_available_child_of_node(dev
->of_node
, child
) {
1233 /* Create per-lane phy */
1234 ret
= qcom_qmp_phy_create(dev
, child
, id
);
1236 dev_err(dev
, "failed to create lane%d phy, %d\n",
1242 * Register the pipe clock provided by phy.
1243 * See function description to see details of this pipe clock.
1245 ret
= phy_pipe_clk_register(qmp
, child
);
1248 "failed to register pipe clock source\n");
1254 phy_provider
= devm_of_phy_provider_register(dev
, of_phy_simple_xlate
);
1255 if (!IS_ERR(phy_provider
))
1256 dev_info(dev
, "Registered Qcom-QMP phy\n");
1258 return PTR_ERR_OR_ZERO(phy_provider
);
1261 static struct platform_driver qcom_qmp_phy_driver
= {
1262 .probe
= qcom_qmp_phy_probe
,
1264 .name
= "qcom-qmp-phy",
1265 .of_match_table
= qcom_qmp_phy_of_match_table
,
1269 module_platform_driver(qcom_qmp_phy_driver
);
1271 MODULE_AUTHOR("Vivek Gautam <vivek.gautam@codeaurora.org>");
1272 MODULE_DESCRIPTION("Qualcomm QMP PHY driver");
1273 MODULE_LICENSE("GPL v2");