1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * phy-brcm-usb-init.c - Broadcom USB Phy chip specific init functions |
4 | * |
5 | * Copyright (C) 2014-2017 Broadcom |
6 | */ |
7 | |
8 | /* |
9 | * This module contains USB PHY initialization for power up and S3 resume |
10 | */ |
11 | |
12 | #include <linux/delay.h> |
13 | #include <linux/io.h> |
14 | |
15 | #include <linux/soc/brcmstb/brcmstb.h> |
16 | #include "phy-brcm-usb-init.h" |
17 | |
18 | #define PHY_PORTS 2 |
19 | #define PHY_PORT_SELECT_0 0 |
20 | #define PHY_PORT_SELECT_1 0x1000 |
21 | |
22 | /* Register definitions for the USB CTRL block */ |
23 | #define USB_CTRL_SETUP 0x00 |
24 | #define USB_CTRL_SETUP_BABO_MASK BIT(0) |
25 | #define USB_CTRL_SETUP_FNHW_MASK BIT(1) |
26 | #define USB_CTRL_SETUP_FNBO_MASK BIT(2) |
27 | #define USB_CTRL_SETUP_WABO_MASK BIT(3) |
28 | #define USB_CTRL_SETUP_IOC_MASK BIT(4) |
29 | #define USB_CTRL_SETUP_IPP_MASK BIT(5) |
30 | #define USB_CTRL_SETUP_SCB_CLIENT_SWAP_MASK BIT(13) /* option */ |
31 | #define USB_CTRL_SETUP_SCB1_EN_MASK BIT(14) /* option */ |
32 | #define USB_CTRL_SETUP_SCB2_EN_MASK BIT(15) /* option */ |
33 | #define USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK BIT(17) /* option */ |
34 | #define USB_CTRL_SETUP_SS_EHCI64BIT_EN_VAR_MASK BIT(16) /* option */ |
35 | #define USB_CTRL_SETUP_STRAP_IPP_SEL_MASK BIT(25) /* option */ |
36 | #define USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK BIT(26) /* option */ |
37 | #define USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK BIT(27) /* opt */ |
38 | #define USB_CTRL_SETUP_OC_DISABLE_PORT0_MASK BIT(28) |
39 | #define USB_CTRL_SETUP_OC_DISABLE_PORT1_MASK BIT(29) |
40 | #define USB_CTRL_SETUP_OC_DISABLE_MASK GENMASK(29, 28) /* option */ |
41 | #define USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK BIT(30) |
42 | #define USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK BIT(31) |
43 | #define USB_CTRL_SETUP_OC3_DISABLE_MASK GENMASK(31, 30) /* option */ |
44 | #define USB_CTRL_PLL_CTL 0x04 |
45 | #define USB_CTRL_PLL_CTL_PLL_SUSPEND_EN_MASK BIT(27) |
46 | #define USB_CTRL_PLL_CTL_PLL_RESETB_MASK BIT(30) |
47 | #define USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK BIT(31) /* option */ |
48 | #define USB_CTRL_EBRIDGE 0x0c |
49 | #define USB_CTRL_EBRIDGE_EBR_SCB_SIZE_MASK GENMASK(11, 7) /* option */ |
50 | #define USB_CTRL_EBRIDGE_ESTOP_SCB_REQ_MASK BIT(17) /* option */ |
51 | #define USB_CTRL_OBRIDGE 0x10 |
52 | #define USB_CTRL_OBRIDGE_LS_KEEP_ALIVE_MASK BIT(27) |
53 | #define USB_CTRL_MDIO 0x14 |
54 | #define USB_CTRL_MDIO2 0x18 |
55 | #define USB_CTRL_UTMI_CTL_1 0x2c |
56 | #define USB_CTRL_UTMI_CTL_1_POWER_UP_FSM_EN_MASK BIT(11) |
57 | #define USB_CTRL_UTMI_CTL_1_POWER_UP_FSM_EN_P1_MASK BIT(27) |
58 | #define USB_CTRL_USB_PM 0x34 |
59 | #define USB_CTRL_USB_PM_RMTWKUP_EN_MASK BIT(0) |
60 | #define USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK GENMASK(21, 20) /* option */ |
61 | #define USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK BIT(22) /* option */ |
62 | #define USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK BIT(23) /* option */ |
63 | #define USB_CTRL_USB_PM_USB20_HC_RESETB_MASK GENMASK(29, 28) /* option */ |
64 | #define USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK BIT(30) /* option */ |
65 | #define USB_CTRL_USB_PM_SOFT_RESET_MASK BIT(30) /* option */ |
66 | #define USB_CTRL_USB_PM_USB_PWRDN_MASK BIT(31) /* option */ |
67 | #define USB_CTRL_USB_PM_STATUS 0x38 |
68 | #define USB_CTRL_USB30_CTL1 0x60 |
69 | #define USB_CTRL_USB30_CTL1_PHY3_PLL_SEQ_START_MASK BIT(4) |
70 | #define USB_CTRL_USB30_CTL1_PHY3_RESETB_MASK BIT(16) |
71 | #define USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK BIT(17) /* option */ |
72 | #define USB_CTRL_USB30_CTL1_USB3_IOC_MASK BIT(28) /* option */ |
73 | #define USB_CTRL_USB30_CTL1_USB3_IPP_MASK BIT(29) /* option */ |
74 | #define USB_CTRL_USB30_PCTL 0x70 |
75 | #define USB_CTRL_USB30_PCTL_PHY3_SOFT_RESETB_MASK BIT(1) |
76 | #define USB_CTRL_USB30_PCTL_PHY3_IDDQ_OVERRIDE_MASK BIT(15) |
77 | #define USB_CTRL_USB30_PCTL_PHY3_SOFT_RESETB_P1_MASK BIT(17) |
78 | #define USB_CTRL_USB_DEVICE_CTL1 0x90 |
79 | #define USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK GENMASK(1, 0) /* option */ |
80 | |
81 | /* Register definitions for the XHCI EC block */ |
82 | #define USB_XHCI_EC_IRAADR 0x658 |
83 | #define USB_XHCI_EC_IRADAT 0x65c |
84 | |
85 | enum brcm_family_type { |
86 | BRCM_FAMILY_3390A0, |
87 | BRCM_FAMILY_4908, |
88 | BRCM_FAMILY_7250B0, |
89 | BRCM_FAMILY_7271A0, |
90 | BRCM_FAMILY_7364A0, |
91 | BRCM_FAMILY_7366C0, |
92 | BRCM_FAMILY_74371A0, |
93 | BRCM_FAMILY_7439B0, |
94 | BRCM_FAMILY_7445D0, |
95 | BRCM_FAMILY_7260A0, |
96 | BRCM_FAMILY_7278A0, |
97 | BRCM_FAMILY_COUNT, |
98 | }; |
99 | |
100 | #define USB_BRCM_FAMILY(chip) \ |
101 | [BRCM_FAMILY_##chip] = __stringify(chip) |
102 | |
103 | static const char *family_names[BRCM_FAMILY_COUNT] = { |
104 | USB_BRCM_FAMILY(3390A0), |
105 | USB_BRCM_FAMILY(4908), |
106 | USB_BRCM_FAMILY(7250B0), |
107 | USB_BRCM_FAMILY(7271A0), |
108 | USB_BRCM_FAMILY(7364A0), |
109 | USB_BRCM_FAMILY(7366C0), |
110 | USB_BRCM_FAMILY(74371A0), |
111 | USB_BRCM_FAMILY(7439B0), |
112 | USB_BRCM_FAMILY(7445D0), |
113 | USB_BRCM_FAMILY(7260A0), |
114 | USB_BRCM_FAMILY(7278A0), |
115 | }; |
116 | |
117 | enum { |
118 | USB_CTRL_SETUP_SCB1_EN_SELECTOR, |
119 | USB_CTRL_SETUP_SCB2_EN_SELECTOR, |
120 | USB_CTRL_SETUP_SS_EHCI64BIT_EN_SELECTOR, |
121 | USB_CTRL_SETUP_STRAP_IPP_SEL_SELECTOR, |
122 | USB_CTRL_SETUP_OC3_DISABLE_PORT0_SELECTOR, |
123 | USB_CTRL_SETUP_OC3_DISABLE_PORT1_SELECTOR, |
124 | USB_CTRL_SETUP_OC3_DISABLE_SELECTOR, |
125 | USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_SELECTOR, |
126 | USB_CTRL_USB_PM_BDC_SOFT_RESETB_SELECTOR, |
127 | USB_CTRL_USB_PM_XHC_SOFT_RESETB_SELECTOR, |
128 | USB_CTRL_USB_PM_USB_PWRDN_SELECTOR, |
129 | USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_SELECTOR, |
130 | USB_CTRL_USB30_CTL1_USB3_IOC_SELECTOR, |
131 | USB_CTRL_USB30_CTL1_USB3_IPP_SELECTOR, |
132 | USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_SELECTOR, |
133 | USB_CTRL_USB_PM_SOFT_RESET_SELECTOR, |
134 | USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_SELECTOR, |
135 | USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_SELECTOR, |
136 | USB_CTRL_USB_PM_USB20_HC_RESETB_SELECTOR, |
137 | USB_CTRL_SETUP_ENDIAN_SELECTOR, |
138 | USB_CTRL_SELECTOR_COUNT, |
139 | }; |
140 | |
141 | #define USB_CTRL_MASK_FAMILY(params, reg, field) \ |
142 | (params->usb_reg_bits_map[USB_CTRL_##reg##_##field##_SELECTOR]) |
143 | |
144 | #define USB_CTRL_SET_FAMILY(params, reg, field) \ |
145 | usb_ctrl_set_family(params, USB_CTRL_##reg, \ |
146 | USB_CTRL_##reg##_##field##_SELECTOR) |
147 | #define USB_CTRL_UNSET_FAMILY(params, reg, field) \ |
148 | usb_ctrl_unset_family(params, USB_CTRL_##reg, \ |
149 | USB_CTRL_##reg##_##field##_SELECTOR) |
150 | |
151 | #define MDIO_USB2 0 |
152 | #define MDIO_USB3 BIT(31) |
153 | |
154 | #define USB_CTRL_SETUP_ENDIAN_BITS ( \ |
155 | USB_CTRL_MASK(SETUP, BABO) | \ |
156 | USB_CTRL_MASK(SETUP, FNHW) | \ |
157 | USB_CTRL_MASK(SETUP, FNBO) | \ |
158 | USB_CTRL_MASK(SETUP, WABO)) |
159 | |
160 | #ifdef __LITTLE_ENDIAN |
161 | #define ENDIAN_SETTINGS ( \ |
162 | USB_CTRL_MASK(SETUP, BABO) | \ |
163 | USB_CTRL_MASK(SETUP, FNHW)) |
164 | #else |
165 | #define ENDIAN_SETTINGS ( \ |
166 | USB_CTRL_MASK(SETUP, FNHW) | \ |
167 | USB_CTRL_MASK(SETUP, FNBO) | \ |
168 | USB_CTRL_MASK(SETUP, WABO)) |
169 | #endif |
170 | |
171 | struct id_to_type { |
172 | u32 id; |
173 | int type; |
174 | }; |
175 | |
176 | static const struct id_to_type id_to_type_table[] = { |
177 | { 0x33900000, BRCM_FAMILY_3390A0 }, |
178 | { 0x72500010, BRCM_FAMILY_7250B0 }, |
179 | { 0x72600000, BRCM_FAMILY_7260A0 }, |
180 | { 0x72550000, BRCM_FAMILY_7260A0 }, |
181 | { 0x72680000, BRCM_FAMILY_7271A0 }, |
182 | { 0x72710000, BRCM_FAMILY_7271A0 }, |
183 | { 0x73640000, BRCM_FAMILY_7364A0 }, |
184 | { 0x73660020, BRCM_FAMILY_7366C0 }, |
185 | { 0x07437100, BRCM_FAMILY_74371A0 }, |
186 | { 0x74390010, BRCM_FAMILY_7439B0 }, |
187 | { 0x74450030, BRCM_FAMILY_7445D0 }, |
188 | { 0x72780000, BRCM_FAMILY_7278A0 }, |
189 | { 0, BRCM_FAMILY_7271A0 }, /* default */ |
190 | }; |
191 | |
192 | static const u32 |
193 | usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = { |
194 | /* 3390B0 */ |
195 | [BRCM_FAMILY_3390A0] = { |
196 | USB_CTRL_SETUP_SCB1_EN_MASK, |
197 | USB_CTRL_SETUP_SCB2_EN_MASK, |
198 | USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK, |
199 | USB_CTRL_SETUP_STRAP_IPP_SEL_MASK, |
200 | USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK, |
201 | USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK, |
202 | USB_CTRL_SETUP_OC3_DISABLE_MASK, |
203 | 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */ |
204 | 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */ |
205 | USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK, |
206 | USB_CTRL_USB_PM_USB_PWRDN_MASK, |
207 | 0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */ |
208 | 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */ |
209 | 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */ |
210 | USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK, |
211 | 0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */ |
212 | 0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */ |
213 | 0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */ |
214 | USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK, |
215 | ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */ |
216 | }, |
217 | /* 4908 */ |
218 | [BRCM_FAMILY_4908] = { |
219 | 0, /* USB_CTRL_SETUP_SCB1_EN_MASK */ |
220 | 0, /* USB_CTRL_SETUP_SCB2_EN_MASK */ |
221 | 0, /* USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK */ |
222 | 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */ |
223 | 0, /* USB_CTRL_SETUP_OC3_DISABLE_MASK */ |
224 | 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */ |
225 | 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */ |
226 | USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK, |
227 | USB_CTRL_USB_PM_USB_PWRDN_MASK, |
228 | 0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */ |
229 | 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */ |
230 | 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */ |
231 | 0, /* USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK */ |
232 | 0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */ |
233 | 0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */ |
234 | 0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */ |
235 | 0, /* USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK */ |
236 | 0, /* USB_CTRL_SETUP ENDIAN bits */ |
237 | }, |
238 | /* 7250b0 */ |
239 | [BRCM_FAMILY_7250B0] = { |
240 | USB_CTRL_SETUP_SCB1_EN_MASK, |
241 | USB_CTRL_SETUP_SCB2_EN_MASK, |
242 | USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK, |
243 | 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */ |
244 | USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK, |
245 | USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK, |
246 | USB_CTRL_SETUP_OC3_DISABLE_MASK, |
247 | USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK, |
248 | 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */ |
249 | USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK, |
250 | 0, /* USB_CTRL_USB_PM_USB_PWRDN_MASK */ |
251 | 0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */ |
252 | 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */ |
253 | 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */ |
254 | 0, /* USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK */ |
255 | 0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */ |
256 | 0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */ |
257 | 0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */ |
258 | USB_CTRL_USB_PM_USB20_HC_RESETB_MASK, |
259 | ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */ |
260 | }, |
261 | /* 7271a0 */ |
262 | [BRCM_FAMILY_7271A0] = { |
263 | 0, /* USB_CTRL_SETUP_SCB1_EN_MASK */ |
264 | 0, /* USB_CTRL_SETUP_SCB2_EN_MASK */ |
265 | USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK, |
266 | USB_CTRL_SETUP_STRAP_IPP_SEL_MASK, |
267 | USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK, |
268 | USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK, |
269 | USB_CTRL_SETUP_OC3_DISABLE_MASK, |
270 | 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */ |
271 | USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK, |
272 | USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK, |
273 | USB_CTRL_USB_PM_USB_PWRDN_MASK, |
274 | 0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */ |
275 | 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */ |
276 | 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */ |
277 | USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK, |
278 | USB_CTRL_USB_PM_SOFT_RESET_MASK, |
279 | USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK, |
280 | USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK, |
281 | USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK, |
282 | ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */ |
283 | }, |
284 | /* 7364a0 */ |
285 | [BRCM_FAMILY_7364A0] = { |
286 | USB_CTRL_SETUP_SCB1_EN_MASK, |
287 | USB_CTRL_SETUP_SCB2_EN_MASK, |
288 | USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK, |
289 | 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */ |
290 | USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK, |
291 | USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK, |
292 | USB_CTRL_SETUP_OC3_DISABLE_MASK, |
293 | USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK, |
294 | 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */ |
295 | USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK, |
296 | 0, /* USB_CTRL_USB_PM_USB_PWRDN_MASK */ |
297 | 0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */ |
298 | 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */ |
299 | 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */ |
300 | 0, /* USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK */ |
301 | 0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */ |
302 | 0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */ |
303 | 0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */ |
304 | USB_CTRL_USB_PM_USB20_HC_RESETB_MASK, |
305 | ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */ |
306 | }, |
307 | /* 7366c0 */ |
308 | [BRCM_FAMILY_7366C0] = { |
309 | USB_CTRL_SETUP_SCB1_EN_MASK, |
310 | USB_CTRL_SETUP_SCB2_EN_MASK, |
311 | USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK, |
312 | 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */ |
313 | USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK, |
314 | USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK, |
315 | USB_CTRL_SETUP_OC3_DISABLE_MASK, |
316 | 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */ |
317 | 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */ |
318 | USB_CTRL_USB_PM_XHC_SOFT_RESETB_VAR_MASK, |
319 | USB_CTRL_USB_PM_USB_PWRDN_MASK, |
320 | 0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */ |
321 | 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */ |
322 | 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */ |
323 | 0, /* USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK */ |
324 | 0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */ |
325 | 0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */ |
326 | 0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */ |
327 | USB_CTRL_USB_PM_USB20_HC_RESETB_MASK, |
328 | ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */ |
329 | }, |
330 | /* 74371A0 */ |
331 | [BRCM_FAMILY_74371A0] = { |
332 | USB_CTRL_SETUP_SCB1_EN_MASK, |
333 | USB_CTRL_SETUP_SCB2_EN_MASK, |
334 | USB_CTRL_SETUP_SS_EHCI64BIT_EN_VAR_MASK, |
335 | 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */ |
336 | 0, /* USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK */ |
337 | 0, /* USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK */ |
338 | 0, /* USB_CTRL_SETUP_OC3_DISABLE_MASK */ |
339 | USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK, |
340 | 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */ |
341 | 0, /* USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK */ |
342 | 0, /* USB_CTRL_USB_PM_USB_PWRDN_MASK */ |
343 | USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK, |
344 | USB_CTRL_USB30_CTL1_USB3_IOC_MASK, |
345 | USB_CTRL_USB30_CTL1_USB3_IPP_MASK, |
346 | 0, /* USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK */ |
347 | 0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */ |
348 | 0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */ |
349 | 0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */ |
350 | 0, /* USB_CTRL_USB_PM_USB20_HC_RESETB_MASK */ |
351 | ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */ |
352 | }, |
353 | /* 7439B0 */ |
354 | [BRCM_FAMILY_7439B0] = { |
355 | USB_CTRL_SETUP_SCB1_EN_MASK, |
356 | USB_CTRL_SETUP_SCB2_EN_MASK, |
357 | USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK, |
358 | USB_CTRL_SETUP_STRAP_IPP_SEL_MASK, |
359 | USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK, |
360 | USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK, |
361 | USB_CTRL_SETUP_OC3_DISABLE_MASK, |
362 | 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */ |
363 | USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK, |
364 | USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK, |
365 | USB_CTRL_USB_PM_USB_PWRDN_MASK, |
366 | 0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */ |
367 | 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */ |
368 | 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */ |
369 | USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK, |
370 | 0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */ |
371 | 0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */ |
372 | 0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */ |
373 | USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK, |
374 | ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */ |
375 | }, |
376 | /* 7445d0 */ |
377 | [BRCM_FAMILY_7445D0] = { |
378 | USB_CTRL_SETUP_SCB1_EN_MASK, |
379 | USB_CTRL_SETUP_SCB2_EN_MASK, |
380 | USB_CTRL_SETUP_SS_EHCI64BIT_EN_VAR_MASK, |
381 | 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */ |
382 | USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK, |
383 | USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK, |
384 | USB_CTRL_SETUP_OC3_DISABLE_MASK, |
385 | USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK, |
386 | 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */ |
387 | 0, /* USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK */ |
388 | 0, /* USB_CTRL_USB_PM_USB_PWRDN_MASK */ |
389 | USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK, |
390 | 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */ |
391 | 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */ |
392 | 0, /* USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK */ |
393 | 0, /* USB_CTRL_USB_PM_SOFT_RESET_MASK */ |
394 | 0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */ |
395 | 0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */ |
396 | USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK, |
397 | ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */ |
398 | }, |
399 | /* 7260a0 */ |
400 | [BRCM_FAMILY_7260A0] = { |
401 | 0, /* USB_CTRL_SETUP_SCB1_EN_MASK */ |
402 | 0, /* USB_CTRL_SETUP_SCB2_EN_MASK */ |
403 | USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK, |
404 | USB_CTRL_SETUP_STRAP_IPP_SEL_MASK, |
405 | USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK, |
406 | USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK, |
407 | USB_CTRL_SETUP_OC3_DISABLE_MASK, |
408 | 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */ |
409 | USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK, |
410 | USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK, |
411 | USB_CTRL_USB_PM_USB_PWRDN_MASK, |
412 | 0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */ |
413 | 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */ |
414 | 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */ |
415 | USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK, |
416 | USB_CTRL_USB_PM_SOFT_RESET_MASK, |
417 | USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK, |
418 | USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK, |
419 | USB_CTRL_USB_PM_USB20_HC_RESETB_VAR_MASK, |
420 | ENDIAN_SETTINGS, /* USB_CTRL_SETUP ENDIAN bits */ |
421 | }, |
422 | /* 7278a0 */ |
423 | [BRCM_FAMILY_7278A0] = { |
424 | 0, /* USB_CTRL_SETUP_SCB1_EN_MASK */ |
425 | 0, /* USB_CTRL_SETUP_SCB2_EN_MASK */ |
426 | 0, /*USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK */ |
427 | USB_CTRL_SETUP_STRAP_IPP_SEL_MASK, |
428 | USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK, |
429 | USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK, |
430 | USB_CTRL_SETUP_OC3_DISABLE_MASK, |
431 | 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */ |
432 | USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK, |
433 | USB_CTRL_USB_PM_XHC_SOFT_RESETB_MASK, |
434 | USB_CTRL_USB_PM_USB_PWRDN_MASK, |
435 | 0, /* USB_CTRL_USB30_CTL1_XHC_SOFT_RESETB_MASK */ |
436 | 0, /* USB_CTRL_USB30_CTL1_USB3_IOC_MASK */ |
437 | 0, /* USB_CTRL_USB30_CTL1_USB3_IPP_MASK */ |
438 | USB_CTRL_USB_DEVICE_CTL1_PORT_MODE_MASK, |
439 | USB_CTRL_USB_PM_SOFT_RESET_MASK, |
440 | 0, /* USB_CTRL_SETUP_CC_DRD_MODE_ENABLE_MASK */ |
441 | 0, /* USB_CTRL_SETUP_STRAP_CC_DRD_MODE_ENABLE_SEL_MASK */ |
442 | 0, /* USB_CTRL_USB_PM_USB20_HC_RESETB_MASK */ |
443 | 0, /* USB_CTRL_SETUP ENDIAN bits */ |
444 | }, |
445 | }; |
446 | |
447 | static inline |
448 | void usb_ctrl_unset_family(struct brcm_usb_init_params *params, |
449 | u32 reg_offset, u32 field) |
450 | { |
451 | u32 mask; |
452 | |
453 | mask = params->usb_reg_bits_map[field]; |
454 | brcm_usb_ctrl_unset(reg: params->regs[BRCM_REGS_CTRL] + reg_offset, mask); |
455 | }; |
456 | |
457 | static inline |
458 | void usb_ctrl_set_family(struct brcm_usb_init_params *params, |
459 | u32 reg_offset, u32 field) |
460 | { |
461 | u32 mask; |
462 | |
463 | mask = params->usb_reg_bits_map[field]; |
464 | brcm_usb_ctrl_set(reg: params->regs[BRCM_REGS_CTRL] + reg_offset, mask); |
465 | }; |
466 | |
467 | static u32 brcmusb_usb_mdio_read(void __iomem *ctrl_base, u32 reg, int mode) |
468 | { |
469 | u32 data; |
470 | |
471 | data = (reg << 16) | mode; |
472 | brcm_usb_writel(val: data, USB_CTRL_REG(ctrl_base, MDIO)); |
473 | data |= (1 << 24); |
474 | brcm_usb_writel(val: data, USB_CTRL_REG(ctrl_base, MDIO)); |
475 | data &= ~(1 << 24); |
476 | /* wait for the 60MHz parallel to serial shifter */ |
477 | usleep_range(min: 10, max: 20); |
478 | brcm_usb_writel(val: data, USB_CTRL_REG(ctrl_base, MDIO)); |
479 | /* wait for the 60MHz parallel to serial shifter */ |
480 | usleep_range(min: 10, max: 20); |
481 | |
482 | return brcm_usb_readl(USB_CTRL_REG(ctrl_base, MDIO2)) & 0xffff; |
483 | } |
484 | |
485 | static void brcmusb_usb_mdio_write(void __iomem *ctrl_base, u32 reg, |
486 | u32 val, int mode) |
487 | { |
488 | u32 data; |
489 | |
490 | data = (reg << 16) | val | mode; |
491 | brcm_usb_writel(val: data, USB_CTRL_REG(ctrl_base, MDIO)); |
492 | data |= (1 << 25); |
493 | brcm_usb_writel(val: data, USB_CTRL_REG(ctrl_base, MDIO)); |
494 | data &= ~(1 << 25); |
495 | |
496 | /* wait for the 60MHz parallel to serial shifter */ |
497 | usleep_range(min: 10, max: 20); |
498 | brcm_usb_writel(val: data, USB_CTRL_REG(ctrl_base, MDIO)); |
499 | /* wait for the 60MHz parallel to serial shifter */ |
500 | usleep_range(min: 10, max: 20); |
501 | } |
502 | |
503 | static void brcmusb_usb_phy_ldo_fix(void __iomem *ctrl_base) |
504 | { |
505 | /* first disable FSM but also leave it that way */ |
506 | /* to allow normal suspend/resume */ |
507 | USB_CTRL_UNSET(ctrl_base, UTMI_CTL_1, POWER_UP_FSM_EN); |
508 | USB_CTRL_UNSET(ctrl_base, UTMI_CTL_1, POWER_UP_FSM_EN_P1); |
509 | |
510 | /* reset USB 2.0 PLL */ |
511 | USB_CTRL_UNSET(ctrl_base, PLL_CTL, PLL_RESETB); |
512 | /* PLL reset period */ |
513 | udelay(1); |
514 | USB_CTRL_SET(ctrl_base, PLL_CTL, PLL_RESETB); |
515 | /* Give PLL enough time to lock */ |
516 | usleep_range(min: 1000, max: 2000); |
517 | } |
518 | |
519 | static void brcmusb_usb2_eye_fix(void __iomem *ctrl_base) |
520 | { |
521 | /* Increase USB 2.0 TX level to meet spec requirement */ |
522 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x1f, val: 0x80a0, MDIO_USB2); |
523 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x0a, val: 0xc6a0, MDIO_USB2); |
524 | } |
525 | |
526 | static void brcmusb_usb3_pll_fix(void __iomem *ctrl_base) |
527 | { |
528 | /* Set correct window for PLL lock detect */ |
529 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x1f, val: 0x8000, MDIO_USB3); |
530 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x07, val: 0x1503, MDIO_USB3); |
531 | } |
532 | |
533 | static void brcmusb_usb3_enable_pipe_reset(void __iomem *ctrl_base) |
534 | { |
535 | u32 val; |
536 | |
537 | /* Re-enable USB 3.0 pipe reset */ |
538 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x1f, val: 0x8000, MDIO_USB3); |
539 | val = brcmusb_usb_mdio_read(ctrl_base, reg: 0x0f, MDIO_USB3) | 0x200; |
540 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x0f, val, MDIO_USB3); |
541 | } |
542 | |
543 | static void brcmusb_usb3_enable_sigdet(void __iomem *ctrl_base) |
544 | { |
545 | u32 val, ofs; |
546 | int ii; |
547 | |
548 | ofs = 0; |
549 | for (ii = 0; ii < PHY_PORTS; ++ii) { |
550 | /* Set correct default for sigdet */ |
551 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x1f, val: (0x8080 + ofs), |
552 | MDIO_USB3); |
553 | val = brcmusb_usb_mdio_read(ctrl_base, reg: 0x05, MDIO_USB3); |
554 | val = (val & ~0x800f) | 0x800d; |
555 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x05, val, MDIO_USB3); |
556 | ofs = PHY_PORT_SELECT_1; |
557 | } |
558 | } |
559 | |
560 | static void brcmusb_usb3_enable_skip_align(void __iomem *ctrl_base) |
561 | { |
562 | u32 val, ofs; |
563 | int ii; |
564 | |
565 | ofs = 0; |
566 | for (ii = 0; ii < PHY_PORTS; ++ii) { |
567 | /* Set correct default for SKIP align */ |
568 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x1f, val: (0x8060 + ofs), |
569 | MDIO_USB3); |
570 | val = brcmusb_usb_mdio_read(ctrl_base, reg: 0x01, MDIO_USB3) | 0x200; |
571 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x01, val, MDIO_USB3); |
572 | ofs = PHY_PORT_SELECT_1; |
573 | } |
574 | } |
575 | |
576 | static void brcmusb_usb3_unfreeze_aeq(void __iomem *ctrl_base) |
577 | { |
578 | u32 val, ofs; |
579 | int ii; |
580 | |
581 | ofs = 0; |
582 | for (ii = 0; ii < PHY_PORTS; ++ii) { |
583 | /* Let EQ freeze after TSEQ */ |
584 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x1f, val: (0x80e0 + ofs), |
585 | MDIO_USB3); |
586 | val = brcmusb_usb_mdio_read(ctrl_base, reg: 0x01, MDIO_USB3); |
587 | val &= ~0x0008; |
588 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x01, val, MDIO_USB3); |
589 | ofs = PHY_PORT_SELECT_1; |
590 | } |
591 | } |
592 | |
593 | static void brcmusb_usb3_pll_54mhz(struct brcm_usb_init_params *params) |
594 | { |
595 | u32 ofs; |
596 | int ii; |
597 | void __iomem *ctrl_base = params->regs[BRCM_REGS_CTRL]; |
598 | |
599 | /* |
600 | * On newer B53 based SoC's, the reference clock for the |
601 | * 3.0 PLL has been changed from 50MHz to 54MHz so the |
602 | * PLL needs to be reprogrammed. |
603 | * See SWLINUX-4006. |
604 | * |
605 | * On the 7364C0, the reference clock for the |
606 | * 3.0 PLL has been changed from 50MHz to 54MHz to |
607 | * work around a MOCA issue. |
608 | * See SWLINUX-4169. |
609 | */ |
610 | switch (params->selected_family) { |
611 | case BRCM_FAMILY_3390A0: |
612 | case BRCM_FAMILY_4908: |
613 | case BRCM_FAMILY_7250B0: |
614 | case BRCM_FAMILY_7366C0: |
615 | case BRCM_FAMILY_74371A0: |
616 | case BRCM_FAMILY_7439B0: |
617 | case BRCM_FAMILY_7445D0: |
618 | case BRCM_FAMILY_7260A0: |
619 | return; |
620 | case BRCM_FAMILY_7364A0: |
621 | if (BRCM_REV(reg: params->family_id) < 0x20) |
622 | return; |
623 | break; |
624 | } |
625 | |
626 | /* set USB 3.0 PLL to accept 54Mhz reference clock */ |
627 | USB_CTRL_UNSET(ctrl_base, USB30_CTL1, PHY3_PLL_SEQ_START); |
628 | |
629 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x1f, val: 0x8000, MDIO_USB3); |
630 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x10, val: 0x5784, MDIO_USB3); |
631 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x11, val: 0x01d0, MDIO_USB3); |
632 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x12, val: 0x1DE8, MDIO_USB3); |
633 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x13, val: 0xAA80, MDIO_USB3); |
634 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x14, val: 0x8826, MDIO_USB3); |
635 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x15, val: 0x0044, MDIO_USB3); |
636 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x16, val: 0x8000, MDIO_USB3); |
637 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x17, val: 0x0851, MDIO_USB3); |
638 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x18, val: 0x0000, MDIO_USB3); |
639 | |
640 | /* both ports */ |
641 | ofs = 0; |
642 | for (ii = 0; ii < PHY_PORTS; ++ii) { |
643 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x1f, val: (0x8040 + ofs), |
644 | MDIO_USB3); |
645 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x03, val: 0x0090, MDIO_USB3); |
646 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x04, val: 0x0134, MDIO_USB3); |
647 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x1f, val: (0x8020 + ofs), |
648 | MDIO_USB3); |
649 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x01, val: 0x00e2, MDIO_USB3); |
650 | ofs = PHY_PORT_SELECT_1; |
651 | } |
652 | |
653 | /* restart PLL sequence */ |
654 | USB_CTRL_SET(ctrl_base, USB30_CTL1, PHY3_PLL_SEQ_START); |
655 | /* Give PLL enough time to lock */ |
656 | usleep_range(min: 1000, max: 2000); |
657 | } |
658 | |
659 | static void brcmusb_usb3_ssc_enable(void __iomem *ctrl_base) |
660 | { |
661 | u32 val; |
662 | |
663 | /* Enable USB 3.0 TX spread spectrum */ |
664 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x1f, val: 0x8040, MDIO_USB3); |
665 | val = brcmusb_usb_mdio_read(ctrl_base, reg: 0x01, MDIO_USB3) | 0xf; |
666 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x01, val, MDIO_USB3); |
667 | |
668 | /* Currently, USB 3.0 SSC is enabled via port 0 MDIO registers, |
669 | * which should have been adequate. However, due to a bug in the |
670 | * USB 3.0 PHY, it must be enabled via both ports (HWUSB3DVT-26). |
671 | */ |
672 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x1f, val: 0x9040, MDIO_USB3); |
673 | val = brcmusb_usb_mdio_read(ctrl_base, reg: 0x01, MDIO_USB3) | 0xf; |
674 | brcmusb_usb_mdio_write(ctrl_base, reg: 0x01, val, MDIO_USB3); |
675 | } |
676 | |
677 | static void brcmusb_usb3_phy_workarounds(struct brcm_usb_init_params *params) |
678 | { |
679 | void __iomem *ctrl_base = params->regs[BRCM_REGS_CTRL]; |
680 | |
681 | brcmusb_usb3_pll_fix(ctrl_base); |
682 | brcmusb_usb3_pll_54mhz(params); |
683 | brcmusb_usb3_ssc_enable(ctrl_base); |
684 | brcmusb_usb3_enable_pipe_reset(ctrl_base); |
685 | brcmusb_usb3_enable_sigdet(ctrl_base); |
686 | brcmusb_usb3_enable_skip_align(ctrl_base); |
687 | brcmusb_usb3_unfreeze_aeq(ctrl_base); |
688 | } |
689 | |
690 | static void brcmusb_memc_fix(struct brcm_usb_init_params *params) |
691 | { |
692 | u32 prid; |
693 | |
694 | if (params->selected_family != BRCM_FAMILY_7445D0) |
695 | return; |
696 | /* |
697 | * This is a workaround for HW7445-1869 where a DMA write ends up |
698 | * doing a read pre-fetch after the end of the DMA buffer. This |
699 | * causes a problem when the DMA buffer is at the end of physical |
700 | * memory, causing the pre-fetch read to access non-existent memory, |
701 | * and the chip bondout has MEMC2 disabled. When the pre-fetch read |
702 | * tries to use the disabled MEMC2, it hangs the bus. The workaround |
703 | * is to disable MEMC2 access in the usb controller which avoids |
704 | * the hang. |
705 | */ |
706 | |
707 | prid = params->product_id & 0xfffff000; |
708 | switch (prid) { |
709 | case 0x72520000: |
710 | case 0x74480000: |
711 | case 0x74490000: |
712 | case 0x07252000: |
713 | case 0x07448000: |
714 | case 0x07449000: |
715 | USB_CTRL_UNSET_FAMILY(params, SETUP, SCB2_EN); |
716 | } |
717 | } |
718 | |
719 | static void brcmusb_usb3_otp_fix(struct brcm_usb_init_params *params) |
720 | { |
721 | void __iomem *xhci_ec_base = params->regs[BRCM_REGS_XHCI_EC]; |
722 | u32 val; |
723 | |
724 | if (params->family_id != 0x74371000 || !xhci_ec_base) |
725 | return; |
726 | brcm_usb_writel(val: 0xa20c, USB_XHCI_EC_REG(xhci_ec_base, IRAADR)); |
727 | val = brcm_usb_readl(USB_XHCI_EC_REG(xhci_ec_base, IRADAT)); |
728 | |
729 | /* set cfg_pick_ss_lock */ |
730 | val |= (1 << 27); |
731 | brcm_usb_writel(val, USB_XHCI_EC_REG(xhci_ec_base, IRADAT)); |
732 | |
733 | /* Reset USB 3.0 PHY for workaround to take effect */ |
734 | USB_CTRL_UNSET(params->regs[BRCM_REGS_CTRL], USB30_CTL1, PHY3_RESETB); |
735 | USB_CTRL_SET(params->regs[BRCM_REGS_CTRL], USB30_CTL1, PHY3_RESETB); |
736 | } |
737 | |
738 | static void brcmusb_xhci_soft_reset(struct brcm_usb_init_params *params, |
739 | int on_off) |
740 | { |
741 | /* Assert reset */ |
742 | if (on_off) { |
743 | if (USB_CTRL_MASK_FAMILY(params, USB_PM, XHC_SOFT_RESETB)) |
744 | USB_CTRL_UNSET_FAMILY(params, USB_PM, XHC_SOFT_RESETB); |
745 | else |
746 | USB_CTRL_UNSET_FAMILY(params, |
747 | USB30_CTL1, XHC_SOFT_RESETB); |
748 | } else { /* De-assert reset */ |
749 | if (USB_CTRL_MASK_FAMILY(params, USB_PM, XHC_SOFT_RESETB)) |
750 | USB_CTRL_SET_FAMILY(params, USB_PM, XHC_SOFT_RESETB); |
751 | else |
752 | USB_CTRL_SET_FAMILY(params, USB30_CTL1, |
753 | XHC_SOFT_RESETB); |
754 | } |
755 | } |
756 | |
757 | /* |
758 | * Return the best map table family. The order is: |
759 | * - exact match of chip and major rev |
760 | * - exact match of chip and closest older major rev |
761 | * - default chip/rev. |
762 | * NOTE: The minor rev is always ignored. |
763 | */ |
764 | static enum brcm_family_type get_family_type( |
765 | struct brcm_usb_init_params *params) |
766 | { |
767 | int last_type = -1; |
768 | u32 last_family = 0; |
769 | u32 family_no_major; |
770 | unsigned int x; |
771 | u32 family; |
772 | |
773 | family = params->family_id & 0xfffffff0; |
774 | family_no_major = params->family_id & 0xffffff00; |
775 | for (x = 0; id_to_type_table[x].id; x++) { |
776 | if (family == id_to_type_table[x].id) |
777 | return id_to_type_table[x].type; |
778 | if (family_no_major == (id_to_type_table[x].id & 0xffffff00)) |
779 | if (family > id_to_type_table[x].id && |
780 | last_family < id_to_type_table[x].id) { |
781 | last_family = id_to_type_table[x].id; |
782 | last_type = id_to_type_table[x].type; |
783 | } |
784 | } |
785 | |
786 | /* If no match, return the default family */ |
787 | if (last_type == -1) |
788 | return id_to_type_table[x].type; |
789 | return last_type; |
790 | } |
791 | |
792 | static void usb_init_ipp(struct brcm_usb_init_params *params) |
793 | { |
794 | void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; |
795 | u32 reg; |
796 | u32 orig_reg; |
797 | |
798 | /* Starting with the 7445d0, there are no longer separate 3.0 |
799 | * versions of IOC and IPP. |
800 | */ |
801 | if (USB_CTRL_MASK_FAMILY(params, USB30_CTL1, USB3_IOC)) { |
802 | if (params->ioc) |
803 | USB_CTRL_SET_FAMILY(params, USB30_CTL1, USB3_IOC); |
804 | if (params->ipp == 1) |
805 | USB_CTRL_SET_FAMILY(params, USB30_CTL1, USB3_IPP); |
806 | } |
807 | |
808 | reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP)); |
809 | orig_reg = reg; |
810 | if (USB_CTRL_MASK_FAMILY(params, SETUP, STRAP_CC_DRD_MODE_ENABLE_SEL)) |
811 | /* Never use the strap, it's going away. */ |
812 | reg &= ~(USB_CTRL_MASK_FAMILY(params, |
813 | SETUP, |
814 | STRAP_CC_DRD_MODE_ENABLE_SEL)); |
815 | if (USB_CTRL_MASK_FAMILY(params, SETUP, STRAP_IPP_SEL)) |
816 | /* override ipp strap pin (if it exits) */ |
817 | if (params->ipp != 2) |
818 | reg &= ~(USB_CTRL_MASK_FAMILY(params, SETUP, |
819 | STRAP_IPP_SEL)); |
820 | |
821 | /* Override the default OC and PP polarity */ |
822 | reg &= ~(USB_CTRL_MASK(SETUP, IPP) | USB_CTRL_MASK(SETUP, IOC)); |
823 | if (params->ioc) |
824 | reg |= USB_CTRL_MASK(SETUP, IOC); |
825 | if (params->ipp == 1) |
826 | reg |= USB_CTRL_MASK(SETUP, IPP); |
827 | brcm_usb_writel(val: reg, USB_CTRL_REG(ctrl, SETUP)); |
828 | |
829 | /* |
830 | * If we're changing IPP, make sure power is off long enough |
831 | * to turn off any connected devices. |
832 | */ |
833 | if ((reg ^ orig_reg) & USB_CTRL_MASK(SETUP, IPP)) |
834 | msleep(msecs: 50); |
835 | } |
836 | |
837 | static void usb_wake_enable(struct brcm_usb_init_params *params, |
838 | bool enable) |
839 | { |
840 | void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; |
841 | |
842 | if (enable) |
843 | USB_CTRL_SET(ctrl, USB_PM, RMTWKUP_EN); |
844 | else |
845 | USB_CTRL_UNSET(ctrl, USB_PM, RMTWKUP_EN); |
846 | } |
847 | |
848 | static void usb_init_common(struct brcm_usb_init_params *params) |
849 | { |
850 | u32 reg; |
851 | void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; |
852 | |
853 | /* Clear any pending wake conditions */ |
854 | usb_wake_enable(params, enable: false); |
855 | reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_PM_STATUS)); |
856 | brcm_usb_writel(val: reg, USB_CTRL_REG(ctrl, USB_PM_STATUS)); |
857 | |
858 | /* Take USB out of power down */ |
859 | if (USB_CTRL_MASK_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN)) { |
860 | USB_CTRL_UNSET_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN); |
861 | /* 1 millisecond - for USB clocks to settle down */ |
862 | usleep_range(min: 1000, max: 2000); |
863 | } |
864 | |
865 | if (USB_CTRL_MASK_FAMILY(params, USB_PM, USB_PWRDN)) { |
866 | USB_CTRL_UNSET_FAMILY(params, USB_PM, USB_PWRDN); |
867 | /* 1 millisecond - for USB clocks to settle down */ |
868 | usleep_range(min: 1000, max: 2000); |
869 | } |
870 | |
871 | if (params->selected_family != BRCM_FAMILY_74371A0 && |
872 | (BRCM_ID(reg: params->family_id) != 0x7364)) |
873 | /* |
874 | * HW7439-637: 7439a0 and its derivatives do not have large |
875 | * enough descriptor storage for this. |
876 | */ |
877 | USB_CTRL_SET_FAMILY(params, SETUP, SS_EHCI64BIT_EN); |
878 | |
879 | /* Block auto PLL suspend by USB2 PHY (Sasi) */ |
880 | USB_CTRL_SET(ctrl, PLL_CTL, PLL_SUSPEND_EN); |
881 | |
882 | reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP)); |
883 | if (params->selected_family == BRCM_FAMILY_7364A0) |
884 | /* Suppress overcurrent indication from USB30 ports for A0 */ |
885 | reg |= USB_CTRL_MASK_FAMILY(params, SETUP, OC3_DISABLE); |
886 | |
887 | brcmusb_usb_phy_ldo_fix(ctrl_base: ctrl); |
888 | brcmusb_usb2_eye_fix(ctrl_base: ctrl); |
889 | |
890 | /* |
891 | * Make sure the second and third memory controller |
892 | * interfaces are enabled if they exist. |
893 | */ |
894 | if (USB_CTRL_MASK_FAMILY(params, SETUP, SCB1_EN)) |
895 | reg |= USB_CTRL_MASK_FAMILY(params, SETUP, SCB1_EN); |
896 | if (USB_CTRL_MASK_FAMILY(params, SETUP, SCB2_EN)) |
897 | reg |= USB_CTRL_MASK_FAMILY(params, SETUP, SCB2_EN); |
898 | brcm_usb_writel(val: reg, USB_CTRL_REG(ctrl, SETUP)); |
899 | |
900 | brcmusb_memc_fix(params); |
901 | |
902 | /* Workaround for false positive OC for 7439b2 in DRD/Device mode */ |
903 | if ((params->family_id == 0x74390012) && |
904 | (params->supported_port_modes != USB_CTLR_MODE_HOST)) { |
905 | USB_CTRL_SET(ctrl, SETUP, OC_DISABLE_PORT1); |
906 | USB_CTRL_SET_FAMILY(params, SETUP, OC3_DISABLE_PORT1); |
907 | } |
908 | |
909 | if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) { |
910 | reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1)); |
911 | reg &= ~USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, |
912 | PORT_MODE); |
913 | reg |= params->port_mode; |
914 | brcm_usb_writel(val: reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1)); |
915 | } |
916 | if (USB_CTRL_MASK_FAMILY(params, USB_PM, BDC_SOFT_RESETB)) { |
917 | switch (params->supported_port_modes) { |
918 | case USB_CTLR_MODE_HOST: |
919 | USB_CTRL_UNSET_FAMILY(params, USB_PM, BDC_SOFT_RESETB); |
920 | break; |
921 | default: |
922 | USB_CTRL_UNSET_FAMILY(params, USB_PM, BDC_SOFT_RESETB); |
923 | USB_CTRL_SET_FAMILY(params, USB_PM, BDC_SOFT_RESETB); |
924 | break; |
925 | } |
926 | } |
927 | if (USB_CTRL_MASK_FAMILY(params, SETUP, CC_DRD_MODE_ENABLE)) { |
928 | if (params->supported_port_modes == USB_CTLR_MODE_TYPEC_PD) |
929 | USB_CTRL_SET_FAMILY(params, SETUP, CC_DRD_MODE_ENABLE); |
930 | else |
931 | USB_CTRL_UNSET_FAMILY(params, SETUP, |
932 | CC_DRD_MODE_ENABLE); |
933 | } |
934 | } |
935 | |
936 | static void usb_init_eohci(struct brcm_usb_init_params *params) |
937 | { |
938 | u32 reg; |
939 | void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; |
940 | |
941 | if (USB_CTRL_MASK_FAMILY(params, USB_PM, USB20_HC_RESETB)) |
942 | USB_CTRL_SET_FAMILY(params, USB_PM, USB20_HC_RESETB); |
943 | |
944 | if (params->selected_family == BRCM_FAMILY_7366C0) |
945 | /* |
946 | * Don't enable this so the memory controller doesn't read |
947 | * into memory holes. NOTE: This bit is low true on 7366C0. |
948 | */ |
949 | USB_CTRL_SET(ctrl, EBRIDGE, ESTOP_SCB_REQ); |
950 | |
951 | /* Setup the endian bits */ |
952 | reg = brcm_usb_readl(USB_CTRL_REG(ctrl, SETUP)); |
953 | reg &= ~USB_CTRL_SETUP_ENDIAN_BITS; |
954 | reg |= USB_CTRL_MASK_FAMILY(params, SETUP, ENDIAN); |
955 | brcm_usb_writel(val: reg, USB_CTRL_REG(ctrl, SETUP)); |
956 | |
957 | if (params->selected_family == BRCM_FAMILY_7271A0) |
958 | /* Enable LS keep alive fix for certain keyboards */ |
959 | USB_CTRL_SET(ctrl, OBRIDGE, LS_KEEP_ALIVE); |
960 | |
961 | if (params->family_id == 0x72550000) { |
962 | /* |
963 | * Make the burst size 512 bytes to fix a hardware bug |
964 | * on the 7255a0. See HW7255-24. |
965 | */ |
966 | reg = brcm_usb_readl(USB_CTRL_REG(ctrl, EBRIDGE)); |
967 | reg &= ~USB_CTRL_MASK(EBRIDGE, EBR_SCB_SIZE); |
968 | reg |= 0x800; |
969 | brcm_usb_writel(val: reg, USB_CTRL_REG(ctrl, EBRIDGE)); |
970 | } |
971 | } |
972 | |
973 | static void usb_init_xhci(struct brcm_usb_init_params *params) |
974 | { |
975 | void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; |
976 | |
977 | USB_CTRL_UNSET(ctrl, USB30_PCTL, PHY3_IDDQ_OVERRIDE); |
978 | /* 1 millisecond - for USB clocks to settle down */ |
979 | usleep_range(min: 1000, max: 2000); |
980 | |
981 | if (BRCM_ID(reg: params->family_id) == 0x7366) { |
982 | /* |
983 | * The PHY3_SOFT_RESETB bits default to the wrong state. |
984 | */ |
985 | USB_CTRL_SET(ctrl, USB30_PCTL, PHY3_SOFT_RESETB); |
986 | USB_CTRL_SET(ctrl, USB30_PCTL, PHY3_SOFT_RESETB_P1); |
987 | } |
988 | |
989 | /* |
990 | * Kick start USB3 PHY |
991 | * Make sure it's low to insure a rising edge. |
992 | */ |
993 | USB_CTRL_UNSET(ctrl, USB30_CTL1, PHY3_PLL_SEQ_START); |
994 | USB_CTRL_SET(ctrl, USB30_CTL1, PHY3_PLL_SEQ_START); |
995 | |
996 | brcmusb_usb3_phy_workarounds(params); |
997 | brcmusb_xhci_soft_reset(params, on_off: 0); |
998 | brcmusb_usb3_otp_fix(params); |
999 | } |
1000 | |
1001 | static void usb_uninit_common(struct brcm_usb_init_params *params) |
1002 | { |
1003 | if (USB_CTRL_MASK_FAMILY(params, USB_PM, USB_PWRDN)) |
1004 | USB_CTRL_SET_FAMILY(params, USB_PM, USB_PWRDN); |
1005 | |
1006 | if (USB_CTRL_MASK_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN)) |
1007 | USB_CTRL_SET_FAMILY(params, PLL_CTL, PLL_IDDQ_PWRDN); |
1008 | if (params->wake_enabled) |
1009 | usb_wake_enable(params, enable: true); |
1010 | } |
1011 | |
1012 | static void usb_uninit_eohci(struct brcm_usb_init_params *params) |
1013 | { |
1014 | } |
1015 | |
1016 | static void usb_uninit_xhci(struct brcm_usb_init_params *params) |
1017 | { |
1018 | brcmusb_xhci_soft_reset(params, on_off: 1); |
1019 | USB_CTRL_SET(params->regs[BRCM_REGS_CTRL], USB30_PCTL, |
1020 | PHY3_IDDQ_OVERRIDE); |
1021 | } |
1022 | |
1023 | static int usb_get_dual_select(struct brcm_usb_init_params *params) |
1024 | { |
1025 | void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; |
1026 | u32 reg = 0; |
1027 | |
1028 | pr_debug("%s\n" , __func__); |
1029 | if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) { |
1030 | reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1)); |
1031 | reg &= USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, |
1032 | PORT_MODE); |
1033 | } |
1034 | return reg; |
1035 | } |
1036 | |
1037 | static void usb_set_dual_select(struct brcm_usb_init_params *params) |
1038 | { |
1039 | void __iomem *ctrl = params->regs[BRCM_REGS_CTRL]; |
1040 | u32 reg; |
1041 | |
1042 | pr_debug("%s\n" , __func__); |
1043 | |
1044 | if (USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, PORT_MODE)) { |
1045 | reg = brcm_usb_readl(USB_CTRL_REG(ctrl, USB_DEVICE_CTL1)); |
1046 | reg &= ~USB_CTRL_MASK_FAMILY(params, USB_DEVICE_CTL1, |
1047 | PORT_MODE); |
1048 | reg |= params->port_mode; |
1049 | brcm_usb_writel(val: reg, USB_CTRL_REG(ctrl, USB_DEVICE_CTL1)); |
1050 | } |
1051 | } |
1052 | |
1053 | static const struct brcm_usb_init_ops bcm7445_ops = { |
1054 | .init_ipp = usb_init_ipp, |
1055 | .init_common = usb_init_common, |
1056 | .init_eohci = usb_init_eohci, |
1057 | .init_xhci = usb_init_xhci, |
1058 | .uninit_common = usb_uninit_common, |
1059 | .uninit_eohci = usb_uninit_eohci, |
1060 | .uninit_xhci = usb_uninit_xhci, |
1061 | .get_dual_select = usb_get_dual_select, |
1062 | .set_dual_select = usb_set_dual_select, |
1063 | }; |
1064 | |
1065 | void brcm_usb_dvr_init_4908(struct brcm_usb_init_params *params) |
1066 | { |
1067 | int fam; |
1068 | |
1069 | fam = BRCM_FAMILY_4908; |
1070 | params->selected_family = fam; |
1071 | params->usb_reg_bits_map = |
1072 | &usb_reg_bits_map_table[fam][0]; |
1073 | params->family_name = family_names[fam]; |
1074 | params->ops = &bcm7445_ops; |
1075 | } |
1076 | |
1077 | void brcm_usb_dvr_init_7445(struct brcm_usb_init_params *params) |
1078 | { |
1079 | int fam; |
1080 | |
1081 | pr_debug("%s\n" , __func__); |
1082 | |
1083 | fam = get_family_type(params); |
1084 | params->selected_family = fam; |
1085 | params->usb_reg_bits_map = |
1086 | &usb_reg_bits_map_table[fam][0]; |
1087 | params->family_name = family_names[fam]; |
1088 | params->ops = &bcm7445_ops; |
1089 | } |
1090 | |