diff options
-rw-r--r-- | Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt | 733 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-xusb-padctl.txt | 6 | ||||
-rw-r--r-- | Documentation/phy.txt | 16 | ||||
-rw-r--r-- | drivers/clk/tegra/clk-tegra210.c | 58 | ||||
-rw-r--r-- | drivers/phy/Kconfig | 2 | ||||
-rw-r--r-- | drivers/phy/Makefile | 2 | ||||
-rw-r--r-- | drivers/phy/phy-core.c | 50 | ||||
-rw-r--r-- | drivers/phy/tegra/Kconfig | 8 | ||||
-rw-r--r-- | drivers/phy/tegra/Makefile | 6 | ||||
-rw-r--r-- | drivers/phy/tegra/xusb-tegra124.c | 1752 | ||||
-rw-r--r-- | drivers/phy/tegra/xusb-tegra210.c | 2045 | ||||
-rw-r--r-- | drivers/phy/tegra/xusb.c | 1021 | ||||
-rw-r--r-- | drivers/phy/tegra/xusb.h | 421 | ||||
-rw-r--r-- | drivers/pinctrl/tegra/pinctrl-tegra-xusb.c | 20 | ||||
-rw-r--r-- | include/linux/clk/tegra.h | 5 | ||||
-rw-r--r-- | include/linux/phy/phy.h | 31 | ||||
-rw-r--r-- | include/linux/phy/tegra/xusb.h | 30 | ||||
-rw-r--r-- | include/soc/tegra/fuse.h | 1 |
18 files changed, 6173 insertions, 34 deletions
diff --git a/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt b/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt new file mode 100644 index 000000000000..0bf1ae243552 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/nvidia,tegra124-xusb-padctl.txt | |||
@@ -0,0 +1,733 @@ | |||
1 | Device tree binding for NVIDIA Tegra XUSB pad controller | ||
2 | ======================================================== | ||
3 | |||
4 | The Tegra XUSB pad controller manages a set of I/O lanes (with differential | ||
5 | signals) which connect directly to pins/pads on the SoC package. Each lane | ||
6 | is controlled by a HW block referred to as a "pad" in the Tegra hardware | ||
7 | documentation. Each such "pad" may control either one or multiple lanes, | ||
8 | and thus contains any logic common to all its lanes. Each lane can be | ||
9 | separately configured and powered up. | ||
10 | |||
11 | Some of the lanes are high-speed lanes, which can be used for PCIe, SATA or | ||
12 | super-speed USB. Other lanes are for various types of low-speed, full-speed | ||
13 | or high-speed USB (such as UTMI, ULPI and HSIC). The XUSB pad controller | ||
14 | contains a software-configurable mux that sits between the I/O controller | ||
15 | ports (e.g. PCIe) and the lanes. | ||
16 | |||
17 | In addition to per-lane configuration, USB 3.0 ports may require additional | ||
18 | settings on a per-board basis. | ||
19 | |||
20 | Pads will be represented as children of the top-level XUSB pad controller | ||
21 | device tree node. Each lane exposed by the pad will be represented by its | ||
22 | own subnode and can be referenced by users of the lane using the standard | ||
23 | PHY bindings, as described by the phy-bindings.txt file in this directory. | ||
24 | |||
25 | The Tegra hardware documentation refers to the connection between the XUSB | ||
26 | pad controller and the XUSB controller as "ports". This is confusing since | ||
27 | "port" is typically used to denote the physical USB receptacle. The device | ||
28 | tree binding in this document uses the term "port" to refer to the logical | ||
29 | abstraction of the signals that are routed to a USB receptacle (i.e. a PHY | ||
30 | for the USB signal, the VBUS power supply, the USB 2.0 companion port for | ||
31 | USB 3.0 receptacles, ...). | ||
32 | |||
33 | Required properties: | ||
34 | -------------------- | ||
35 | - compatible: Must be: | ||
36 | - Tegra124: "nvidia,tegra124-xusb-padctl" | ||
37 | - Tegra132: "nvidia,tegra132-xusb-padctl", "nvidia,tegra124-xusb-padctl" | ||
38 | - Tegra210: "nvidia,tegra210-xusb-padctl" | ||
39 | - reg: Physical base address and length of the controller's registers. | ||
40 | - resets: Must contain an entry for each entry in reset-names. | ||
41 | - reset-names: Must include the following entries: | ||
42 | - "padctl" | ||
43 | |||
44 | |||
45 | Pad nodes: | ||
46 | ========== | ||
47 | |||
48 | A required child node named "pads" contains a list of subnodes, one for each | ||
49 | of the pads exposed by the XUSB pad controller. Each pad may need additional | ||
50 | resources that can be referenced in its pad node. | ||
51 | |||
52 | The "status" property is used to enable or disable the use of a pad. If set | ||
53 | to "disabled", the pad will not be used on the given board. In order to use | ||
54 | the pad and any of its lanes, this property must be set to "okay". | ||
55 | |||
56 | For Tegra124 and Tegra132, the following pads exist: usb2, ulpi, hsic, pcie | ||
57 | and sata. No extra resources are required for operation of these pads. | ||
58 | |||
59 | For Tegra210, the following pads exist: usb2, hsic, pcie and sata. Below is | ||
60 | a description of the properties of each pad. | ||
61 | |||
62 | UTMI pad: | ||
63 | --------- | ||
64 | |||
65 | Required properties: | ||
66 | - clocks: Must contain an entry for each entry in clock-names. | ||
67 | - clock-names: Must contain the following entries: | ||
68 | - "trk": phandle and specifier referring to the USB2 tracking clock | ||
69 | |||
70 | HSIC pad: | ||
71 | --------- | ||
72 | |||
73 | Required properties: | ||
74 | - clocks: Must contain an entry for each entry in clock-names. | ||
75 | - clock-names: Must contain the following entries: | ||
76 | - "trk": phandle and specifier referring to the HSIC tracking clock | ||
77 | |||
78 | PCIe pad: | ||
79 | --------- | ||
80 | |||
81 | Required properties: | ||
82 | - clocks: Must contain an entry for each entry in clock-names. | ||
83 | - clock-names: Must contain the following entries: | ||
84 | - "pll": phandle and specifier referring to the PLLE | ||
85 | - resets: Must contain an entry for each entry in reset-names. | ||
86 | - reset-names: Must contain the following entries: | ||
87 | - "phy": reset for the PCIe UPHY block | ||
88 | |||
89 | SATA pad: | ||
90 | --------- | ||
91 | |||
92 | Required properties: | ||
93 | - resets: Must contain an entry for each entry in reset-names. | ||
94 | - reset-names: Must contain the following entries: | ||
95 | - "phy": reset for the SATA UPHY block | ||
96 | |||
97 | |||
98 | PHY nodes: | ||
99 | ========== | ||
100 | |||
101 | Each pad node has a child named "lanes" that contains one or more children of | ||
102 | its own, each representing one of the lanes controlled by the pad. | ||
103 | |||
104 | Required properties: | ||
105 | -------------------- | ||
106 | - status: Defines the operation status of the PHY. Valid values are: | ||
107 | - "disabled": the PHY is disabled | ||
108 | - "okay": the PHY is enabled | ||
109 | - #phy-cells: Should be 0. Since each lane represents a single PHY, there is | ||
110 | no need for an additional specifier. | ||
111 | - nvidia,function: The output function of the PHY. See below for a list of | ||
112 | valid functions per SoC generation. | ||
113 | |||
114 | For Tegra124 and Tegra132, the list of valid PHY nodes is given below: | ||
115 | - usb2: usb2-0, usb2-1, usb2-2 | ||
116 | - functions: "snps", "xusb", "uart" | ||
117 | - ulpi: ulpi-0 | ||
118 | - functions: "snps", "xusb" | ||
119 | - hsic: hsic-0, hsic-1 | ||
120 | - functions: "snps", "xusb" | ||
121 | - pcie: pcie-0, pcie-1, pcie-2, pcie-3, pcie-4 | ||
122 | - functions: "pcie", "usb3-ss" | ||
123 | - sata: sata-0 | ||
124 | - functions: "usb3-ss", "sata" | ||
125 | |||
126 | For Tegra210, the list of valid PHY nodes is given below: | ||
127 | - utmi: utmi-0, utmi-1, utmi-2, utmi-3 | ||
128 | - functions: "snps", "xusb", "uart" | ||
129 | - hsic: hsic-0, hsic-1 | ||
130 | - functions: "snps", "xusb" | ||
131 | - pcie: pcie-0, pcie-1, pcie-2, pcie-3, pcie-4, pcie-5, pcie-6 | ||
132 | - functions: "pcie-x1", "usb3-ss", "pcie-x4" | ||
133 | - sata: sata-0 | ||
134 | - functions: "usb3-ss", "sata" | ||
135 | |||
136 | |||
137 | Port nodes: | ||
138 | =========== | ||
139 | |||
140 | A required child node named "ports" contains a list of all the ports exposed | ||
141 | by the XUSB pad controller. Per-port configuration is only required for USB. | ||
142 | |||
143 | USB2 ports: | ||
144 | ----------- | ||
145 | |||
146 | Required properties: | ||
147 | - status: Defines the operation status of the port. Valid values are: | ||
148 | - "disabled": the port is disabled | ||
149 | - "okay": the port is enabled | ||
150 | - mode: A string that determines the mode in which to run the port. Valid | ||
151 | values are: | ||
152 | - "host": for USB host mode | ||
153 | - "device": for USB device mode | ||
154 | - "otg": for USB OTG mode | ||
155 | |||
156 | Optional properties: | ||
157 | - nvidia,internal: A boolean property whose presence determines that a port | ||
158 | is internal. In the absence of this property the port is considered to be | ||
159 | external. | ||
160 | - vbus-supply: phandle to a regulator supplying the VBUS voltage. | ||
161 | |||
162 | ULPI ports: | ||
163 | ----------- | ||
164 | |||
165 | Optional properties: | ||
166 | - status: Defines the operation status of the port. Valid values are: | ||
167 | - "disabled": the port is disabled | ||
168 | - "okay": the port is enabled | ||
169 | - nvidia,internal: A boolean property whose presence determines that a port | ||
170 | is internal. In the absence of this property the port is considered to be | ||
171 | external. | ||
172 | - vbus-supply: phandle to a regulator supplying the VBUS voltage. | ||
173 | |||
174 | HSIC ports: | ||
175 | ----------- | ||
176 | |||
177 | Required properties: | ||
178 | - status: Defines the operation status of the port. Valid values are: | ||
179 | - "disabled": the port is disabled | ||
180 | - "okay": the port is enabled | ||
181 | |||
182 | Optional properties: | ||
183 | - vbus-supply: phandle to a regulator supplying the VBUS voltage. | ||
184 | |||
185 | Super-speed USB ports: | ||
186 | ---------------------- | ||
187 | |||
188 | Required properties: | ||
189 | - status: Defines the operation status of the port. Valid values are: | ||
190 | - "disabled": the port is disabled | ||
191 | - "okay": the port is enabled | ||
192 | - nvidia,usb2-companion: A single cell that specifies the physical port number | ||
193 | to map this super-speed USB port to. The range of valid port numbers varies | ||
194 | with the SoC generation: | ||
195 | - 0-2: for Tegra124 and Tegra132 | ||
196 | - 0-3: for Tegra210 | ||
197 | |||
198 | Optional properties: | ||
199 | - nvidia,internal: A boolean property whose presence determines that a port | ||
200 | is internal. In the absence of this property the port is considered to be | ||
201 | external. | ||
202 | |||
203 | For Tegra124 and Tegra132, the XUSB pad controller exposes the following | ||
204 | ports: | ||
205 | - 3x USB2: usb2-0, usb2-1, usb2-2 | ||
206 | - 1x ULPI: ulpi-0 | ||
207 | - 2x HSIC: hsic-0, hsic-1 | ||
208 | - 2x super-speed USB: usb3-0, usb3-1 | ||
209 | |||
210 | For Tegra210, the XUSB pad controller exposes the following ports: | ||
211 | - 4x USB2: usb2-0, usb2-1, usb2-2, usb2-3 | ||
212 | - 2x HSIC: hsic-0, hsic-1 | ||
213 | - 4x super-speed USB: usb3-0, usb3-1, usb3-2, usb3-3 | ||
214 | |||
215 | |||
216 | Examples: | ||
217 | ========= | ||
218 | |||
219 | Tegra124 and Tegra132: | ||
220 | ---------------------- | ||
221 | |||
222 | SoC include: | ||
223 | |||
224 | padctl@7009f000 { | ||
225 | /* for Tegra124 */ | ||
226 | compatible = "nvidia,tegra124-xusb-padctl"; | ||
227 | /* for Tegra132 */ | ||
228 | compatible = "nvidia,tegra132-xusb-padctl", | ||
229 | "nvidia,tegra124-xusb-padctl"; | ||
230 | reg = <0x0 0x7009f000 0x0 0x1000>; | ||
231 | resets = <&tegra_car 142>; | ||
232 | reset-names = "padctl"; | ||
233 | |||
234 | pads { | ||
235 | usb2 { | ||
236 | status = "disabled"; | ||
237 | |||
238 | lanes { | ||
239 | usb2-0 { | ||
240 | status = "disabled"; | ||
241 | #phy-cells = <0>; | ||
242 | }; | ||
243 | |||
244 | usb2-1 { | ||
245 | status = "disabled"; | ||
246 | #phy-cells = <0>; | ||
247 | }; | ||
248 | |||
249 | usb2-2 { | ||
250 | status = "disabled"; | ||
251 | #phy-cells = <0>; | ||
252 | }; | ||
253 | }; | ||
254 | }; | ||
255 | |||
256 | ulpi { | ||
257 | status = "disabled"; | ||
258 | |||
259 | lanes { | ||
260 | ulpi-0 { | ||
261 | status = "disabled"; | ||
262 | #phy-cells = <0>; | ||
263 | }; | ||
264 | }; | ||
265 | }; | ||
266 | |||
267 | hsic { | ||
268 | status = "disabled"; | ||
269 | |||
270 | lanes { | ||
271 | hsic-0 { | ||
272 | status = "disabled"; | ||
273 | #phy-cells = <0>; | ||
274 | }; | ||
275 | |||
276 | hsic-1 { | ||
277 | status = "disabled"; | ||
278 | #phy-cells = <0>; | ||
279 | }; | ||
280 | }; | ||
281 | }; | ||
282 | |||
283 | pcie { | ||
284 | status = "disabled"; | ||
285 | |||
286 | lanes { | ||
287 | pcie-0 { | ||
288 | status = "disabled"; | ||
289 | #phy-cells = <0>; | ||
290 | }; | ||
291 | |||
292 | pcie-1 { | ||
293 | status = "disabled"; | ||
294 | #phy-cells = <0>; | ||
295 | }; | ||
296 | |||
297 | pcie-2 { | ||
298 | status = "disabled"; | ||
299 | #phy-cells = <0>; | ||
300 | }; | ||
301 | |||
302 | pcie-3 { | ||
303 | status = "disabled"; | ||
304 | #phy-cells = <0>; | ||
305 | }; | ||
306 | |||
307 | pcie-4 { | ||
308 | status = "disabled"; | ||
309 | #phy-cells = <0>; | ||
310 | }; | ||
311 | }; | ||
312 | }; | ||
313 | |||
314 | sata { | ||
315 | status = "disabled"; | ||
316 | |||
317 | lanes { | ||
318 | sata-0 { | ||
319 | status = "disabled"; | ||
320 | #phy-cells = <0>; | ||
321 | }; | ||
322 | }; | ||
323 | }; | ||
324 | }; | ||
325 | |||
326 | ports { | ||
327 | usb2-0 { | ||
328 | status = "disabled"; | ||
329 | }; | ||
330 | |||
331 | usb2-1 { | ||
332 | status = "disabled"; | ||
333 | }; | ||
334 | |||
335 | usb2-2 { | ||
336 | status = "disabled"; | ||
337 | }; | ||
338 | |||
339 | ulpi-0 { | ||
340 | status = "disabled"; | ||
341 | }; | ||
342 | |||
343 | hsic-0 { | ||
344 | status = "disabled"; | ||
345 | }; | ||
346 | |||
347 | hsic-1 { | ||
348 | status = "disabled"; | ||
349 | }; | ||
350 | |||
351 | usb3-0 { | ||
352 | status = "disabled"; | ||
353 | }; | ||
354 | |||
355 | usb3-1 { | ||
356 | status = "disabled"; | ||
357 | }; | ||
358 | }; | ||
359 | }; | ||
360 | |||
361 | Board file: | ||
362 | |||
363 | padctl@7009f000 { | ||
364 | status = "okay"; | ||
365 | |||
366 | pads { | ||
367 | usb2 { | ||
368 | status = "okay"; | ||
369 | |||
370 | lanes { | ||
371 | usb2-0 { | ||
372 | nvidia,function = "xusb"; | ||
373 | status = "okay"; | ||
374 | }; | ||
375 | |||
376 | usb2-1 { | ||
377 | nvidia,function = "xusb"; | ||
378 | status = "okay"; | ||
379 | }; | ||
380 | |||
381 | usb2-2 { | ||
382 | nvidia,function = "xusb"; | ||
383 | status = "okay"; | ||
384 | }; | ||
385 | }; | ||
386 | }; | ||
387 | |||
388 | pcie { | ||
389 | status = "okay"; | ||
390 | |||
391 | lanes { | ||
392 | pcie-0 { | ||
393 | nvidia,function = "usb3-ss"; | ||
394 | status = "okay"; | ||
395 | }; | ||
396 | |||
397 | pcie-2 { | ||
398 | nvidia,function = "pcie"; | ||
399 | status = "okay"; | ||
400 | }; | ||
401 | |||
402 | pcie-4 { | ||
403 | nvidia,function = "pcie"; | ||
404 | status = "okay"; | ||
405 | }; | ||
406 | }; | ||
407 | }; | ||
408 | |||
409 | sata { | ||
410 | status = "okay"; | ||
411 | |||
412 | lanes { | ||
413 | sata-0 { | ||
414 | nvidia,function = "sata"; | ||
415 | status = "okay"; | ||
416 | }; | ||
417 | }; | ||
418 | }; | ||
419 | }; | ||
420 | |||
421 | ports { | ||
422 | /* Micro A/B */ | ||
423 | usb2-0 { | ||
424 | status = "okay"; | ||
425 | mode = "otg"; | ||
426 | }; | ||
427 | |||
428 | /* Mini PCIe */ | ||
429 | usb2-1 { | ||
430 | status = "okay"; | ||
431 | mode = "host"; | ||
432 | }; | ||
433 | |||
434 | /* USB3 */ | ||
435 | usb2-2 { | ||
436 | status = "okay"; | ||
437 | mode = "host"; | ||
438 | |||
439 | vbus-supply = <&vdd_usb3_vbus>; | ||
440 | }; | ||
441 | |||
442 | usb3-0 { | ||
443 | nvidia,port = <2>; | ||
444 | status = "okay"; | ||
445 | }; | ||
446 | }; | ||
447 | }; | ||
448 | |||
449 | Tegra210: | ||
450 | --------- | ||
451 | |||
452 | SoC include: | ||
453 | |||
454 | padctl@7009f000 { | ||
455 | compatible = "nvidia,tegra210-xusb-padctl"; | ||
456 | reg = <0x0 0x7009f000 0x0 0x1000>; | ||
457 | resets = <&tegra_car 142>; | ||
458 | reset-names = "padctl"; | ||
459 | |||
460 | status = "disabled"; | ||
461 | |||
462 | pads { | ||
463 | usb2 { | ||
464 | clocks = <&tegra_car TEGRA210_CLK_USB2_TRK>; | ||
465 | clock-names = "trk"; | ||
466 | status = "disabled"; | ||
467 | |||
468 | lanes { | ||
469 | usb2-0 { | ||
470 | status = "disabled"; | ||
471 | #phy-cells = <0>; | ||
472 | }; | ||
473 | |||
474 | usb2-1 { | ||
475 | status = "disabled"; | ||
476 | #phy-cells = <0>; | ||
477 | }; | ||
478 | |||
479 | usb2-2 { | ||
480 | status = "disabled"; | ||
481 | #phy-cells = <0>; | ||
482 | }; | ||
483 | |||
484 | usb2-3 { | ||
485 | status = "disabled"; | ||
486 | #phy-cells = <0>; | ||
487 | }; | ||
488 | }; | ||
489 | }; | ||
490 | |||
491 | hsic { | ||
492 | clocks = <&tegra_car TEGRA210_CLK_HSIC_TRK>; | ||
493 | clock-names = "trk"; | ||
494 | status = "disabled"; | ||
495 | |||
496 | lanes { | ||
497 | hsic-0 { | ||
498 | status = "disabled"; | ||
499 | #phy-cells = <0>; | ||
500 | }; | ||
501 | |||
502 | hsic-1 { | ||
503 | status = "disabled"; | ||
504 | #phy-cells = <0>; | ||
505 | }; | ||
506 | }; | ||
507 | }; | ||
508 | |||
509 | pcie { | ||
510 | clocks = <&tegra_car TEGRA210_CLK_PLL_E>; | ||
511 | clock-names = "pll"; | ||
512 | resets = <&tegra_car 205>; | ||
513 | reset-names = "phy"; | ||
514 | status = "disabled"; | ||
515 | |||
516 | lanes { | ||
517 | pcie-0 { | ||
518 | status = "disabled"; | ||
519 | #phy-cells = <0>; | ||
520 | }; | ||
521 | |||
522 | pcie-1 { | ||
523 | status = "disabled"; | ||
524 | #phy-cells = <0>; | ||
525 | }; | ||
526 | |||
527 | pcie-2 { | ||
528 | status = "disabled"; | ||
529 | #phy-cells = <0>; | ||
530 | }; | ||
531 | |||
532 | pcie-3 { | ||
533 | status = "disabled"; | ||
534 | #phy-cells = <0>; | ||
535 | }; | ||
536 | |||
537 | pcie-4 { | ||
538 | status = "disabled"; | ||
539 | #phy-cells = <0>; | ||
540 | }; | ||
541 | |||
542 | pcie-5 { | ||
543 | status = "disabled"; | ||
544 | #phy-cells = <0>; | ||
545 | }; | ||
546 | |||
547 | pcie-6 { | ||
548 | status = "disabled"; | ||
549 | #phy-cells = <0>; | ||
550 | }; | ||
551 | }; | ||
552 | }; | ||
553 | |||
554 | sata { | ||
555 | clocks = <&tegra_car TEGRA210_CLK_PLL_E>; | ||
556 | clock-names = "pll"; | ||
557 | resets = <&tegra_car 204>; | ||
558 | reset-names = "phy"; | ||
559 | status = "disabled"; | ||
560 | |||
561 | lanes { | ||
562 | sata-0 { | ||
563 | status = "disabled"; | ||
564 | #phy-cells = <0>; | ||
565 | }; | ||
566 | }; | ||
567 | }; | ||
568 | }; | ||
569 | |||
570 | ports { | ||
571 | usb2-0 { | ||
572 | status = "disabled"; | ||
573 | }; | ||
574 | |||
575 | usb2-1 { | ||
576 | status = "disabled"; | ||
577 | }; | ||
578 | |||
579 | usb2-2 { | ||
580 | status = "disabled"; | ||
581 | }; | ||
582 | |||
583 | usb2-3 { | ||
584 | status = "disabled"; | ||
585 | }; | ||
586 | |||
587 | hsic-0 { | ||
588 | status = "disabled"; | ||
589 | }; | ||
590 | |||
591 | hsic-1 { | ||
592 | status = "disabled"; | ||
593 | }; | ||
594 | |||
595 | usb3-0 { | ||
596 | status = "disabled"; | ||
597 | }; | ||
598 | |||
599 | usb3-1 { | ||
600 | status = "disabled"; | ||
601 | }; | ||
602 | |||
603 | usb3-2 { | ||
604 | status = "disabled"; | ||
605 | }; | ||
606 | |||
607 | usb3-3 { | ||
608 | status = "disabled"; | ||
609 | }; | ||
610 | }; | ||
611 | }; | ||
612 | |||
613 | Board file: | ||
614 | |||
615 | padctl@7009f000 { | ||
616 | status = "okay"; | ||
617 | |||
618 | pads { | ||
619 | usb2 { | ||
620 | status = "okay"; | ||
621 | |||
622 | lanes { | ||
623 | usb2-0 { | ||
624 | nvidia,function = "xusb"; | ||
625 | status = "okay"; | ||
626 | }; | ||
627 | |||
628 | usb2-1 { | ||
629 | nvidia,function = "xusb"; | ||
630 | status = "okay"; | ||
631 | }; | ||
632 | |||
633 | usb2-2 { | ||
634 | nvidia,function = "xusb"; | ||
635 | status = "okay"; | ||
636 | }; | ||
637 | |||
638 | usb2-3 { | ||
639 | nvidia,function = "xusb"; | ||
640 | status = "okay"; | ||
641 | }; | ||
642 | }; | ||
643 | }; | ||
644 | |||
645 | pcie { | ||
646 | status = "okay"; | ||
647 | |||
648 | lanes { | ||
649 | pcie-0 { | ||
650 | nvidia,function = "pcie-x1"; | ||
651 | status = "okay"; | ||
652 | }; | ||
653 | |||
654 | pcie-1 { | ||
655 | nvidia,function = "pcie-x4"; | ||
656 | status = "okay"; | ||
657 | }; | ||
658 | |||
659 | pcie-2 { | ||
660 | nvidia,function = "pcie-x4"; | ||
661 | status = "okay"; | ||
662 | }; | ||
663 | |||
664 | pcie-3 { | ||
665 | nvidia,function = "pcie-x4"; | ||
666 | status = "okay"; | ||
667 | }; | ||
668 | |||
669 | pcie-4 { | ||
670 | nvidia,function = "pcie-x4"; | ||
671 | status = "okay"; | ||
672 | }; | ||
673 | |||
674 | pcie-5 { | ||
675 | nvidia,function = "usb3-ss"; | ||
676 | status = "okay"; | ||
677 | }; | ||
678 | |||
679 | pcie-6 { | ||
680 | nvidia,function = "usb3-ss"; | ||
681 | status = "okay"; | ||
682 | }; | ||
683 | }; | ||
684 | }; | ||
685 | |||
686 | sata { | ||
687 | status = "okay"; | ||
688 | |||
689 | lanes { | ||
690 | sata-0 { | ||
691 | nvidia,function = "sata"; | ||
692 | status = "okay"; | ||
693 | }; | ||
694 | }; | ||
695 | }; | ||
696 | }; | ||
697 | |||
698 | ports { | ||
699 | usb2-0 { | ||
700 | status = "okay"; | ||
701 | mode = "otg"; | ||
702 | }; | ||
703 | |||
704 | usb2-1 { | ||
705 | status = "okay"; | ||
706 | vbus-supply = <&vdd_5v0_rtl>; | ||
707 | mode = "host"; | ||
708 | }; | ||
709 | |||
710 | usb2-2 { | ||
711 | status = "okay"; | ||
712 | vbus-supply = <&vdd_usb_vbus>; | ||
713 | mode = "host"; | ||
714 | }; | ||
715 | |||
716 | usb2-3 { | ||
717 | status = "okay"; | ||
718 | mode = "host"; | ||
719 | }; | ||
720 | |||
721 | usb3-0 { | ||
722 | status = "okay"; | ||
723 | nvidia,lanes = "pcie-6"; | ||
724 | nvidia,port = <1>; | ||
725 | }; | ||
726 | |||
727 | usb3-1 { | ||
728 | status = "okay"; | ||
729 | nvidia,lanes = "pcie-5"; | ||
730 | nvidia,port = <2>; | ||
731 | }; | ||
732 | }; | ||
733 | }; | ||
diff --git a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-xusb-padctl.txt b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-xusb-padctl.txt index 30676ded85bb..8a6223dbc143 100644 --- a/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-xusb-padctl.txt +++ b/Documentation/devicetree/bindings/pinctrl/nvidia,tegra124-xusb-padctl.txt | |||
@@ -1,6 +1,12 @@ | |||
1 | Device tree binding for NVIDIA Tegra XUSB pad controller | 1 | Device tree binding for NVIDIA Tegra XUSB pad controller |
2 | ======================================================== | 2 | ======================================================== |
3 | 3 | ||
4 | NOTE: It turns out that this binding isn't an accurate description of the XUSB | ||
5 | pad controller. While the description is good enough for the functional subset | ||
6 | required for PCIe and SATA, it lacks the flexibility to represent the features | ||
7 | needed for USB. For the new binding, see ../phy/nvidia,tegra-xusb-padctl.txt. | ||
8 | The binding described in this file is deprecated and should not be used. | ||
9 | |||
4 | The Tegra XUSB pad controller manages a set of lanes, each of which can be | 10 | The Tegra XUSB pad controller manages a set of lanes, each of which can be |
5 | assigned to one out of a set of different pads. Some of these pads have an | 11 | assigned to one out of a set of different pads. Some of these pads have an |
6 | associated PHY that must be powered up before the pad can be used. | 12 | associated PHY that must be powered up before the pad can be used. |
diff --git a/Documentation/phy.txt b/Documentation/phy.txt index b388c5af9e72..0aa994bd9a91 100644 --- a/Documentation/phy.txt +++ b/Documentation/phy.txt | |||
@@ -31,16 +31,28 @@ should provide its own implementation of of_xlate. of_xlate is used only for | |||
31 | dt boot case. | 31 | dt boot case. |
32 | 32 | ||
33 | #define of_phy_provider_register(dev, xlate) \ | 33 | #define of_phy_provider_register(dev, xlate) \ |
34 | __of_phy_provider_register((dev), THIS_MODULE, (xlate)) | 34 | __of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate)) |
35 | 35 | ||
36 | #define devm_of_phy_provider_register(dev, xlate) \ | 36 | #define devm_of_phy_provider_register(dev, xlate) \ |
37 | __devm_of_phy_provider_register((dev), THIS_MODULE, (xlate)) | 37 | __devm_of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate)) |
38 | 38 | ||
39 | of_phy_provider_register and devm_of_phy_provider_register macros can be used to | 39 | of_phy_provider_register and devm_of_phy_provider_register macros can be used to |
40 | register the phy_provider and it takes device and of_xlate as | 40 | register the phy_provider and it takes device and of_xlate as |
41 | arguments. For the dt boot case, all PHY providers should use one of the above | 41 | arguments. For the dt boot case, all PHY providers should use one of the above |
42 | 2 macros to register the PHY provider. | 42 | 2 macros to register the PHY provider. |
43 | 43 | ||
44 | Often the device tree nodes associated with a PHY provider will contain a set | ||
45 | of children that each represent a single PHY. Some bindings may nest the child | ||
46 | nodes within extra levels for context and extensibility, in which case the low | ||
47 | level of_phy_provider_register_full() and devm_of_phy_provider_register_full() | ||
48 | macros can be used to override the node containing the children. | ||
49 | |||
50 | #define of_phy_provider_register_full(dev, children, xlate) \ | ||
51 | __of_phy_provider_register(dev, children, THIS_MODULE, xlate) | ||
52 | |||
53 | #define devm_of_phy_provider_register_full(dev, children, xlate) \ | ||
54 | __devm_of_phy_provider_register_full(dev, children, THIS_MODULE, xlate) | ||
55 | |||
44 | void devm_of_phy_provider_unregister(struct device *dev, | 56 | void devm_of_phy_provider_unregister(struct device *dev, |
45 | struct phy_provider *phy_provider); | 57 | struct phy_provider *phy_provider); |
46 | void of_phy_provider_unregister(struct phy_provider *phy_provider); | 58 | void of_phy_provider_unregister(struct phy_provider *phy_provider); |
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 637041fd53ad..3d0edee1f9fe 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c | |||
@@ -175,6 +175,19 @@ | |||
175 | #define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN BIT(14) | 175 | #define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN BIT(14) |
176 | #define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN BIT(12) | 176 | #define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN BIT(12) |
177 | 177 | ||
178 | #define SATA_PLL_CFG0 0x490 | ||
179 | #define SATA_PLL_CFG0_PADPLL_RESET_SWCTL BIT(0) | ||
180 | #define SATA_PLL_CFG0_PADPLL_USE_LOCKDET BIT(2) | ||
181 | #define SATA_PLL_CFG0_PADPLL_SLEEP_IDDQ BIT(13) | ||
182 | #define SATA_PLL_CFG0_SEQ_ENABLE BIT(24) | ||
183 | |||
184 | #define XUSBIO_PLL_CFG0 0x51c | ||
185 | #define XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL BIT(0) | ||
186 | #define XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL BIT(2) | ||
187 | #define XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET BIT(6) | ||
188 | #define XUSBIO_PLL_CFG0_PADPLL_SLEEP_IDDQ BIT(13) | ||
189 | #define XUSBIO_PLL_CFG0_SEQ_ENABLE BIT(24) | ||
190 | |||
178 | #define UTMIPLL_HW_PWRDN_CFG0 0x52c | 191 | #define UTMIPLL_HW_PWRDN_CFG0 0x52c |
179 | #define UTMIPLL_HW_PWRDN_CFG0_UTMIPLL_LOCK BIT(31) | 192 | #define UTMIPLL_HW_PWRDN_CFG0_UTMIPLL_LOCK BIT(31) |
180 | #define UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE BIT(25) | 193 | #define UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE BIT(25) |
@@ -416,6 +429,51 @@ static const char *mux_pllmcp_clkm[] = { | |||
416 | #define PLLU_MISC0_WRITE_MASK 0xbfffffff | 429 | #define PLLU_MISC0_WRITE_MASK 0xbfffffff |
417 | #define PLLU_MISC1_WRITE_MASK 0x00000007 | 430 | #define PLLU_MISC1_WRITE_MASK 0x00000007 |
418 | 431 | ||
432 | void tegra210_xusb_pll_hw_control_enable(void) | ||
433 | { | ||
434 | u32 val; | ||
435 | |||
436 | val = readl_relaxed(clk_base + XUSBIO_PLL_CFG0); | ||
437 | val &= ~(XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL | | ||
438 | XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL); | ||
439 | val |= XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET | | ||
440 | XUSBIO_PLL_CFG0_PADPLL_SLEEP_IDDQ; | ||
441 | writel_relaxed(val, clk_base + XUSBIO_PLL_CFG0); | ||
442 | } | ||
443 | EXPORT_SYMBOL_GPL(tegra210_xusb_pll_hw_control_enable); | ||
444 | |||
445 | void tegra210_xusb_pll_hw_sequence_start(void) | ||
446 | { | ||
447 | u32 val; | ||
448 | |||
449 | val = readl_relaxed(clk_base + XUSBIO_PLL_CFG0); | ||
450 | val |= XUSBIO_PLL_CFG0_SEQ_ENABLE; | ||
451 | writel_relaxed(val, clk_base + XUSBIO_PLL_CFG0); | ||
452 | } | ||
453 | EXPORT_SYMBOL_GPL(tegra210_xusb_pll_hw_sequence_start); | ||
454 | |||
455 | void tegra210_sata_pll_hw_control_enable(void) | ||
456 | { | ||
457 | u32 val; | ||
458 | |||
459 | val = readl_relaxed(clk_base + SATA_PLL_CFG0); | ||
460 | val &= ~SATA_PLL_CFG0_PADPLL_RESET_SWCTL; | ||
461 | val |= SATA_PLL_CFG0_PADPLL_USE_LOCKDET | | ||
462 | SATA_PLL_CFG0_PADPLL_SLEEP_IDDQ; | ||
463 | writel_relaxed(val, clk_base + SATA_PLL_CFG0); | ||
464 | } | ||
465 | EXPORT_SYMBOL_GPL(tegra210_sata_pll_hw_control_enable); | ||
466 | |||
467 | void tegra210_sata_pll_hw_sequence_start(void) | ||
468 | { | ||
469 | u32 val; | ||
470 | |||
471 | val = readl_relaxed(clk_base + SATA_PLL_CFG0); | ||
472 | val |= SATA_PLL_CFG0_SEQ_ENABLE; | ||
473 | writel_relaxed(val, clk_base + SATA_PLL_CFG0); | ||
474 | } | ||
475 | EXPORT_SYMBOL_GPL(tegra210_sata_pll_hw_sequence_start); | ||
476 | |||
419 | static inline void _pll_misc_chk_default(void __iomem *base, | 477 | static inline void _pll_misc_chk_default(void __iomem *base, |
420 | struct tegra_clk_pll_params *params, | 478 | struct tegra_clk_pll_params *params, |
421 | u8 misc_num, u32 default_val, u32 mask) | 479 | u8 misc_num, u32 default_val, u32 mask) |
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 26566db09de0..27e5f6ee9a2a 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig | |||
@@ -421,4 +421,6 @@ config PHY_CYGNUS_PCIE | |||
421 | Enable this to support the Broadcom Cygnus PCIe PHY. | 421 | Enable this to support the Broadcom Cygnus PCIe PHY. |
422 | If unsure, say N. | 422 | If unsure, say N. |
423 | 423 | ||
424 | source "drivers/phy/tegra/Kconfig" | ||
425 | |||
424 | endmenu | 426 | endmenu |
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 24596a96a887..d4f06e69fd9a 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile | |||
@@ -52,3 +52,5 @@ obj-$(CONFIG_PHY_TUSB1210) += phy-tusb1210.o | |||
52 | obj-$(CONFIG_PHY_BRCMSTB_SATA) += phy-brcmstb-sata.o | 52 | obj-$(CONFIG_PHY_BRCMSTB_SATA) += phy-brcmstb-sata.o |
53 | obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o | 53 | obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o |
54 | obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o | 54 | obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o |
55 | |||
56 | obj-$(CONFIG_ARCH_TEGRA) += tegra/ | ||
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index e7e574dc667a..b72e9a3b6429 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c | |||
@@ -141,7 +141,7 @@ static struct phy_provider *of_phy_provider_lookup(struct device_node *node) | |||
141 | if (phy_provider->dev->of_node == node) | 141 | if (phy_provider->dev->of_node == node) |
142 | return phy_provider; | 142 | return phy_provider; |
143 | 143 | ||
144 | for_each_child_of_node(phy_provider->dev->of_node, child) | 144 | for_each_child_of_node(phy_provider->children, child) |
145 | if (child == node) | 145 | if (child == node) |
146 | return phy_provider; | 146 | return phy_provider; |
147 | } | 147 | } |
@@ -811,24 +811,59 @@ EXPORT_SYMBOL_GPL(devm_phy_destroy); | |||
811 | /** | 811 | /** |
812 | * __of_phy_provider_register() - create/register phy provider with the framework | 812 | * __of_phy_provider_register() - create/register phy provider with the framework |
813 | * @dev: struct device of the phy provider | 813 | * @dev: struct device of the phy provider |
814 | * @children: device node containing children (if different from dev->of_node) | ||
814 | * @owner: the module owner containing of_xlate | 815 | * @owner: the module owner containing of_xlate |
815 | * @of_xlate: function pointer to obtain phy instance from phy provider | 816 | * @of_xlate: function pointer to obtain phy instance from phy provider |
816 | * | 817 | * |
817 | * Creates struct phy_provider from dev and of_xlate function pointer. | 818 | * Creates struct phy_provider from dev and of_xlate function pointer. |
818 | * This is used in the case of dt boot for finding the phy instance from | 819 | * This is used in the case of dt boot for finding the phy instance from |
819 | * phy provider. | 820 | * phy provider. |
821 | * | ||
822 | * If the PHY provider doesn't nest children directly but uses a separate | ||
823 | * child node to contain the individual children, the @children parameter | ||
824 | * can be used to override the default. If NULL, the default (dev->of_node) | ||
825 | * will be used. If non-NULL, the device node must be a child (or further | ||
826 | * descendant) of dev->of_node. Otherwise an ERR_PTR()-encoded -EINVAL | ||
827 | * error code is returned. | ||
820 | */ | 828 | */ |
821 | struct phy_provider *__of_phy_provider_register(struct device *dev, | 829 | struct phy_provider *__of_phy_provider_register(struct device *dev, |
822 | struct module *owner, struct phy * (*of_xlate)(struct device *dev, | 830 | struct device_node *children, struct module *owner, |
823 | struct of_phandle_args *args)) | 831 | struct phy * (*of_xlate)(struct device *dev, |
832 | struct of_phandle_args *args)) | ||
824 | { | 833 | { |
825 | struct phy_provider *phy_provider; | 834 | struct phy_provider *phy_provider; |
826 | 835 | ||
836 | /* | ||
837 | * If specified, the device node containing the children must itself | ||
838 | * be the provider's device node or a child (or further descendant) | ||
839 | * thereof. | ||
840 | */ | ||
841 | if (children) { | ||
842 | struct device_node *parent = of_node_get(children), *next; | ||
843 | |||
844 | while (parent) { | ||
845 | if (parent == dev->of_node) | ||
846 | break; | ||
847 | |||
848 | next = of_get_parent(parent); | ||
849 | of_node_put(parent); | ||
850 | parent = next; | ||
851 | } | ||
852 | |||
853 | if (!parent) | ||
854 | return ERR_PTR(-EINVAL); | ||
855 | |||
856 | of_node_put(parent); | ||
857 | } else { | ||
858 | children = dev->of_node; | ||
859 | } | ||
860 | |||
827 | phy_provider = kzalloc(sizeof(*phy_provider), GFP_KERNEL); | 861 | phy_provider = kzalloc(sizeof(*phy_provider), GFP_KERNEL); |
828 | if (!phy_provider) | 862 | if (!phy_provider) |
829 | return ERR_PTR(-ENOMEM); | 863 | return ERR_PTR(-ENOMEM); |
830 | 864 | ||
831 | phy_provider->dev = dev; | 865 | phy_provider->dev = dev; |
866 | phy_provider->children = of_node_get(children); | ||
832 | phy_provider->owner = owner; | 867 | phy_provider->owner = owner; |
833 | phy_provider->of_xlate = of_xlate; | 868 | phy_provider->of_xlate = of_xlate; |
834 | 869 | ||
@@ -854,8 +889,9 @@ EXPORT_SYMBOL_GPL(__of_phy_provider_register); | |||
854 | * on the devres data, then, devres data is freed. | 889 | * on the devres data, then, devres data is freed. |
855 | */ | 890 | */ |
856 | struct phy_provider *__devm_of_phy_provider_register(struct device *dev, | 891 | struct phy_provider *__devm_of_phy_provider_register(struct device *dev, |
857 | struct module *owner, struct phy * (*of_xlate)(struct device *dev, | 892 | struct device_node *children, struct module *owner, |
858 | struct of_phandle_args *args)) | 893 | struct phy * (*of_xlate)(struct device *dev, |
894 | struct of_phandle_args *args)) | ||
859 | { | 895 | { |
860 | struct phy_provider **ptr, *phy_provider; | 896 | struct phy_provider **ptr, *phy_provider; |
861 | 897 | ||
@@ -863,7 +899,8 @@ struct phy_provider *__devm_of_phy_provider_register(struct device *dev, | |||
863 | if (!ptr) | 899 | if (!ptr) |
864 | return ERR_PTR(-ENOMEM); | 900 | return ERR_PTR(-ENOMEM); |
865 | 901 | ||
866 | phy_provider = __of_phy_provider_register(dev, owner, of_xlate); | 902 | phy_provider = __of_phy_provider_register(dev, children, owner, |
903 | of_xlate); | ||
867 | if (!IS_ERR(phy_provider)) { | 904 | if (!IS_ERR(phy_provider)) { |
868 | *ptr = phy_provider; | 905 | *ptr = phy_provider; |
869 | devres_add(dev, ptr); | 906 | devres_add(dev, ptr); |
@@ -888,6 +925,7 @@ void of_phy_provider_unregister(struct phy_provider *phy_provider) | |||
888 | 925 | ||
889 | mutex_lock(&phy_provider_mutex); | 926 | mutex_lock(&phy_provider_mutex); |
890 | list_del(&phy_provider->list); | 927 | list_del(&phy_provider->list); |
928 | of_node_put(phy_provider->children); | ||
891 | kfree(phy_provider); | 929 | kfree(phy_provider); |
892 | mutex_unlock(&phy_provider_mutex); | 930 | mutex_unlock(&phy_provider_mutex); |
893 | } | 931 | } |
diff --git a/drivers/phy/tegra/Kconfig b/drivers/phy/tegra/Kconfig new file mode 100644 index 000000000000..a3b1de953fb7 --- /dev/null +++ b/drivers/phy/tegra/Kconfig | |||
@@ -0,0 +1,8 @@ | |||
1 | config PHY_TEGRA_XUSB | ||
2 | tristate "NVIDIA Tegra XUSB pad controller driver" | ||
3 | depends on ARCH_TEGRA | ||
4 | help | ||
5 | Choose this option if you have an NVIDIA Tegra SoC. | ||
6 | |||
7 | To compile this driver as a module, choose M here: the module will | ||
8 | be called phy-tegra-xusb. | ||
diff --git a/drivers/phy/tegra/Makefile b/drivers/phy/tegra/Makefile new file mode 100644 index 000000000000..898589238fd9 --- /dev/null +++ b/drivers/phy/tegra/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | obj-$(CONFIG_PHY_TEGRA_XUSB) += phy-tegra-xusb.o | ||
2 | |||
3 | phy-tegra-xusb-y += xusb.o | ||
4 | phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_124_SOC) += xusb-tegra124.o | ||
5 | phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_132_SOC) += xusb-tegra124.o | ||
6 | phy-tegra-xusb-$(CONFIG_ARCH_TEGRA_210_SOC) += xusb-tegra210.o | ||
diff --git a/drivers/phy/tegra/xusb-tegra124.c b/drivers/phy/tegra/xusb-tegra124.c new file mode 100644 index 000000000000..119957249a51 --- /dev/null +++ b/drivers/phy/tegra/xusb-tegra124.c | |||
@@ -0,0 +1,1752 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/delay.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/mailbox_client.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/phy/phy.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/regulator/consumer.h> | ||
22 | #include <linux/reset.h> | ||
23 | #include <linux/slab.h> | ||
24 | |||
25 | #include <soc/tegra/fuse.h> | ||
26 | |||
27 | #include "xusb.h" | ||
28 | |||
29 | #define FUSE_SKU_CALIB_HS_CURR_LEVEL_PADX_SHIFT(x) ((x) ? 15 : 0) | ||
30 | #define FUSE_SKU_CALIB_HS_CURR_LEVEL_PAD_MASK 0x3f | ||
31 | #define FUSE_SKU_CALIB_HS_IREF_CAP_SHIFT 13 | ||
32 | #define FUSE_SKU_CALIB_HS_IREF_CAP_MASK 0x3 | ||
33 | #define FUSE_SKU_CALIB_HS_SQUELCH_LEVEL_SHIFT 11 | ||
34 | #define FUSE_SKU_CALIB_HS_SQUELCH_LEVEL_MASK 0x3 | ||
35 | #define FUSE_SKU_CALIB_HS_TERM_RANGE_ADJ_SHIFT 7 | ||
36 | #define FUSE_SKU_CALIB_HS_TERM_RANGE_ADJ_MASK 0xf | ||
37 | |||
38 | #define XUSB_PADCTL_USB2_PORT_CAP 0x008 | ||
39 | #define XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_SHIFT(x) ((x) * 4) | ||
40 | #define XUSB_PADCTL_USB2_PORT_CAP_PORT_CAP_MASK 0x3 | ||
41 | #define XUSB_PADCTL_USB2_PORT_CAP_DISABLED 0x0 | ||
42 | #define XUSB_PADCTL_USB2_PORT_CAP_HOST 0x1 | ||
43 | #define XUSB_PADCTL_USB2_PORT_CAP_DEVICE 0x2 | ||
44 | #define XUSB_PADCTL_USB2_PORT_CAP_OTG 0x3 | ||
45 | |||
46 | #define XUSB_PADCTL_SS_PORT_MAP 0x014 | ||
47 | #define XUSB_PADCTL_SS_PORT_MAP_PORTX_INTERNAL(x) (1 << (((x) * 4) + 3)) | ||
48 | #define XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_SHIFT(x) ((x) * 4) | ||
49 | #define XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_MASK(x) (0x7 << ((x) * 4)) | ||
50 | #define XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP(x, v) (((v) & 0x7) << ((x) * 4)) | ||
51 | #define XUSB_PADCTL_SS_PORT_MAP_PORT_MAP_MASK 0x7 | ||
52 | |||
53 | #define XUSB_PADCTL_ELPG_PROGRAM 0x01c | ||
54 | #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 26) | ||
55 | #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 25) | ||
56 | #define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN (1 << 24) | ||
57 | #define XUSB_PADCTL_ELPG_PROGRAM_SSPX_ELPG_VCORE_DOWN(x) (1 << (18 + (x) * 4)) | ||
58 | #define XUSB_PADCTL_ELPG_PROGRAM_SSPX_ELPG_CLAMP_EN_EARLY(x) \ | ||
59 | (1 << (17 + (x) * 4)) | ||
60 | #define XUSB_PADCTL_ELPG_PROGRAM_SSPX_ELPG_CLAMP_EN(x) (1 << (16 + (x) * 4)) | ||
61 | |||
62 | #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1 0x040 | ||
63 | #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET (1 << 19) | ||
64 | #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK (0xf << 12) | ||
65 | #define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST (1 << 1) | ||
66 | |||
67 | #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2 0x044 | ||
68 | #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN (1 << 6) | ||
69 | #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN (1 << 5) | ||
70 | #define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL (1 << 4) | ||
71 | |||
72 | #define XUSB_PADCTL_IOPHY_USB3_PADX_CTL2(x) (0x058 + (x) * 4) | ||
73 | #define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_CDR_CNTL_SHIFT 24 | ||
74 | #define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_CDR_CNTL_MASK 0xff | ||
75 | #define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_CDR_CNTL_VAL 0x24 | ||
76 | #define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_Z_SHIFT 16 | ||
77 | #define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_Z_MASK 0x3f | ||
78 | #define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_G_SHIFT 8 | ||
79 | #define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_G_MASK 0x3f | ||
80 | #define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_SHIFT 8 | ||
81 | #define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_MASK 0xffff | ||
82 | #define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_VAL 0xf070 | ||
83 | #define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_WANDER_SHIFT 4 | ||
84 | #define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_WANDER_MASK 0xf | ||
85 | #define XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_WANDER_VAL 0xf | ||
86 | |||
87 | #define XUSB_PADCTL_IOPHY_USB3_PADX_CTL4(x) (0x068 + (x) * 4) | ||
88 | #define XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_TAP_SHIFT 24 | ||
89 | #define XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_TAP_MASK 0x1f | ||
90 | #define XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_AMP_SHIFT 16 | ||
91 | #define XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_AMP_MASK 0x7f | ||
92 | #define XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_VAL 0x002008ee | ||
93 | |||
94 | #define XUSB_PADCTL_IOPHY_MISC_PAD_PX_CTL2(x) ((x) < 2 ? 0x078 + (x) * 4 : \ | ||
95 | 0x0f8 + (x) * 4) | ||
96 | #define XUSB_PADCTL_IOPHY_MISC_PAD_CTL2_SPARE_IN_SHIFT 28 | ||
97 | #define XUSB_PADCTL_IOPHY_MISC_PAD_CTL2_SPARE_IN_MASK 0x3 | ||
98 | #define XUSB_PADCTL_IOPHY_MISC_PAD_CTL2_SPARE_IN_VAL 0x1 | ||
99 | |||
100 | #define XUSB_PADCTL_IOPHY_MISC_PAD_PX_CTL5(x) ((x) < 2 ? 0x090 + (x) * 4 : \ | ||
101 | 0x11c + (x) * 4) | ||
102 | #define XUSB_PADCTL_IOPHY_MISC_PAD_CTL5_RX_QEYE_EN (1 << 8) | ||
103 | |||
104 | #define XUSB_PADCTL_IOPHY_MISC_PAD_PX_CTL6(x) ((x) < 2 ? 0x098 + (x) * 4 : \ | ||
105 | 0x128 + (x) * 4) | ||
106 | #define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SHIFT 24 | ||
107 | #define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_G_Z_MASK 0x3f | ||
108 | #define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_TAP_MASK 0x1f | ||
109 | #define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_AMP_MASK 0x7f | ||
110 | #define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT 16 | ||
111 | #define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_MASK 0xff | ||
112 | #define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_G_Z 0x21 | ||
113 | #define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_TAP 0x32 | ||
114 | #define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_AMP 0x33 | ||
115 | #define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_CTLE_Z 0x48 | ||
116 | #define XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_LATCH_G_Z 0xa1 | ||
117 | |||
118 | #define XUSB_PADCTL_USB2_OTG_PADX_CTL0(x) (0x0a0 + (x) * 4) | ||
119 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD_ZI (1 << 21) | ||
120 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD2 (1 << 20) | ||
121 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD (1 << 19) | ||
122 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL0_LS_RSLEW_SHIFT 14 | ||
123 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL0_LS_RSLEW_MASK 0x3 | ||
124 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL0_LS_RSLEW_VAL(x) ((x) ? 0x0 : 0x3) | ||
125 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_SLEW_SHIFT 6 | ||
126 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_SLEW_MASK 0x3f | ||
127 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_SLEW_VAL 0x0e | ||
128 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_SHIFT 0 | ||
129 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_MASK 0x3f | ||
130 | |||
131 | #define XUSB_PADCTL_USB2_OTG_PADX_CTL1(x) (0x0ac + (x) * 4) | ||
132 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL1_HS_IREF_CAP_SHIFT 9 | ||
133 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL1_HS_IREF_CAP_MASK 0x3 | ||
134 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_SHIFT 3 | ||
135 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_MASK 0x7 | ||
136 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_DR (1 << 2) | ||
137 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_DISC_FORCE_POWERUP (1 << 1) | ||
138 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_CHRP_FORCE_POWERUP (1 << 0) | ||
139 | |||
140 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL0 0x0b8 | ||
141 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_PD (1 << 12) | ||
142 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_SHIFT 2 | ||
143 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_MASK 0x7 | ||
144 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_VAL 0x5 | ||
145 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_SHIFT 0 | ||
146 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_MASK 0x3 | ||
147 | |||
148 | #define XUSB_PADCTL_HSIC_PADX_CTL0(x) (0x0c0 + (x) * 4) | ||
149 | #define XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWN_SHIFT 12 | ||
150 | #define XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWN_MASK 0x7 | ||
151 | #define XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWP_SHIFT 8 | ||
152 | #define XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWP_MASK 0x7 | ||
153 | #define XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEN_SHIFT 4 | ||
154 | #define XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEN_MASK 0x7 | ||
155 | #define XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEP_SHIFT 0 | ||
156 | #define XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEP_MASK 0x7 | ||
157 | |||
158 | #define XUSB_PADCTL_HSIC_PADX_CTL1(x) (0x0c8 + (x) * 4) | ||
159 | #define XUSB_PADCTL_HSIC_PAD_CTL1_RPU_STROBE (1 << 10) | ||
160 | #define XUSB_PADCTL_HSIC_PAD_CTL1_RPU_DATA (1 << 9) | ||
161 | #define XUSB_PADCTL_HSIC_PAD_CTL1_RPD_STROBE (1 << 8) | ||
162 | #define XUSB_PADCTL_HSIC_PAD_CTL1_RPD_DATA (1 << 7) | ||
163 | #define XUSB_PADCTL_HSIC_PAD_CTL1_PD_ZI (1 << 5) | ||
164 | #define XUSB_PADCTL_HSIC_PAD_CTL1_PD_RX (1 << 4) | ||
165 | #define XUSB_PADCTL_HSIC_PAD_CTL1_PD_TRX (1 << 3) | ||
166 | #define XUSB_PADCTL_HSIC_PAD_CTL1_PD_TX (1 << 2) | ||
167 | #define XUSB_PADCTL_HSIC_PAD_CTL1_AUTO_TERM_EN (1 << 0) | ||
168 | |||
169 | #define XUSB_PADCTL_HSIC_PADX_CTL2(x) (0x0d0 + (x) * 4) | ||
170 | #define XUSB_PADCTL_HSIC_PAD_CTL2_RX_STROBE_TRIM_SHIFT 4 | ||
171 | #define XUSB_PADCTL_HSIC_PAD_CTL2_RX_STROBE_TRIM_MASK 0x7 | ||
172 | #define XUSB_PADCTL_HSIC_PAD_CTL2_RX_DATA_TRIM_SHIFT 0 | ||
173 | #define XUSB_PADCTL_HSIC_PAD_CTL2_RX_DATA_TRIM_MASK 0x7 | ||
174 | |||
175 | #define XUSB_PADCTL_HSIC_STRB_TRIM_CONTROL 0x0e0 | ||
176 | #define XUSB_PADCTL_HSIC_STRB_TRIM_CONTROL_STRB_TRIM_MASK 0x1f | ||
177 | |||
178 | #define XUSB_PADCTL_USB3_PAD_MUX 0x134 | ||
179 | #define XUSB_PADCTL_USB3_PAD_MUX_PCIE_IDDQ_DISABLE(x) (1 << (1 + (x))) | ||
180 | #define XUSB_PADCTL_USB3_PAD_MUX_SATA_IDDQ_DISABLE(x) (1 << (6 + (x))) | ||
181 | |||
182 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1 0x138 | ||
183 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET (1 << 27) | ||
184 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE (1 << 24) | ||
185 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL0_REFCLK_NDIV_SHIFT 20 | ||
186 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL0_REFCLK_NDIV_MASK 0x3 | ||
187 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD (1 << 3) | ||
188 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST (1 << 1) | ||
189 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ (1 << 0) | ||
190 | |||
191 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL2 0x13c | ||
192 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL1_CP_CNTL_SHIFT 20 | ||
193 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL1_CP_CNTL_MASK 0xf | ||
194 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL0_CP_CNTL_SHIFT 16 | ||
195 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL0_CP_CNTL_MASK 0xf | ||
196 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL2_TCLKOUT_EN (1 << 12) | ||
197 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL2_TXCLKREF_SEL (1 << 4) | ||
198 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL2_XDIGCLK_SEL_SHIFT 0 | ||
199 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL2_XDIGCLK_SEL_MASK 0x7 | ||
200 | |||
201 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL3 0x140 | ||
202 | #define XUSB_PADCTL_IOPHY_PLL_S0_CTL3_RCAL_BYPASS (1 << 7) | ||
203 | |||
204 | #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1 0x148 | ||
205 | #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD (1 << 1) | ||
206 | #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ (1 << 0) | ||
207 | |||
208 | #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL2 0x14c | ||
209 | |||
210 | #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL5 0x158 | ||
211 | |||
212 | #define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL6 0x15c | ||
213 | |||
214 | struct tegra124_xusb_fuse_calibration { | ||
215 | u32 hs_curr_level[3]; | ||
216 | u32 hs_iref_cap; | ||
217 | u32 hs_term_range_adj; | ||
218 | u32 hs_squelch_level; | ||
219 | }; | ||
220 | |||
221 | struct tegra124_xusb_padctl { | ||
222 | struct tegra_xusb_padctl base; | ||
223 | |||
224 | struct tegra124_xusb_fuse_calibration fuse; | ||
225 | }; | ||
226 | |||
227 | static inline struct tegra124_xusb_padctl * | ||
228 | to_tegra124_xusb_padctl(struct tegra_xusb_padctl *padctl) | ||
229 | { | ||
230 | return container_of(padctl, struct tegra124_xusb_padctl, base); | ||
231 | } | ||
232 | |||
233 | static int tegra124_xusb_padctl_enable(struct tegra_xusb_padctl *padctl) | ||
234 | { | ||
235 | u32 value; | ||
236 | |||
237 | mutex_lock(&padctl->lock); | ||
238 | |||
239 | if (padctl->enable++ > 0) | ||
240 | goto out; | ||
241 | |||
242 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); | ||
243 | value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN; | ||
244 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); | ||
245 | |||
246 | usleep_range(100, 200); | ||
247 | |||
248 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); | ||
249 | value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY; | ||
250 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); | ||
251 | |||
252 | usleep_range(100, 200); | ||
253 | |||
254 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); | ||
255 | value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN; | ||
256 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); | ||
257 | |||
258 | out: | ||
259 | mutex_unlock(&padctl->lock); | ||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | static int tegra124_xusb_padctl_disable(struct tegra_xusb_padctl *padctl) | ||
264 | { | ||
265 | u32 value; | ||
266 | |||
267 | mutex_lock(&padctl->lock); | ||
268 | |||
269 | if (WARN_ON(padctl->enable == 0)) | ||
270 | goto out; | ||
271 | |||
272 | if (--padctl->enable > 0) | ||
273 | goto out; | ||
274 | |||
275 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); | ||
276 | value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN; | ||
277 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); | ||
278 | |||
279 | usleep_range(100, 200); | ||
280 | |||
281 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); | ||
282 | value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY; | ||
283 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); | ||
284 | |||
285 | usleep_range(100, 200); | ||
286 | |||
287 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); | ||
288 | value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN; | ||
289 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); | ||
290 | |||
291 | out: | ||
292 | mutex_unlock(&padctl->lock); | ||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | static int tegra124_usb3_save_context(struct tegra_xusb_padctl *padctl, | ||
297 | unsigned int index) | ||
298 | { | ||
299 | struct tegra_xusb_usb3_port *port; | ||
300 | struct tegra_xusb_lane *lane; | ||
301 | u32 value, offset; | ||
302 | |||
303 | port = tegra_xusb_find_usb3_port(padctl, index); | ||
304 | if (!port) | ||
305 | return -ENODEV; | ||
306 | |||
307 | port->context_saved = true; | ||
308 | lane = port->base.lane; | ||
309 | |||
310 | if (lane->pad == padctl->pcie) | ||
311 | offset = XUSB_PADCTL_IOPHY_MISC_PAD_PX_CTL6(lane->index); | ||
312 | else | ||
313 | offset = XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL6; | ||
314 | |||
315 | value = padctl_readl(padctl, offset); | ||
316 | value &= ~(XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_MASK << | ||
317 | XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT); | ||
318 | value |= XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_TAP << | ||
319 | XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT; | ||
320 | padctl_writel(padctl, value, offset); | ||
321 | |||
322 | value = padctl_readl(padctl, offset) >> | ||
323 | XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SHIFT; | ||
324 | port->tap1 = value & XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_TAP_MASK; | ||
325 | |||
326 | value = padctl_readl(padctl, offset); | ||
327 | value &= ~(XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_MASK << | ||
328 | XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT); | ||
329 | value |= XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_AMP << | ||
330 | XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT; | ||
331 | padctl_writel(padctl, value, offset); | ||
332 | |||
333 | value = padctl_readl(padctl, offset) >> | ||
334 | XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SHIFT; | ||
335 | port->amp = value & XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_AMP_MASK; | ||
336 | |||
337 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_USB3_PADX_CTL4(index)); | ||
338 | value &= ~((XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_TAP_MASK << | ||
339 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_TAP_SHIFT) | | ||
340 | (XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_AMP_MASK << | ||
341 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_AMP_SHIFT)); | ||
342 | value |= (port->tap1 << | ||
343 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_TAP_SHIFT) | | ||
344 | (port->amp << | ||
345 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_AMP_SHIFT); | ||
346 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_USB3_PADX_CTL4(index)); | ||
347 | |||
348 | value = padctl_readl(padctl, offset); | ||
349 | value &= ~(XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_MASK << | ||
350 | XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT); | ||
351 | value |= XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_LATCH_G_Z << | ||
352 | XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT; | ||
353 | padctl_writel(padctl, value, offset); | ||
354 | |||
355 | value = padctl_readl(padctl, offset); | ||
356 | value &= ~(XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_MASK << | ||
357 | XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT); | ||
358 | value |= XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_G_Z << | ||
359 | XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT; | ||
360 | padctl_writel(padctl, value, offset); | ||
361 | |||
362 | value = padctl_readl(padctl, offset) >> | ||
363 | XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SHIFT; | ||
364 | port->ctle_g = value & | ||
365 | XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_G_Z_MASK; | ||
366 | |||
367 | value = padctl_readl(padctl, offset); | ||
368 | value &= ~(XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_MASK << | ||
369 | XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT); | ||
370 | value |= XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_CTLE_Z << | ||
371 | XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SEL_SHIFT; | ||
372 | padctl_writel(padctl, value, offset); | ||
373 | |||
374 | value = padctl_readl(padctl, offset) >> | ||
375 | XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_SHIFT; | ||
376 | port->ctle_z = value & | ||
377 | XUSB_PADCTL_IOPHY_MISC_PAD_CTL6_MISC_OUT_G_Z_MASK; | ||
378 | |||
379 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_USB3_PADX_CTL2(index)); | ||
380 | value &= ~((XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_G_MASK << | ||
381 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_G_SHIFT) | | ||
382 | (XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_Z_MASK << | ||
383 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_Z_SHIFT)); | ||
384 | value |= (port->ctle_g << | ||
385 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_G_SHIFT) | | ||
386 | (port->ctle_z << | ||
387 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_Z_SHIFT); | ||
388 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_USB3_PADX_CTL2(index)); | ||
389 | |||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | static int tegra124_hsic_set_idle(struct tegra_xusb_padctl *padctl, | ||
394 | unsigned int index, bool idle) | ||
395 | { | ||
396 | u32 value; | ||
397 | |||
398 | value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL1(index)); | ||
399 | |||
400 | if (idle) | ||
401 | value |= XUSB_PADCTL_HSIC_PAD_CTL1_RPD_DATA | | ||
402 | XUSB_PADCTL_HSIC_PAD_CTL1_RPU_STROBE; | ||
403 | else | ||
404 | value &= ~(XUSB_PADCTL_HSIC_PAD_CTL1_RPD_DATA | | ||
405 | XUSB_PADCTL_HSIC_PAD_CTL1_RPU_STROBE); | ||
406 | |||
407 | padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL1(index)); | ||
408 | |||
409 | return 0; | ||
410 | } | ||
411 | |||
412 | #define TEGRA124_LANE(_name, _offset, _shift, _mask, _type) \ | ||
413 | { \ | ||
414 | .name = _name, \ | ||
415 | .offset = _offset, \ | ||
416 | .shift = _shift, \ | ||
417 | .mask = _mask, \ | ||
418 | .num_funcs = ARRAY_SIZE(tegra124_##_type##_functions), \ | ||
419 | .funcs = tegra124_##_type##_functions, \ | ||
420 | } | ||
421 | |||
422 | static const char * const tegra124_usb2_functions[] = { | ||
423 | "snps", | ||
424 | "xusb", | ||
425 | "uart", | ||
426 | }; | ||
427 | |||
428 | static const struct tegra_xusb_lane_soc tegra124_usb2_lanes[] = { | ||
429 | TEGRA124_LANE("usb2-0", 0x004, 0, 0x3, usb2), | ||
430 | TEGRA124_LANE("usb2-1", 0x004, 2, 0x3, usb2), | ||
431 | TEGRA124_LANE("usb2-2", 0x004, 4, 0x3, usb2), | ||
432 | }; | ||
433 | |||
434 | static struct tegra_xusb_lane * | ||
435 | tegra124_usb2_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, | ||
436 | unsigned int index) | ||
437 | { | ||
438 | struct tegra_xusb_usb2_lane *usb2; | ||
439 | int err; | ||
440 | |||
441 | usb2 = kzalloc(sizeof(*usb2), GFP_KERNEL); | ||
442 | if (!usb2) | ||
443 | return ERR_PTR(-ENOMEM); | ||
444 | |||
445 | INIT_LIST_HEAD(&usb2->base.list); | ||
446 | usb2->base.soc = &pad->soc->lanes[index]; | ||
447 | usb2->base.index = index; | ||
448 | usb2->base.pad = pad; | ||
449 | usb2->base.np = np; | ||
450 | |||
451 | err = tegra_xusb_lane_parse_dt(&usb2->base, np); | ||
452 | if (err < 0) { | ||
453 | kfree(usb2); | ||
454 | return ERR_PTR(err); | ||
455 | } | ||
456 | |||
457 | return &usb2->base; | ||
458 | } | ||
459 | |||
460 | static void tegra124_usb2_lane_remove(struct tegra_xusb_lane *lane) | ||
461 | { | ||
462 | struct tegra_xusb_usb2_lane *usb2 = to_usb2_lane(lane); | ||
463 | |||
464 | kfree(usb2); | ||
465 | } | ||
466 | |||
467 | static const struct tegra_xusb_lane_ops tegra124_usb2_lane_ops = { | ||
468 | .probe = tegra124_usb2_lane_probe, | ||
469 | .remove = tegra124_usb2_lane_remove, | ||
470 | }; | ||
471 | |||
472 | static int tegra124_usb2_phy_init(struct phy *phy) | ||
473 | { | ||
474 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
475 | |||
476 | return tegra124_xusb_padctl_enable(lane->pad->padctl); | ||
477 | } | ||
478 | |||
479 | static int tegra124_usb2_phy_exit(struct phy *phy) | ||
480 | { | ||
481 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
482 | |||
483 | return tegra124_xusb_padctl_disable(lane->pad->padctl); | ||
484 | } | ||
485 | |||
486 | static int tegra124_usb2_phy_power_on(struct phy *phy) | ||
487 | { | ||
488 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
489 | struct tegra_xusb_usb2_lane *usb2 = to_usb2_lane(lane); | ||
490 | struct tegra_xusb_usb2_pad *pad = to_usb2_pad(lane->pad); | ||
491 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
492 | struct tegra124_xusb_padctl *priv; | ||
493 | struct tegra_xusb_usb2_port *port; | ||
494 | unsigned int index = lane->index; | ||
495 | u32 value; | ||
496 | int err; | ||
497 | |||
498 | port = tegra_xusb_find_usb2_port(padctl, index); | ||
499 | if (!port) { | ||
500 | dev_err(&phy->dev, "no port found for USB2 lane %u\n", index); | ||
501 | return -ENODEV; | ||
502 | } | ||
503 | |||
504 | priv = to_tegra124_xusb_padctl(padctl); | ||
505 | |||
506 | value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); | ||
507 | value &= ~((XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_MASK << | ||
508 | XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_SHIFT) | | ||
509 | (XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_MASK << | ||
510 | XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_SHIFT)); | ||
511 | value |= (priv->fuse.hs_squelch_level << | ||
512 | XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_SHIFT) | | ||
513 | (XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_VAL << | ||
514 | XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_SHIFT); | ||
515 | padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); | ||
516 | |||
517 | value = padctl_readl(padctl, XUSB_PADCTL_USB2_PORT_CAP); | ||
518 | value &= ~(XUSB_PADCTL_USB2_PORT_CAP_PORT_CAP_MASK << | ||
519 | XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_SHIFT(index)); | ||
520 | value |= XUSB_PADCTL_USB2_PORT_CAP_HOST << | ||
521 | XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_SHIFT(index); | ||
522 | padctl_writel(padctl, value, XUSB_PADCTL_USB2_PORT_CAP); | ||
523 | |||
524 | value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index)); | ||
525 | value &= ~((XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_MASK << | ||
526 | XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_SHIFT) | | ||
527 | (XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_SLEW_MASK << | ||
528 | XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_SLEW_SHIFT) | | ||
529 | (XUSB_PADCTL_USB2_OTG_PAD_CTL0_LS_RSLEW_MASK << | ||
530 | XUSB_PADCTL_USB2_OTG_PAD_CTL0_LS_RSLEW_SHIFT) | | ||
531 | XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD | | ||
532 | XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD2 | | ||
533 | XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD_ZI); | ||
534 | value |= (priv->fuse.hs_curr_level[index] + | ||
535 | usb2->hs_curr_level_offset) << | ||
536 | XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_SHIFT; | ||
537 | value |= XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_SLEW_VAL << | ||
538 | XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_SLEW_SHIFT; | ||
539 | value |= XUSB_PADCTL_USB2_OTG_PAD_CTL0_LS_RSLEW_VAL(index) << | ||
540 | XUSB_PADCTL_USB2_OTG_PAD_CTL0_LS_RSLEW_SHIFT; | ||
541 | padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index)); | ||
542 | |||
543 | value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index)); | ||
544 | value &= ~((XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_MASK << | ||
545 | XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_SHIFT) | | ||
546 | (XUSB_PADCTL_USB2_OTG_PAD_CTL1_HS_IREF_CAP_MASK << | ||
547 | XUSB_PADCTL_USB2_OTG_PAD_CTL1_HS_IREF_CAP_SHIFT) | | ||
548 | XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_DR | | ||
549 | XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_CHRP_FORCE_POWERUP | | ||
550 | XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_DISC_FORCE_POWERUP); | ||
551 | value |= (priv->fuse.hs_term_range_adj << | ||
552 | XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_SHIFT) | | ||
553 | (priv->fuse.hs_iref_cap << | ||
554 | XUSB_PADCTL_USB2_OTG_PAD_CTL1_HS_IREF_CAP_SHIFT); | ||
555 | padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index)); | ||
556 | |||
557 | err = regulator_enable(port->supply); | ||
558 | if (err) | ||
559 | return err; | ||
560 | |||
561 | mutex_lock(&pad->lock); | ||
562 | |||
563 | if (pad->enable++ > 0) | ||
564 | goto out; | ||
565 | |||
566 | value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); | ||
567 | value &= ~XUSB_PADCTL_USB2_BIAS_PAD_CTL0_PD; | ||
568 | padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); | ||
569 | |||
570 | out: | ||
571 | mutex_unlock(&pad->lock); | ||
572 | return 0; | ||
573 | } | ||
574 | |||
575 | static int tegra124_usb2_phy_power_off(struct phy *phy) | ||
576 | { | ||
577 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
578 | struct tegra_xusb_usb2_pad *pad = to_usb2_pad(lane->pad); | ||
579 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
580 | struct tegra_xusb_usb2_port *port; | ||
581 | u32 value; | ||
582 | |||
583 | port = tegra_xusb_find_usb2_port(padctl, lane->index); | ||
584 | if (!port) { | ||
585 | dev_err(&phy->dev, "no port found for USB2 lane %u\n", | ||
586 | lane->index); | ||
587 | return -ENODEV; | ||
588 | } | ||
589 | |||
590 | mutex_lock(&pad->lock); | ||
591 | |||
592 | if (WARN_ON(pad->enable == 0)) | ||
593 | goto out; | ||
594 | |||
595 | if (--pad->enable > 0) | ||
596 | goto out; | ||
597 | |||
598 | value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); | ||
599 | value |= XUSB_PADCTL_USB2_BIAS_PAD_CTL0_PD; | ||
600 | padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); | ||
601 | |||
602 | out: | ||
603 | regulator_disable(port->supply); | ||
604 | mutex_unlock(&pad->lock); | ||
605 | return 0; | ||
606 | } | ||
607 | |||
608 | static const struct phy_ops tegra124_usb2_phy_ops = { | ||
609 | .init = tegra124_usb2_phy_init, | ||
610 | .exit = tegra124_usb2_phy_exit, | ||
611 | .power_on = tegra124_usb2_phy_power_on, | ||
612 | .power_off = tegra124_usb2_phy_power_off, | ||
613 | .owner = THIS_MODULE, | ||
614 | }; | ||
615 | |||
616 | static struct tegra_xusb_pad * | ||
617 | tegra124_usb2_pad_probe(struct tegra_xusb_padctl *padctl, | ||
618 | const struct tegra_xusb_pad_soc *soc, | ||
619 | struct device_node *np) | ||
620 | { | ||
621 | struct tegra_xusb_usb2_pad *usb2; | ||
622 | struct tegra_xusb_pad *pad; | ||
623 | int err; | ||
624 | |||
625 | usb2 = kzalloc(sizeof(*usb2), GFP_KERNEL); | ||
626 | if (!usb2) | ||
627 | return ERR_PTR(-ENOMEM); | ||
628 | |||
629 | mutex_init(&usb2->lock); | ||
630 | |||
631 | pad = &usb2->base; | ||
632 | pad->ops = &tegra124_usb2_lane_ops; | ||
633 | pad->soc = soc; | ||
634 | |||
635 | err = tegra_xusb_pad_init(pad, padctl, np); | ||
636 | if (err < 0) { | ||
637 | kfree(usb2); | ||
638 | goto out; | ||
639 | } | ||
640 | |||
641 | err = tegra_xusb_pad_register(pad, &tegra124_usb2_phy_ops); | ||
642 | if (err < 0) | ||
643 | goto unregister; | ||
644 | |||
645 | dev_set_drvdata(&pad->dev, pad); | ||
646 | |||
647 | return pad; | ||
648 | |||
649 | unregister: | ||
650 | device_unregister(&pad->dev); | ||
651 | out: | ||
652 | return ERR_PTR(err); | ||
653 | } | ||
654 | |||
655 | static void tegra124_usb2_pad_remove(struct tegra_xusb_pad *pad) | ||
656 | { | ||
657 | struct tegra_xusb_usb2_pad *usb2 = to_usb2_pad(pad); | ||
658 | |||
659 | kfree(usb2); | ||
660 | } | ||
661 | |||
662 | static const struct tegra_xusb_pad_ops tegra124_usb2_ops = { | ||
663 | .probe = tegra124_usb2_pad_probe, | ||
664 | .remove = tegra124_usb2_pad_remove, | ||
665 | }; | ||
666 | |||
667 | static const struct tegra_xusb_pad_soc tegra124_usb2_pad = { | ||
668 | .name = "usb2", | ||
669 | .num_lanes = ARRAY_SIZE(tegra124_usb2_lanes), | ||
670 | .lanes = tegra124_usb2_lanes, | ||
671 | .ops = &tegra124_usb2_ops, | ||
672 | }; | ||
673 | |||
674 | static const char * const tegra124_ulpi_functions[] = { | ||
675 | "snps", | ||
676 | "xusb", | ||
677 | }; | ||
678 | |||
679 | static const struct tegra_xusb_lane_soc tegra124_ulpi_lanes[] = { | ||
680 | TEGRA124_LANE("ulpi-0", 0x004, 12, 0x1, ulpi), | ||
681 | }; | ||
682 | |||
683 | static struct tegra_xusb_lane * | ||
684 | tegra124_ulpi_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, | ||
685 | unsigned int index) | ||
686 | { | ||
687 | struct tegra_xusb_ulpi_lane *ulpi; | ||
688 | int err; | ||
689 | |||
690 | ulpi = kzalloc(sizeof(*ulpi), GFP_KERNEL); | ||
691 | if (!ulpi) | ||
692 | return ERR_PTR(-ENOMEM); | ||
693 | |||
694 | INIT_LIST_HEAD(&ulpi->base.list); | ||
695 | ulpi->base.soc = &pad->soc->lanes[index]; | ||
696 | ulpi->base.index = index; | ||
697 | ulpi->base.pad = pad; | ||
698 | ulpi->base.np = np; | ||
699 | |||
700 | err = tegra_xusb_lane_parse_dt(&ulpi->base, np); | ||
701 | if (err < 0) { | ||
702 | kfree(ulpi); | ||
703 | return ERR_PTR(err); | ||
704 | } | ||
705 | |||
706 | return &ulpi->base; | ||
707 | } | ||
708 | |||
709 | static void tegra124_ulpi_lane_remove(struct tegra_xusb_lane *lane) | ||
710 | { | ||
711 | struct tegra_xusb_ulpi_lane *ulpi = to_ulpi_lane(lane); | ||
712 | |||
713 | kfree(ulpi); | ||
714 | } | ||
715 | |||
716 | static const struct tegra_xusb_lane_ops tegra124_ulpi_lane_ops = { | ||
717 | .probe = tegra124_ulpi_lane_probe, | ||
718 | .remove = tegra124_ulpi_lane_remove, | ||
719 | }; | ||
720 | |||
721 | static int tegra124_ulpi_phy_init(struct phy *phy) | ||
722 | { | ||
723 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
724 | |||
725 | return tegra124_xusb_padctl_enable(lane->pad->padctl); | ||
726 | } | ||
727 | |||
728 | static int tegra124_ulpi_phy_exit(struct phy *phy) | ||
729 | { | ||
730 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
731 | |||
732 | return tegra124_xusb_padctl_disable(lane->pad->padctl); | ||
733 | } | ||
734 | |||
735 | static int tegra124_ulpi_phy_power_on(struct phy *phy) | ||
736 | { | ||
737 | return 0; | ||
738 | } | ||
739 | |||
740 | static int tegra124_ulpi_phy_power_off(struct phy *phy) | ||
741 | { | ||
742 | return 0; | ||
743 | } | ||
744 | |||
745 | static const struct phy_ops tegra124_ulpi_phy_ops = { | ||
746 | .init = tegra124_ulpi_phy_init, | ||
747 | .exit = tegra124_ulpi_phy_exit, | ||
748 | .power_on = tegra124_ulpi_phy_power_on, | ||
749 | .power_off = tegra124_ulpi_phy_power_off, | ||
750 | .owner = THIS_MODULE, | ||
751 | }; | ||
752 | |||
753 | static struct tegra_xusb_pad * | ||
754 | tegra124_ulpi_pad_probe(struct tegra_xusb_padctl *padctl, | ||
755 | const struct tegra_xusb_pad_soc *soc, | ||
756 | struct device_node *np) | ||
757 | { | ||
758 | struct tegra_xusb_ulpi_pad *ulpi; | ||
759 | struct tegra_xusb_pad *pad; | ||
760 | int err; | ||
761 | |||
762 | ulpi = kzalloc(sizeof(*ulpi), GFP_KERNEL); | ||
763 | if (!ulpi) | ||
764 | return ERR_PTR(-ENOMEM); | ||
765 | |||
766 | pad = &ulpi->base; | ||
767 | pad->ops = &tegra124_ulpi_lane_ops; | ||
768 | pad->soc = soc; | ||
769 | |||
770 | err = tegra_xusb_pad_init(pad, padctl, np); | ||
771 | if (err < 0) { | ||
772 | kfree(ulpi); | ||
773 | goto out; | ||
774 | } | ||
775 | |||
776 | err = tegra_xusb_pad_register(pad, &tegra124_ulpi_phy_ops); | ||
777 | if (err < 0) | ||
778 | goto unregister; | ||
779 | |||
780 | dev_set_drvdata(&pad->dev, pad); | ||
781 | |||
782 | return pad; | ||
783 | |||
784 | unregister: | ||
785 | device_unregister(&pad->dev); | ||
786 | out: | ||
787 | return ERR_PTR(err); | ||
788 | } | ||
789 | |||
790 | static void tegra124_ulpi_pad_remove(struct tegra_xusb_pad *pad) | ||
791 | { | ||
792 | struct tegra_xusb_ulpi_pad *ulpi = to_ulpi_pad(pad); | ||
793 | |||
794 | kfree(ulpi); | ||
795 | } | ||
796 | |||
797 | static const struct tegra_xusb_pad_ops tegra124_ulpi_ops = { | ||
798 | .probe = tegra124_ulpi_pad_probe, | ||
799 | .remove = tegra124_ulpi_pad_remove, | ||
800 | }; | ||
801 | |||
802 | static const struct tegra_xusb_pad_soc tegra124_ulpi_pad = { | ||
803 | .name = "ulpi", | ||
804 | .num_lanes = ARRAY_SIZE(tegra124_ulpi_lanes), | ||
805 | .lanes = tegra124_ulpi_lanes, | ||
806 | .ops = &tegra124_ulpi_ops, | ||
807 | }; | ||
808 | |||
809 | static const char * const tegra124_hsic_functions[] = { | ||
810 | "snps", | ||
811 | "xusb", | ||
812 | }; | ||
813 | |||
814 | static const struct tegra_xusb_lane_soc tegra124_hsic_lanes[] = { | ||
815 | TEGRA124_LANE("hsic-0", 0x004, 14, 0x1, hsic), | ||
816 | TEGRA124_LANE("hsic-1", 0x004, 15, 0x1, hsic), | ||
817 | }; | ||
818 | |||
819 | static struct tegra_xusb_lane * | ||
820 | tegra124_hsic_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, | ||
821 | unsigned int index) | ||
822 | { | ||
823 | struct tegra_xusb_hsic_lane *hsic; | ||
824 | int err; | ||
825 | |||
826 | hsic = kzalloc(sizeof(*hsic), GFP_KERNEL); | ||
827 | if (!hsic) | ||
828 | return ERR_PTR(-ENOMEM); | ||
829 | |||
830 | INIT_LIST_HEAD(&hsic->base.list); | ||
831 | hsic->base.soc = &pad->soc->lanes[index]; | ||
832 | hsic->base.index = index; | ||
833 | hsic->base.pad = pad; | ||
834 | hsic->base.np = np; | ||
835 | |||
836 | err = tegra_xusb_lane_parse_dt(&hsic->base, np); | ||
837 | if (err < 0) { | ||
838 | kfree(hsic); | ||
839 | return ERR_PTR(err); | ||
840 | } | ||
841 | |||
842 | return &hsic->base; | ||
843 | } | ||
844 | |||
845 | static void tegra124_hsic_lane_remove(struct tegra_xusb_lane *lane) | ||
846 | { | ||
847 | struct tegra_xusb_hsic_lane *hsic = to_hsic_lane(lane); | ||
848 | |||
849 | kfree(hsic); | ||
850 | } | ||
851 | |||
852 | static const struct tegra_xusb_lane_ops tegra124_hsic_lane_ops = { | ||
853 | .probe = tegra124_hsic_lane_probe, | ||
854 | .remove = tegra124_hsic_lane_remove, | ||
855 | }; | ||
856 | |||
857 | static int tegra124_hsic_phy_init(struct phy *phy) | ||
858 | { | ||
859 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
860 | |||
861 | return tegra124_xusb_padctl_enable(lane->pad->padctl); | ||
862 | } | ||
863 | |||
864 | static int tegra124_hsic_phy_exit(struct phy *phy) | ||
865 | { | ||
866 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
867 | |||
868 | return tegra124_xusb_padctl_disable(lane->pad->padctl); | ||
869 | } | ||
870 | |||
871 | static int tegra124_hsic_phy_power_on(struct phy *phy) | ||
872 | { | ||
873 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
874 | struct tegra_xusb_hsic_lane *hsic = to_hsic_lane(lane); | ||
875 | struct tegra_xusb_hsic_pad *pad = to_hsic_pad(lane->pad); | ||
876 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
877 | unsigned int index = lane->index; | ||
878 | u32 value; | ||
879 | int err; | ||
880 | |||
881 | err = regulator_enable(pad->supply); | ||
882 | if (err) | ||
883 | return err; | ||
884 | |||
885 | padctl_writel(padctl, hsic->strobe_trim, | ||
886 | XUSB_PADCTL_HSIC_STRB_TRIM_CONTROL); | ||
887 | |||
888 | value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL1(index)); | ||
889 | |||
890 | if (hsic->auto_term) | ||
891 | value |= XUSB_PADCTL_HSIC_PAD_CTL1_AUTO_TERM_EN; | ||
892 | else | ||
893 | value &= ~XUSB_PADCTL_HSIC_PAD_CTL1_AUTO_TERM_EN; | ||
894 | |||
895 | padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL1(index)); | ||
896 | |||
897 | value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL0(index)); | ||
898 | value &= ~((XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEN_MASK << | ||
899 | XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEN_SHIFT) | | ||
900 | (XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEP_MASK << | ||
901 | XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEP_SHIFT) | | ||
902 | (XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWN_MASK << | ||
903 | XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWN_SHIFT) | | ||
904 | (XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWP_MASK << | ||
905 | XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWP_SHIFT)); | ||
906 | value |= (hsic->tx_rtune_n << | ||
907 | XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEN_SHIFT) | | ||
908 | (hsic->tx_rtune_p << | ||
909 | XUSB_PADCTL_HSIC_PAD_CTL0_TX_RTUNEP_SHIFT) | | ||
910 | (hsic->tx_rslew_n << | ||
911 | XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWN_SHIFT) | | ||
912 | (hsic->tx_rslew_p << | ||
913 | XUSB_PADCTL_HSIC_PAD_CTL0_TX_RSLEWP_SHIFT); | ||
914 | padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL0(index)); | ||
915 | |||
916 | value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL2(index)); | ||
917 | value &= ~((XUSB_PADCTL_HSIC_PAD_CTL2_RX_STROBE_TRIM_MASK << | ||
918 | XUSB_PADCTL_HSIC_PAD_CTL2_RX_STROBE_TRIM_SHIFT) | | ||
919 | (XUSB_PADCTL_HSIC_PAD_CTL2_RX_DATA_TRIM_MASK << | ||
920 | XUSB_PADCTL_HSIC_PAD_CTL2_RX_DATA_TRIM_SHIFT)); | ||
921 | value |= (hsic->rx_strobe_trim << | ||
922 | XUSB_PADCTL_HSIC_PAD_CTL2_RX_STROBE_TRIM_SHIFT) | | ||
923 | (hsic->rx_data_trim << | ||
924 | XUSB_PADCTL_HSIC_PAD_CTL2_RX_DATA_TRIM_SHIFT); | ||
925 | padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL2(index)); | ||
926 | |||
927 | value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL1(index)); | ||
928 | value &= ~(XUSB_PADCTL_HSIC_PAD_CTL1_RPD_STROBE | | ||
929 | XUSB_PADCTL_HSIC_PAD_CTL1_RPU_DATA | | ||
930 | XUSB_PADCTL_HSIC_PAD_CTL1_PD_RX | | ||
931 | XUSB_PADCTL_HSIC_PAD_CTL1_PD_ZI | | ||
932 | XUSB_PADCTL_HSIC_PAD_CTL1_PD_TRX | | ||
933 | XUSB_PADCTL_HSIC_PAD_CTL1_PD_TX); | ||
934 | value |= XUSB_PADCTL_HSIC_PAD_CTL1_RPD_DATA | | ||
935 | XUSB_PADCTL_HSIC_PAD_CTL1_RPU_STROBE; | ||
936 | padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL1(index)); | ||
937 | |||
938 | return 0; | ||
939 | } | ||
940 | |||
941 | static int tegra124_hsic_phy_power_off(struct phy *phy) | ||
942 | { | ||
943 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
944 | struct tegra_xusb_hsic_pad *pad = to_hsic_pad(lane->pad); | ||
945 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
946 | unsigned int index = lane->index; | ||
947 | u32 value; | ||
948 | |||
949 | value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL1(index)); | ||
950 | value |= XUSB_PADCTL_HSIC_PAD_CTL1_PD_RX | | ||
951 | XUSB_PADCTL_HSIC_PAD_CTL1_PD_ZI | | ||
952 | XUSB_PADCTL_HSIC_PAD_CTL1_PD_TRX | | ||
953 | XUSB_PADCTL_HSIC_PAD_CTL1_PD_TX; | ||
954 | padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL1(index)); | ||
955 | |||
956 | regulator_disable(pad->supply); | ||
957 | |||
958 | return 0; | ||
959 | } | ||
960 | |||
961 | static const struct phy_ops tegra124_hsic_phy_ops = { | ||
962 | .init = tegra124_hsic_phy_init, | ||
963 | .exit = tegra124_hsic_phy_exit, | ||
964 | .power_on = tegra124_hsic_phy_power_on, | ||
965 | .power_off = tegra124_hsic_phy_power_off, | ||
966 | .owner = THIS_MODULE, | ||
967 | }; | ||
968 | |||
969 | static struct tegra_xusb_pad * | ||
970 | tegra124_hsic_pad_probe(struct tegra_xusb_padctl *padctl, | ||
971 | const struct tegra_xusb_pad_soc *soc, | ||
972 | struct device_node *np) | ||
973 | { | ||
974 | struct tegra_xusb_hsic_pad *hsic; | ||
975 | struct tegra_xusb_pad *pad; | ||
976 | int err; | ||
977 | |||
978 | hsic = kzalloc(sizeof(*hsic), GFP_KERNEL); | ||
979 | if (!hsic) | ||
980 | return ERR_PTR(-ENOMEM); | ||
981 | |||
982 | pad = &hsic->base; | ||
983 | pad->ops = &tegra124_hsic_lane_ops; | ||
984 | pad->soc = soc; | ||
985 | |||
986 | err = tegra_xusb_pad_init(pad, padctl, np); | ||
987 | if (err < 0) { | ||
988 | kfree(hsic); | ||
989 | goto out; | ||
990 | } | ||
991 | |||
992 | err = tegra_xusb_pad_register(pad, &tegra124_hsic_phy_ops); | ||
993 | if (err < 0) | ||
994 | goto unregister; | ||
995 | |||
996 | dev_set_drvdata(&pad->dev, pad); | ||
997 | |||
998 | return pad; | ||
999 | |||
1000 | unregister: | ||
1001 | device_unregister(&pad->dev); | ||
1002 | out: | ||
1003 | return ERR_PTR(err); | ||
1004 | } | ||
1005 | |||
1006 | static void tegra124_hsic_pad_remove(struct tegra_xusb_pad *pad) | ||
1007 | { | ||
1008 | struct tegra_xusb_hsic_pad *hsic = to_hsic_pad(pad); | ||
1009 | |||
1010 | kfree(hsic); | ||
1011 | } | ||
1012 | |||
1013 | static const struct tegra_xusb_pad_ops tegra124_hsic_ops = { | ||
1014 | .probe = tegra124_hsic_pad_probe, | ||
1015 | .remove = tegra124_hsic_pad_remove, | ||
1016 | }; | ||
1017 | |||
1018 | static const struct tegra_xusb_pad_soc tegra124_hsic_pad = { | ||
1019 | .name = "hsic", | ||
1020 | .num_lanes = ARRAY_SIZE(tegra124_hsic_lanes), | ||
1021 | .lanes = tegra124_hsic_lanes, | ||
1022 | .ops = &tegra124_hsic_ops, | ||
1023 | }; | ||
1024 | |||
1025 | static const char * const tegra124_pcie_functions[] = { | ||
1026 | "pcie", | ||
1027 | "usb3-ss", | ||
1028 | "sata", | ||
1029 | }; | ||
1030 | |||
1031 | static const struct tegra_xusb_lane_soc tegra124_pcie_lanes[] = { | ||
1032 | TEGRA124_LANE("pcie-0", 0x134, 16, 0x3, pcie), | ||
1033 | TEGRA124_LANE("pcie-1", 0x134, 18, 0x3, pcie), | ||
1034 | TEGRA124_LANE("pcie-2", 0x134, 20, 0x3, pcie), | ||
1035 | TEGRA124_LANE("pcie-3", 0x134, 22, 0x3, pcie), | ||
1036 | TEGRA124_LANE("pcie-4", 0x134, 24, 0x3, pcie), | ||
1037 | }; | ||
1038 | |||
1039 | static struct tegra_xusb_lane * | ||
1040 | tegra124_pcie_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, | ||
1041 | unsigned int index) | ||
1042 | { | ||
1043 | struct tegra_xusb_pcie_lane *pcie; | ||
1044 | int err; | ||
1045 | |||
1046 | pcie = kzalloc(sizeof(*pcie), GFP_KERNEL); | ||
1047 | if (!pcie) | ||
1048 | return ERR_PTR(-ENOMEM); | ||
1049 | |||
1050 | INIT_LIST_HEAD(&pcie->base.list); | ||
1051 | pcie->base.soc = &pad->soc->lanes[index]; | ||
1052 | pcie->base.index = index; | ||
1053 | pcie->base.pad = pad; | ||
1054 | pcie->base.np = np; | ||
1055 | |||
1056 | err = tegra_xusb_lane_parse_dt(&pcie->base, np); | ||
1057 | if (err < 0) { | ||
1058 | kfree(pcie); | ||
1059 | return ERR_PTR(err); | ||
1060 | } | ||
1061 | |||
1062 | return &pcie->base; | ||
1063 | } | ||
1064 | |||
1065 | static void tegra124_pcie_lane_remove(struct tegra_xusb_lane *lane) | ||
1066 | { | ||
1067 | struct tegra_xusb_pcie_lane *pcie = to_pcie_lane(lane); | ||
1068 | |||
1069 | kfree(pcie); | ||
1070 | } | ||
1071 | |||
1072 | static const struct tegra_xusb_lane_ops tegra124_pcie_lane_ops = { | ||
1073 | .probe = tegra124_pcie_lane_probe, | ||
1074 | .remove = tegra124_pcie_lane_remove, | ||
1075 | }; | ||
1076 | |||
1077 | static int tegra124_pcie_phy_init(struct phy *phy) | ||
1078 | { | ||
1079 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1080 | |||
1081 | return tegra124_xusb_padctl_enable(lane->pad->padctl); | ||
1082 | } | ||
1083 | |||
1084 | static int tegra124_pcie_phy_exit(struct phy *phy) | ||
1085 | { | ||
1086 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1087 | |||
1088 | return tegra124_xusb_padctl_disable(lane->pad->padctl); | ||
1089 | } | ||
1090 | |||
1091 | static int tegra124_pcie_phy_power_on(struct phy *phy) | ||
1092 | { | ||
1093 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1094 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
1095 | unsigned long timeout; | ||
1096 | int err = -ETIMEDOUT; | ||
1097 | u32 value; | ||
1098 | |||
1099 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); | ||
1100 | value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK; | ||
1101 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); | ||
1102 | |||
1103 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL2); | ||
1104 | value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN | | ||
1105 | XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN | | ||
1106 | XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL; | ||
1107 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL2); | ||
1108 | |||
1109 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); | ||
1110 | value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST; | ||
1111 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); | ||
1112 | |||
1113 | timeout = jiffies + msecs_to_jiffies(50); | ||
1114 | |||
1115 | while (time_before(jiffies, timeout)) { | ||
1116 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); | ||
1117 | if (value & XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET) { | ||
1118 | err = 0; | ||
1119 | break; | ||
1120 | } | ||
1121 | |||
1122 | usleep_range(100, 200); | ||
1123 | } | ||
1124 | |||
1125 | value = padctl_readl(padctl, XUSB_PADCTL_USB3_PAD_MUX); | ||
1126 | value |= XUSB_PADCTL_USB3_PAD_MUX_PCIE_IDDQ_DISABLE(lane->index); | ||
1127 | padctl_writel(padctl, value, XUSB_PADCTL_USB3_PAD_MUX); | ||
1128 | |||
1129 | return err; | ||
1130 | } | ||
1131 | |||
1132 | static int tegra124_pcie_phy_power_off(struct phy *phy) | ||
1133 | { | ||
1134 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1135 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
1136 | u32 value; | ||
1137 | |||
1138 | value = padctl_readl(padctl, XUSB_PADCTL_USB3_PAD_MUX); | ||
1139 | value &= ~XUSB_PADCTL_USB3_PAD_MUX_PCIE_IDDQ_DISABLE(lane->index); | ||
1140 | padctl_writel(padctl, value, XUSB_PADCTL_USB3_PAD_MUX); | ||
1141 | |||
1142 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); | ||
1143 | value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST; | ||
1144 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1); | ||
1145 | |||
1146 | return 0; | ||
1147 | } | ||
1148 | |||
1149 | static const struct phy_ops tegra124_pcie_phy_ops = { | ||
1150 | .init = tegra124_pcie_phy_init, | ||
1151 | .exit = tegra124_pcie_phy_exit, | ||
1152 | .power_on = tegra124_pcie_phy_power_on, | ||
1153 | .power_off = tegra124_pcie_phy_power_off, | ||
1154 | .owner = THIS_MODULE, | ||
1155 | }; | ||
1156 | |||
1157 | static struct tegra_xusb_pad * | ||
1158 | tegra124_pcie_pad_probe(struct tegra_xusb_padctl *padctl, | ||
1159 | const struct tegra_xusb_pad_soc *soc, | ||
1160 | struct device_node *np) | ||
1161 | { | ||
1162 | struct tegra_xusb_pcie_pad *pcie; | ||
1163 | struct tegra_xusb_pad *pad; | ||
1164 | int err; | ||
1165 | |||
1166 | pcie = kzalloc(sizeof(*pcie), GFP_KERNEL); | ||
1167 | if (!pcie) | ||
1168 | return ERR_PTR(-ENOMEM); | ||
1169 | |||
1170 | pad = &pcie->base; | ||
1171 | pad->ops = &tegra124_pcie_lane_ops; | ||
1172 | pad->soc = soc; | ||
1173 | |||
1174 | err = tegra_xusb_pad_init(pad, padctl, np); | ||
1175 | if (err < 0) { | ||
1176 | kfree(pcie); | ||
1177 | goto out; | ||
1178 | } | ||
1179 | |||
1180 | err = tegra_xusb_pad_register(pad, &tegra124_pcie_phy_ops); | ||
1181 | if (err < 0) | ||
1182 | goto unregister; | ||
1183 | |||
1184 | dev_set_drvdata(&pad->dev, pad); | ||
1185 | |||
1186 | return pad; | ||
1187 | |||
1188 | unregister: | ||
1189 | device_unregister(&pad->dev); | ||
1190 | out: | ||
1191 | return ERR_PTR(err); | ||
1192 | } | ||
1193 | |||
1194 | static void tegra124_pcie_pad_remove(struct tegra_xusb_pad *pad) | ||
1195 | { | ||
1196 | struct tegra_xusb_pcie_pad *pcie = to_pcie_pad(pad); | ||
1197 | |||
1198 | kfree(pcie); | ||
1199 | } | ||
1200 | |||
1201 | static const struct tegra_xusb_pad_ops tegra124_pcie_ops = { | ||
1202 | .probe = tegra124_pcie_pad_probe, | ||
1203 | .remove = tegra124_pcie_pad_remove, | ||
1204 | }; | ||
1205 | |||
1206 | static const struct tegra_xusb_pad_soc tegra124_pcie_pad = { | ||
1207 | .name = "pcie", | ||
1208 | .num_lanes = ARRAY_SIZE(tegra124_pcie_lanes), | ||
1209 | .lanes = tegra124_pcie_lanes, | ||
1210 | .ops = &tegra124_pcie_ops, | ||
1211 | }; | ||
1212 | |||
1213 | static const struct tegra_xusb_lane_soc tegra124_sata_lanes[] = { | ||
1214 | TEGRA124_LANE("sata-0", 0x134, 26, 0x3, pcie), | ||
1215 | }; | ||
1216 | |||
1217 | static struct tegra_xusb_lane * | ||
1218 | tegra124_sata_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, | ||
1219 | unsigned int index) | ||
1220 | { | ||
1221 | struct tegra_xusb_sata_lane *sata; | ||
1222 | int err; | ||
1223 | |||
1224 | sata = kzalloc(sizeof(*sata), GFP_KERNEL); | ||
1225 | if (!sata) | ||
1226 | return ERR_PTR(-ENOMEM); | ||
1227 | |||
1228 | INIT_LIST_HEAD(&sata->base.list); | ||
1229 | sata->base.soc = &pad->soc->lanes[index]; | ||
1230 | sata->base.index = index; | ||
1231 | sata->base.pad = pad; | ||
1232 | sata->base.np = np; | ||
1233 | |||
1234 | err = tegra_xusb_lane_parse_dt(&sata->base, np); | ||
1235 | if (err < 0) { | ||
1236 | kfree(sata); | ||
1237 | return ERR_PTR(err); | ||
1238 | } | ||
1239 | |||
1240 | return &sata->base; | ||
1241 | } | ||
1242 | |||
1243 | static void tegra124_sata_lane_remove(struct tegra_xusb_lane *lane) | ||
1244 | { | ||
1245 | struct tegra_xusb_sata_lane *sata = to_sata_lane(lane); | ||
1246 | |||
1247 | kfree(sata); | ||
1248 | } | ||
1249 | |||
1250 | static const struct tegra_xusb_lane_ops tegra124_sata_lane_ops = { | ||
1251 | .probe = tegra124_sata_lane_probe, | ||
1252 | .remove = tegra124_sata_lane_remove, | ||
1253 | }; | ||
1254 | |||
1255 | static int tegra124_sata_phy_init(struct phy *phy) | ||
1256 | { | ||
1257 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1258 | |||
1259 | return tegra124_xusb_padctl_enable(lane->pad->padctl); | ||
1260 | } | ||
1261 | |||
1262 | static int tegra124_sata_phy_exit(struct phy *phy) | ||
1263 | { | ||
1264 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1265 | |||
1266 | return tegra124_xusb_padctl_disable(lane->pad->padctl); | ||
1267 | } | ||
1268 | |||
1269 | static int tegra124_sata_phy_power_on(struct phy *phy) | ||
1270 | { | ||
1271 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1272 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
1273 | unsigned long timeout; | ||
1274 | int err = -ETIMEDOUT; | ||
1275 | u32 value; | ||
1276 | |||
1277 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); | ||
1278 | value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD; | ||
1279 | value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ; | ||
1280 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); | ||
1281 | |||
1282 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); | ||
1283 | value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD; | ||
1284 | value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ; | ||
1285 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); | ||
1286 | |||
1287 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); | ||
1288 | value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE; | ||
1289 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); | ||
1290 | |||
1291 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); | ||
1292 | value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST; | ||
1293 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); | ||
1294 | |||
1295 | timeout = jiffies + msecs_to_jiffies(50); | ||
1296 | |||
1297 | while (time_before(jiffies, timeout)) { | ||
1298 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); | ||
1299 | if (value & XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET) { | ||
1300 | err = 0; | ||
1301 | break; | ||
1302 | } | ||
1303 | |||
1304 | usleep_range(100, 200); | ||
1305 | } | ||
1306 | |||
1307 | value = padctl_readl(padctl, XUSB_PADCTL_USB3_PAD_MUX); | ||
1308 | value |= XUSB_PADCTL_USB3_PAD_MUX_SATA_IDDQ_DISABLE(lane->index); | ||
1309 | padctl_writel(padctl, value, XUSB_PADCTL_USB3_PAD_MUX); | ||
1310 | |||
1311 | return err; | ||
1312 | } | ||
1313 | |||
1314 | static int tegra124_sata_phy_power_off(struct phy *phy) | ||
1315 | { | ||
1316 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1317 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
1318 | u32 value; | ||
1319 | |||
1320 | value = padctl_readl(padctl, XUSB_PADCTL_USB3_PAD_MUX); | ||
1321 | value &= ~XUSB_PADCTL_USB3_PAD_MUX_SATA_IDDQ_DISABLE(lane->index); | ||
1322 | padctl_writel(padctl, value, XUSB_PADCTL_USB3_PAD_MUX); | ||
1323 | |||
1324 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); | ||
1325 | value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST; | ||
1326 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); | ||
1327 | |||
1328 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); | ||
1329 | value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE; | ||
1330 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); | ||
1331 | |||
1332 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); | ||
1333 | value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD; | ||
1334 | value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ; | ||
1335 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); | ||
1336 | |||
1337 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); | ||
1338 | value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD; | ||
1339 | value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ; | ||
1340 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1); | ||
1341 | |||
1342 | return 0; | ||
1343 | } | ||
1344 | |||
1345 | static const struct phy_ops tegra124_sata_phy_ops = { | ||
1346 | .init = tegra124_sata_phy_init, | ||
1347 | .exit = tegra124_sata_phy_exit, | ||
1348 | .power_on = tegra124_sata_phy_power_on, | ||
1349 | .power_off = tegra124_sata_phy_power_off, | ||
1350 | .owner = THIS_MODULE, | ||
1351 | }; | ||
1352 | |||
1353 | static struct tegra_xusb_pad * | ||
1354 | tegra124_sata_pad_probe(struct tegra_xusb_padctl *padctl, | ||
1355 | const struct tegra_xusb_pad_soc *soc, | ||
1356 | struct device_node *np) | ||
1357 | { | ||
1358 | struct tegra_xusb_sata_pad *sata; | ||
1359 | struct tegra_xusb_pad *pad; | ||
1360 | int err; | ||
1361 | |||
1362 | sata = kzalloc(sizeof(*sata), GFP_KERNEL); | ||
1363 | if (!sata) | ||
1364 | return ERR_PTR(-ENOMEM); | ||
1365 | |||
1366 | pad = &sata->base; | ||
1367 | pad->ops = &tegra124_sata_lane_ops; | ||
1368 | pad->soc = soc; | ||
1369 | |||
1370 | err = tegra_xusb_pad_init(pad, padctl, np); | ||
1371 | if (err < 0) { | ||
1372 | kfree(sata); | ||
1373 | goto out; | ||
1374 | } | ||
1375 | |||
1376 | err = tegra_xusb_pad_register(pad, &tegra124_sata_phy_ops); | ||
1377 | if (err < 0) | ||
1378 | goto unregister; | ||
1379 | |||
1380 | dev_set_drvdata(&pad->dev, pad); | ||
1381 | |||
1382 | return pad; | ||
1383 | |||
1384 | unregister: | ||
1385 | device_unregister(&pad->dev); | ||
1386 | out: | ||
1387 | return ERR_PTR(err); | ||
1388 | } | ||
1389 | |||
1390 | static void tegra124_sata_pad_remove(struct tegra_xusb_pad *pad) | ||
1391 | { | ||
1392 | struct tegra_xusb_sata_pad *sata = to_sata_pad(pad); | ||
1393 | |||
1394 | kfree(sata); | ||
1395 | } | ||
1396 | |||
1397 | static const struct tegra_xusb_pad_ops tegra124_sata_ops = { | ||
1398 | .probe = tegra124_sata_pad_probe, | ||
1399 | .remove = tegra124_sata_pad_remove, | ||
1400 | }; | ||
1401 | |||
1402 | static const struct tegra_xusb_pad_soc tegra124_sata_pad = { | ||
1403 | .name = "sata", | ||
1404 | .num_lanes = ARRAY_SIZE(tegra124_sata_lanes), | ||
1405 | .lanes = tegra124_sata_lanes, | ||
1406 | .ops = &tegra124_sata_ops, | ||
1407 | }; | ||
1408 | |||
1409 | static const struct tegra_xusb_pad_soc *tegra124_pads[] = { | ||
1410 | &tegra124_usb2_pad, | ||
1411 | &tegra124_ulpi_pad, | ||
1412 | &tegra124_hsic_pad, | ||
1413 | &tegra124_pcie_pad, | ||
1414 | &tegra124_sata_pad, | ||
1415 | }; | ||
1416 | |||
1417 | static int tegra124_usb2_port_enable(struct tegra_xusb_port *port) | ||
1418 | { | ||
1419 | return 0; | ||
1420 | } | ||
1421 | |||
1422 | static void tegra124_usb2_port_disable(struct tegra_xusb_port *port) | ||
1423 | { | ||
1424 | } | ||
1425 | |||
1426 | static struct tegra_xusb_lane * | ||
1427 | tegra124_usb2_port_map(struct tegra_xusb_port *port) | ||
1428 | { | ||
1429 | return tegra_xusb_find_lane(port->padctl, "usb2", port->index); | ||
1430 | } | ||
1431 | |||
1432 | static const struct tegra_xusb_port_ops tegra124_usb2_port_ops = { | ||
1433 | .enable = tegra124_usb2_port_enable, | ||
1434 | .disable = tegra124_usb2_port_disable, | ||
1435 | .map = tegra124_usb2_port_map, | ||
1436 | }; | ||
1437 | |||
1438 | static int tegra124_ulpi_port_enable(struct tegra_xusb_port *port) | ||
1439 | { | ||
1440 | return 0; | ||
1441 | } | ||
1442 | |||
1443 | static void tegra124_ulpi_port_disable(struct tegra_xusb_port *port) | ||
1444 | { | ||
1445 | } | ||
1446 | |||
1447 | static struct tegra_xusb_lane * | ||
1448 | tegra124_ulpi_port_map(struct tegra_xusb_port *port) | ||
1449 | { | ||
1450 | return tegra_xusb_find_lane(port->padctl, "ulpi", port->index); | ||
1451 | } | ||
1452 | |||
1453 | static const struct tegra_xusb_port_ops tegra124_ulpi_port_ops = { | ||
1454 | .enable = tegra124_ulpi_port_enable, | ||
1455 | .disable = tegra124_ulpi_port_disable, | ||
1456 | .map = tegra124_ulpi_port_map, | ||
1457 | }; | ||
1458 | |||
1459 | static int tegra124_hsic_port_enable(struct tegra_xusb_port *port) | ||
1460 | { | ||
1461 | return 0; | ||
1462 | } | ||
1463 | |||
1464 | static void tegra124_hsic_port_disable(struct tegra_xusb_port *port) | ||
1465 | { | ||
1466 | } | ||
1467 | |||
1468 | static struct tegra_xusb_lane * | ||
1469 | tegra124_hsic_port_map(struct tegra_xusb_port *port) | ||
1470 | { | ||
1471 | return tegra_xusb_find_lane(port->padctl, "hsic", port->index); | ||
1472 | } | ||
1473 | |||
1474 | static const struct tegra_xusb_port_ops tegra124_hsic_port_ops = { | ||
1475 | .enable = tegra124_hsic_port_enable, | ||
1476 | .disable = tegra124_hsic_port_disable, | ||
1477 | .map = tegra124_hsic_port_map, | ||
1478 | }; | ||
1479 | |||
1480 | static int tegra124_usb3_port_enable(struct tegra_xusb_port *port) | ||
1481 | { | ||
1482 | struct tegra_xusb_usb3_port *usb3 = to_usb3_port(port); | ||
1483 | struct tegra_xusb_padctl *padctl = port->padctl; | ||
1484 | struct tegra_xusb_lane *lane = usb3->base.lane; | ||
1485 | unsigned int index = port->index, offset; | ||
1486 | int ret = 0; | ||
1487 | u32 value; | ||
1488 | |||
1489 | value = padctl_readl(padctl, XUSB_PADCTL_SS_PORT_MAP); | ||
1490 | |||
1491 | if (!usb3->internal) | ||
1492 | value &= ~XUSB_PADCTL_SS_PORT_MAP_PORTX_INTERNAL(index); | ||
1493 | else | ||
1494 | value |= XUSB_PADCTL_SS_PORT_MAP_PORTX_INTERNAL(index); | ||
1495 | |||
1496 | value &= ~XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_MASK(index); | ||
1497 | value |= XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP(index, usb3->port); | ||
1498 | padctl_writel(padctl, value, XUSB_PADCTL_SS_PORT_MAP); | ||
1499 | |||
1500 | /* | ||
1501 | * TODO: move this code into the PCIe/SATA PHY ->power_on() callbacks | ||
1502 | * and conditionalize based on mux function? This seems to work, but | ||
1503 | * might not be the exact proper sequence. | ||
1504 | */ | ||
1505 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_USB3_PADX_CTL2(index)); | ||
1506 | value &= ~((XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_WANDER_MASK << | ||
1507 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_WANDER_SHIFT) | | ||
1508 | (XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_MASK << | ||
1509 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_SHIFT) | | ||
1510 | (XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_CDR_CNTL_MASK << | ||
1511 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_CDR_CNTL_SHIFT)); | ||
1512 | value |= (XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_WANDER_VAL << | ||
1513 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_WANDER_SHIFT) | | ||
1514 | (XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_CDR_CNTL_VAL << | ||
1515 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_CDR_CNTL_SHIFT) | | ||
1516 | (XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_VAL << | ||
1517 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_SHIFT); | ||
1518 | |||
1519 | if (usb3->context_saved) { | ||
1520 | value &= ~((XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_G_MASK << | ||
1521 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_G_SHIFT) | | ||
1522 | (XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_Z_MASK << | ||
1523 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_Z_SHIFT)); | ||
1524 | value |= (usb3->ctle_g << | ||
1525 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_G_SHIFT) | | ||
1526 | (usb3->ctle_z << | ||
1527 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL2_RX_EQ_Z_SHIFT); | ||
1528 | } | ||
1529 | |||
1530 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_USB3_PADX_CTL2(index)); | ||
1531 | |||
1532 | value = XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_VAL; | ||
1533 | |||
1534 | if (usb3->context_saved) { | ||
1535 | value &= ~((XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_TAP_MASK << | ||
1536 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_TAP_SHIFT) | | ||
1537 | (XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_AMP_MASK << | ||
1538 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_AMP_SHIFT)); | ||
1539 | value |= (usb3->tap1 << | ||
1540 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_TAP_SHIFT) | | ||
1541 | (usb3->amp << | ||
1542 | XUSB_PADCTL_IOPHY_USB3_PAD_CTL4_DFE_CNTL_AMP_SHIFT); | ||
1543 | } | ||
1544 | |||
1545 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_USB3_PADX_CTL4(index)); | ||
1546 | |||
1547 | if (lane->pad == padctl->pcie) | ||
1548 | offset = XUSB_PADCTL_IOPHY_MISC_PAD_PX_CTL2(lane->index); | ||
1549 | else | ||
1550 | offset = XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL2; | ||
1551 | |||
1552 | value = padctl_readl(padctl, offset); | ||
1553 | value &= ~(XUSB_PADCTL_IOPHY_MISC_PAD_CTL2_SPARE_IN_MASK << | ||
1554 | XUSB_PADCTL_IOPHY_MISC_PAD_CTL2_SPARE_IN_SHIFT); | ||
1555 | value |= XUSB_PADCTL_IOPHY_MISC_PAD_CTL2_SPARE_IN_VAL << | ||
1556 | XUSB_PADCTL_IOPHY_MISC_PAD_CTL2_SPARE_IN_SHIFT; | ||
1557 | padctl_writel(padctl, value, offset); | ||
1558 | |||
1559 | if (lane->pad == padctl->pcie) | ||
1560 | offset = XUSB_PADCTL_IOPHY_MISC_PAD_PX_CTL5(lane->index); | ||
1561 | else | ||
1562 | offset = XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL5; | ||
1563 | |||
1564 | value = padctl_readl(padctl, offset); | ||
1565 | value |= XUSB_PADCTL_IOPHY_MISC_PAD_CTL5_RX_QEYE_EN; | ||
1566 | padctl_writel(padctl, value, offset); | ||
1567 | |||
1568 | /* Enable SATA PHY when SATA lane is used */ | ||
1569 | if (lane->pad == padctl->sata) { | ||
1570 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); | ||
1571 | value &= ~(XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL0_REFCLK_NDIV_MASK << | ||
1572 | XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL0_REFCLK_NDIV_SHIFT); | ||
1573 | value |= 0x2 << | ||
1574 | XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL0_REFCLK_NDIV_SHIFT; | ||
1575 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1); | ||
1576 | |||
1577 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL2); | ||
1578 | value &= ~((XUSB_PADCTL_IOPHY_PLL_S0_CTL2_XDIGCLK_SEL_MASK << | ||
1579 | XUSB_PADCTL_IOPHY_PLL_S0_CTL2_XDIGCLK_SEL_SHIFT) | | ||
1580 | (XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL1_CP_CNTL_MASK << | ||
1581 | XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL1_CP_CNTL_SHIFT) | | ||
1582 | (XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL0_CP_CNTL_MASK << | ||
1583 | XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL0_CP_CNTL_SHIFT) | | ||
1584 | XUSB_PADCTL_IOPHY_PLL_S0_CTL2_TCLKOUT_EN); | ||
1585 | value |= (0x7 << | ||
1586 | XUSB_PADCTL_IOPHY_PLL_S0_CTL2_XDIGCLK_SEL_SHIFT) | | ||
1587 | (0x8 << | ||
1588 | XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL1_CP_CNTL_SHIFT) | | ||
1589 | (0x8 << | ||
1590 | XUSB_PADCTL_IOPHY_PLL_S0_CTL2_PLL0_CP_CNTL_SHIFT) | | ||
1591 | XUSB_PADCTL_IOPHY_PLL_S0_CTL2_TXCLKREF_SEL; | ||
1592 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL2); | ||
1593 | |||
1594 | value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL3); | ||
1595 | value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL3_RCAL_BYPASS; | ||
1596 | padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL3); | ||
1597 | } | ||
1598 | |||
1599 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); | ||
1600 | value &= ~XUSB_PADCTL_ELPG_PROGRAM_SSPX_ELPG_VCORE_DOWN(index); | ||
1601 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); | ||
1602 | |||
1603 | usleep_range(100, 200); | ||
1604 | |||
1605 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); | ||
1606 | value &= ~XUSB_PADCTL_ELPG_PROGRAM_SSPX_ELPG_CLAMP_EN_EARLY(index); | ||
1607 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); | ||
1608 | |||
1609 | usleep_range(100, 200); | ||
1610 | |||
1611 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); | ||
1612 | value &= ~XUSB_PADCTL_ELPG_PROGRAM_SSPX_ELPG_CLAMP_EN(index); | ||
1613 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); | ||
1614 | |||
1615 | return ret; | ||
1616 | } | ||
1617 | |||
1618 | static void tegra124_usb3_port_disable(struct tegra_xusb_port *port) | ||
1619 | { | ||
1620 | struct tegra_xusb_padctl *padctl = port->padctl; | ||
1621 | u32 value; | ||
1622 | |||
1623 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); | ||
1624 | value |= XUSB_PADCTL_ELPG_PROGRAM_SSPX_ELPG_CLAMP_EN_EARLY(port->index); | ||
1625 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); | ||
1626 | |||
1627 | usleep_range(100, 200); | ||
1628 | |||
1629 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); | ||
1630 | value |= XUSB_PADCTL_ELPG_PROGRAM_SSPX_ELPG_CLAMP_EN(port->index); | ||
1631 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); | ||
1632 | |||
1633 | usleep_range(250, 350); | ||
1634 | |||
1635 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); | ||
1636 | value |= XUSB_PADCTL_ELPG_PROGRAM_SSPX_ELPG_VCORE_DOWN(port->index); | ||
1637 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); | ||
1638 | |||
1639 | value = padctl_readl(padctl, XUSB_PADCTL_SS_PORT_MAP); | ||
1640 | value &= ~XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_MASK(port->index); | ||
1641 | value |= XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP(port->index, 0x7); | ||
1642 | padctl_writel(padctl, value, XUSB_PADCTL_SS_PORT_MAP); | ||
1643 | } | ||
1644 | |||
1645 | static const struct tegra_xusb_lane_map tegra124_usb3_map[] = { | ||
1646 | { 0, "pcie", 0 }, | ||
1647 | { 1, "pcie", 1 }, | ||
1648 | { 1, "sata", 0 }, | ||
1649 | { 0, NULL, 0 }, | ||
1650 | }; | ||
1651 | |||
1652 | static struct tegra_xusb_lane * | ||
1653 | tegra124_usb3_port_map(struct tegra_xusb_port *port) | ||
1654 | { | ||
1655 | return tegra_xusb_port_find_lane(port, tegra124_usb3_map, "usb3-ss"); | ||
1656 | } | ||
1657 | |||
1658 | static const struct tegra_xusb_port_ops tegra124_usb3_port_ops = { | ||
1659 | .enable = tegra124_usb3_port_enable, | ||
1660 | .disable = tegra124_usb3_port_disable, | ||
1661 | .map = tegra124_usb3_port_map, | ||
1662 | }; | ||
1663 | |||
1664 | static int | ||
1665 | tegra124_xusb_read_fuse_calibration(struct tegra124_xusb_fuse_calibration *fuse) | ||
1666 | { | ||
1667 | unsigned int i; | ||
1668 | int err; | ||
1669 | u32 value; | ||
1670 | |||
1671 | err = tegra_fuse_readl(TEGRA_FUSE_SKU_CALIB_0, &value); | ||
1672 | if (err < 0) | ||
1673 | return err; | ||
1674 | |||
1675 | for (i = 0; i < ARRAY_SIZE(fuse->hs_curr_level); i++) { | ||
1676 | fuse->hs_curr_level[i] = | ||
1677 | (value >> FUSE_SKU_CALIB_HS_CURR_LEVEL_PADX_SHIFT(i)) & | ||
1678 | FUSE_SKU_CALIB_HS_CURR_LEVEL_PAD_MASK; | ||
1679 | } | ||
1680 | fuse->hs_iref_cap = | ||
1681 | (value >> FUSE_SKU_CALIB_HS_IREF_CAP_SHIFT) & | ||
1682 | FUSE_SKU_CALIB_HS_IREF_CAP_MASK; | ||
1683 | fuse->hs_term_range_adj = | ||
1684 | (value >> FUSE_SKU_CALIB_HS_TERM_RANGE_ADJ_SHIFT) & | ||
1685 | FUSE_SKU_CALIB_HS_TERM_RANGE_ADJ_MASK; | ||
1686 | fuse->hs_squelch_level = | ||
1687 | (value >> FUSE_SKU_CALIB_HS_SQUELCH_LEVEL_SHIFT) & | ||
1688 | FUSE_SKU_CALIB_HS_SQUELCH_LEVEL_MASK; | ||
1689 | |||
1690 | return 0; | ||
1691 | } | ||
1692 | |||
1693 | static struct tegra_xusb_padctl * | ||
1694 | tegra124_xusb_padctl_probe(struct device *dev, | ||
1695 | const struct tegra_xusb_padctl_soc *soc) | ||
1696 | { | ||
1697 | struct tegra124_xusb_padctl *padctl; | ||
1698 | int err; | ||
1699 | |||
1700 | padctl = devm_kzalloc(dev, sizeof(*padctl), GFP_KERNEL); | ||
1701 | if (!padctl) | ||
1702 | return ERR_PTR(-ENOMEM); | ||
1703 | |||
1704 | padctl->base.dev = dev; | ||
1705 | padctl->base.soc = soc; | ||
1706 | |||
1707 | err = tegra124_xusb_read_fuse_calibration(&padctl->fuse); | ||
1708 | if (err < 0) | ||
1709 | return ERR_PTR(err); | ||
1710 | |||
1711 | return &padctl->base; | ||
1712 | } | ||
1713 | |||
1714 | static void tegra124_xusb_padctl_remove(struct tegra_xusb_padctl *padctl) | ||
1715 | { | ||
1716 | } | ||
1717 | |||
1718 | static const struct tegra_xusb_padctl_ops tegra124_xusb_padctl_ops = { | ||
1719 | .probe = tegra124_xusb_padctl_probe, | ||
1720 | .remove = tegra124_xusb_padctl_remove, | ||
1721 | .usb3_save_context = tegra124_usb3_save_context, | ||
1722 | .hsic_set_idle = tegra124_hsic_set_idle, | ||
1723 | }; | ||
1724 | |||
1725 | const struct tegra_xusb_padctl_soc tegra124_xusb_padctl_soc = { | ||
1726 | .num_pads = ARRAY_SIZE(tegra124_pads), | ||
1727 | .pads = tegra124_pads, | ||
1728 | .ports = { | ||
1729 | .usb2 = { | ||
1730 | .ops = &tegra124_usb2_port_ops, | ||
1731 | .count = 3, | ||
1732 | }, | ||
1733 | .ulpi = { | ||
1734 | .ops = &tegra124_ulpi_port_ops, | ||
1735 | .count = 1, | ||
1736 | }, | ||
1737 | .hsic = { | ||
1738 | .ops = &tegra124_hsic_port_ops, | ||
1739 | .count = 2, | ||
1740 | }, | ||
1741 | .usb3 = { | ||
1742 | .ops = &tegra124_usb3_port_ops, | ||
1743 | .count = 2, | ||
1744 | }, | ||
1745 | }, | ||
1746 | .ops = &tegra124_xusb_padctl_ops, | ||
1747 | }; | ||
1748 | EXPORT_SYMBOL_GPL(tegra124_xusb_padctl_soc); | ||
1749 | |||
1750 | MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); | ||
1751 | MODULE_DESCRIPTION("NVIDIA Tegra 124 XUSB Pad Controller driver"); | ||
1752 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/phy/tegra/xusb-tegra210.c b/drivers/phy/tegra/xusb-tegra210.c new file mode 100644 index 000000000000..9d0689ebd28c --- /dev/null +++ b/drivers/phy/tegra/xusb-tegra210.c | |||
@@ -0,0 +1,2045 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. | ||
3 | * Copyright (C) 2015 Google, Inc. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/clk.h> | ||
16 | #include <linux/clk/tegra.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/mailbox_client.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/of.h> | ||
22 | #include <linux/phy/phy.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/regulator/consumer.h> | ||
25 | #include <linux/reset.h> | ||
26 | #include <linux/slab.h> | ||
27 | |||
28 | #include <soc/tegra/fuse.h> | ||
29 | |||
30 | #include "xusb.h" | ||
31 | |||
32 | #define FUSE_SKU_CALIB_HS_CURR_LEVEL_PADX_SHIFT(x) \ | ||
33 | ((x) ? (11 + ((x) - 1) * 6) : 0) | ||
34 | #define FUSE_SKU_CALIB_HS_CURR_LEVEL_PAD_MASK 0x3f | ||
35 | #define FUSE_SKU_CALIB_HS_TERM_RANGE_ADJ_SHIFT 7 | ||
36 | #define FUSE_SKU_CALIB_HS_TERM_RANGE_ADJ_MASK 0xf | ||
37 | |||
38 | #define FUSE_USB_CALIB_EXT_RPD_CTRL_SHIFT 0 | ||
39 | #define FUSE_USB_CALIB_EXT_RPD_CTRL_MASK 0x1f | ||
40 | |||
41 | #define XUSB_PADCTL_USB2_PAD_MUX 0x004 | ||
42 | #define XUSB_PADCTL_USB2_PAD_MUX_HSIC_PAD_TRK_SHIFT 16 | ||
43 | #define XUSB_PADCTL_USB2_PAD_MUX_HSIC_PAD_TRK_MASK 0x3 | ||
44 | #define XUSB_PADCTL_USB2_PAD_MUX_HSIC_PAD_TRK_XUSB 0x1 | ||
45 | #define XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_SHIFT 18 | ||
46 | #define XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_MASK 0x3 | ||
47 | #define XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_XUSB 0x1 | ||
48 | |||
49 | #define XUSB_PADCTL_USB2_PORT_CAP 0x008 | ||
50 | #define XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_HOST(x) (0x1 << ((x) * 4)) | ||
51 | #define XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_MASK(x) (0x3 << ((x) * 4)) | ||
52 | |||
53 | #define XUSB_PADCTL_SS_PORT_MAP 0x014 | ||
54 | #define XUSB_PADCTL_SS_PORT_MAP_PORTX_INTERNAL(x) (1 << (((x) * 5) + 4)) | ||
55 | #define XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_SHIFT(x) ((x) * 5) | ||
56 | #define XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_MASK(x) (0x7 << ((x) * 5)) | ||
57 | #define XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP(x, v) (((v) & 0x7) << ((x) * 5)) | ||
58 | |||
59 | #define XUSB_PADCTL_ELPG_PROGRAM1 0x024 | ||
60 | #define XUSB_PADCTL_ELPG_PROGRAM1_AUX_MUX_LP0_VCORE_DOWN (1 << 31) | ||
61 | #define XUSB_PADCTL_ELPG_PROGRAM1_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 30) | ||
62 | #define XUSB_PADCTL_ELPG_PROGRAM1_AUX_MUX_LP0_CLAMP_EN (1 << 29) | ||
63 | #define XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_VCORE_DOWN(x) (1 << (2 + (x) * 3)) | ||
64 | #define XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_CLAMP_EN_EARLY(x) \ | ||
65 | (1 << (1 + (x) * 3)) | ||
66 | #define XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_CLAMP_EN(x) (1 << ((x) * 3)) | ||
67 | |||
68 | #define XUSB_PADCTL_USB3_PAD_MUX 0x028 | ||
69 | #define XUSB_PADCTL_USB3_PAD_MUX_PCIE_IDDQ_DISABLE(x) (1 << (1 + (x))) | ||
70 | #define XUSB_PADCTL_USB3_PAD_MUX_SATA_IDDQ_DISABLE(x) (1 << (8 + (x))) | ||
71 | |||
72 | #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL1(x) (0x084 + (x) * 0x40) | ||
73 | #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV_SHIFT 7 | ||
74 | #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV_MASK 0x3 | ||
75 | #define XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_FIX18 (1 << 6) | ||
76 | |||
77 | #define XUSB_PADCTL_USB2_OTG_PADX_CTL0(x) (0x088 + (x) * 0x40) | ||
78 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD_ZI (1 << 29) | ||
79 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD2 (1 << 27) | ||
80 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD (1 << 26) | ||
81 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_SHIFT 0 | ||
82 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_MASK 0x3f | ||
83 | |||
84 | #define XUSB_PADCTL_USB2_OTG_PADX_CTL1(x) (0x08c + (x) * 0x40) | ||
85 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL1_RPD_CTRL_SHIFT 26 | ||
86 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL1_RPD_CTRL_MASK 0x1f | ||
87 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_SHIFT 3 | ||
88 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_MASK 0xf | ||
89 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_DR (1 << 2) | ||
90 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_DISC_OVRD (1 << 1) | ||
91 | #define XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_CHRP_OVRD (1 << 0) | ||
92 | |||
93 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL0 0x284 | ||
94 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_PD (1 << 11) | ||
95 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_SHIFT 3 | ||
96 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_MASK 0x7 | ||
97 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_VAL 0x7 | ||
98 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_SHIFT 0 | ||
99 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_MASK 0x7 | ||
100 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_VAL 0x2 | ||
101 | |||
102 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL1 0x288 | ||
103 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL1_PD_TRK (1 << 26) | ||
104 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_SHIFT 19 | ||
105 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_MASK 0x7f | ||
106 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_VAL 0x0a | ||
107 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_SHIFT 12 | ||
108 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_MASK 0x7f | ||
109 | #define XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_VAL 0x1e | ||
110 | |||
111 | #define XUSB_PADCTL_HSIC_PADX_CTL0(x) (0x300 + (x) * 0x20) | ||
112 | #define XUSB_PADCTL_HSIC_PAD_CTL0_RPU_STROBE (1 << 18) | ||
113 | #define XUSB_PADCTL_HSIC_PAD_CTL0_RPU_DATA1 (1 << 17) | ||
114 | #define XUSB_PADCTL_HSIC_PAD_CTL0_RPU_DATA0 (1 << 16) | ||
115 | #define XUSB_PADCTL_HSIC_PAD_CTL0_RPD_STROBE (1 << 15) | ||
116 | #define XUSB_PADCTL_HSIC_PAD_CTL0_RPD_DATA1 (1 << 14) | ||
117 | #define XUSB_PADCTL_HSIC_PAD_CTL0_RPD_DATA0 (1 << 13) | ||
118 | #define XUSB_PADCTL_HSIC_PAD_CTL0_PD_ZI_STROBE (1 << 9) | ||
119 | #define XUSB_PADCTL_HSIC_PAD_CTL0_PD_ZI_DATA1 (1 << 8) | ||
120 | #define XUSB_PADCTL_HSIC_PAD_CTL0_PD_ZI_DATA0 (1 << 7) | ||
121 | #define XUSB_PADCTL_HSIC_PAD_CTL0_PD_RX_STROBE (1 << 6) | ||
122 | #define XUSB_PADCTL_HSIC_PAD_CTL0_PD_RX_DATA1 (1 << 5) | ||
123 | #define XUSB_PADCTL_HSIC_PAD_CTL0_PD_RX_DATA0 (1 << 4) | ||
124 | #define XUSB_PADCTL_HSIC_PAD_CTL0_PD_TX_STROBE (1 << 3) | ||
125 | #define XUSB_PADCTL_HSIC_PAD_CTL0_PD_TX_DATA1 (1 << 2) | ||
126 | #define XUSB_PADCTL_HSIC_PAD_CTL0_PD_TX_DATA0 (1 << 1) | ||
127 | |||
128 | #define XUSB_PADCTL_HSIC_PADX_CTL1(x) (0x304 + (x) * 0x20) | ||
129 | #define XUSB_PADCTL_HSIC_PAD_CTL1_TX_RTUNEP_SHIFT 0 | ||
130 | #define XUSB_PADCTL_HSIC_PAD_CTL1_TX_RTUNEP_MASK 0xf | ||
131 | |||
132 | #define XUSB_PADCTL_HSIC_PADX_CTL2(x) (0x308 + (x) * 0x20) | ||
133 | #define XUSB_PADCTL_HSIC_PAD_CTL2_RX_STROBE_TRIM_SHIFT 8 | ||
134 | #define XUSB_PADCTL_HSIC_PAD_CTL2_RX_STROBE_TRIM_MASK 0xf | ||
135 | #define XUSB_PADCTL_HSIC_PAD_CTL2_RX_DATA_TRIM_SHIFT 0 | ||
136 | #define XUSB_PADCTL_HSIC_PAD_CTL2_RX_DATA_TRIM_MASK 0xff | ||
137 | |||
138 | #define XUSB_PADCTL_HSIC_PAD_TRK_CTL 0x340 | ||
139 | #define XUSB_PADCTL_HSIC_PAD_TRK_CTL_PD_TRK (1 << 19) | ||
140 | #define XUSB_PADCTL_HSIC_PAD_TRK_CTL_TRK_DONE_RESET_TIMER_SHIFT 12 | ||
141 | #define XUSB_PADCTL_HSIC_PAD_TRK_CTL_TRK_DONE_RESET_TIMER_MASK 0x7f | ||
142 | #define XUSB_PADCTL_HSIC_PAD_TRK_CTL_TRK_DONE_RESET_TIMER_VAL 0x0a | ||
143 | #define XUSB_PADCTL_HSIC_PAD_TRK_CTL_TRK_START_TIMER_SHIFT 5 | ||
144 | #define XUSB_PADCTL_HSIC_PAD_TRK_CTL_TRK_START_TIMER_MASK 0x7f | ||
145 | #define XUSB_PADCTL_HSIC_PAD_TRK_CTL_TRK_START_TIMER_VAL 0x1e | ||
146 | |||
147 | #define XUSB_PADCTL_HSIC_STRB_TRIM_CONTROL 0x344 | ||
148 | |||
149 | #define XUSB_PADCTL_UPHY_PLL_P0_CTL1 0x360 | ||
150 | #define XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_SHIFT 20 | ||
151 | #define XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_MASK 0xff | ||
152 | #define XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_USB_VAL 0x19 | ||
153 | #define XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_SATA_VAL 0x1e | ||
154 | #define XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_MDIV_SHIFT 16 | ||
155 | #define XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_MDIV_MASK 0x3 | ||
156 | #define XUSB_PADCTL_UPHY_PLL_CTL1_LOCKDET_STATUS (1 << 15) | ||
157 | #define XUSB_PADCTL_UPHY_PLL_CTL1_PWR_OVRD (1 << 4) | ||
158 | #define XUSB_PADCTL_UPHY_PLL_CTL1_ENABLE (1 << 3) | ||
159 | #define XUSB_PADCTL_UPHY_PLL_CTL1_SLEEP_SHIFT 1 | ||
160 | #define XUSB_PADCTL_UPHY_PLL_CTL1_SLEEP_MASK 0x3 | ||
161 | #define XUSB_PADCTL_UPHY_PLL_CTL1_IDDQ (1 << 0) | ||
162 | |||
163 | #define XUSB_PADCTL_UPHY_PLL_P0_CTL2 0x364 | ||
164 | #define XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_SHIFT 4 | ||
165 | #define XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_MASK 0xffffff | ||
166 | #define XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_VAL 0x136 | ||
167 | #define XUSB_PADCTL_UPHY_PLL_CTL2_CAL_OVRD (1 << 2) | ||
168 | #define XUSB_PADCTL_UPHY_PLL_CTL2_CAL_DONE (1 << 1) | ||
169 | #define XUSB_PADCTL_UPHY_PLL_CTL2_CAL_EN (1 << 0) | ||
170 | |||
171 | #define XUSB_PADCTL_UPHY_PLL_P0_CTL4 0x36c | ||
172 | #define XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_EN (1 << 15) | ||
173 | #define XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_SHIFT 12 | ||
174 | #define XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_MASK 0x3 | ||
175 | #define XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_USB_VAL 0x2 | ||
176 | #define XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_SATA_VAL 0x0 | ||
177 | #define XUSB_PADCTL_UPHY_PLL_CTL4_REFCLKBUF_EN (1 << 8) | ||
178 | #define XUSB_PADCTL_UPHY_PLL_CTL4_REFCLK_SEL_SHIFT 4 | ||
179 | #define XUSB_PADCTL_UPHY_PLL_CTL4_REFCLK_SEL_MASK 0xf | ||
180 | |||
181 | #define XUSB_PADCTL_UPHY_PLL_P0_CTL5 0x370 | ||
182 | #define XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_SHIFT 16 | ||
183 | #define XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_MASK 0xff | ||
184 | #define XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_VAL 0x2a | ||
185 | |||
186 | #define XUSB_PADCTL_UPHY_PLL_P0_CTL8 0x37c | ||
187 | #define XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_DONE (1 << 31) | ||
188 | #define XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_OVRD (1 << 15) | ||
189 | #define XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_CLK_EN (1 << 13) | ||
190 | #define XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_EN (1 << 12) | ||
191 | |||
192 | #define XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL1(x) (0x460 + (x) * 0x40) | ||
193 | #define XUSB_PADCTL_UPHY_MISC_PAD_CTL1_AUX_RX_IDLE_MODE_SHIFT 20 | ||
194 | #define XUSB_PADCTL_UPHY_MISC_PAD_CTL1_AUX_RX_IDLE_MODE_MASK 0x3 | ||
195 | #define XUSB_PADCTL_UPHY_MISC_PAD_CTL1_AUX_RX_IDLE_MODE_VAL 0x1 | ||
196 | #define XUSB_PADCTL_UPHY_MISC_PAD_CTL1_AUX_RX_TERM_EN BIT(18) | ||
197 | #define XUSB_PADCTL_UPHY_MISC_PAD_CTL1_AUX_RX_MODE_OVRD BIT(13) | ||
198 | |||
199 | #define XUSB_PADCTL_UPHY_PLL_S0_CTL1 0x860 | ||
200 | |||
201 | #define XUSB_PADCTL_UPHY_PLL_S0_CTL2 0x864 | ||
202 | |||
203 | #define XUSB_PADCTL_UPHY_PLL_S0_CTL4 0x86c | ||
204 | |||
205 | #define XUSB_PADCTL_UPHY_PLL_S0_CTL5 0x870 | ||
206 | |||
207 | #define XUSB_PADCTL_UPHY_PLL_S0_CTL8 0x87c | ||
208 | |||
209 | #define XUSB_PADCTL_UPHY_MISC_PAD_S0_CTL1 0x960 | ||
210 | |||
211 | #define XUSB_PADCTL_UPHY_USB3_PADX_ECTL1(x) (0xa60 + (x) * 0x40) | ||
212 | #define XUSB_PADCTL_UPHY_USB3_PAD_ECTL1_TX_TERM_CTRL_SHIFT 16 | ||
213 | #define XUSB_PADCTL_UPHY_USB3_PAD_ECTL1_TX_TERM_CTRL_MASK 0x3 | ||
214 | #define XUSB_PADCTL_UPHY_USB3_PAD_ECTL1_TX_TERM_CTRL_VAL 0x2 | ||
215 | |||
216 | #define XUSB_PADCTL_UPHY_USB3_PADX_ECTL2(x) (0xa64 + (x) * 0x40) | ||
217 | #define XUSB_PADCTL_UPHY_USB3_PAD_ECTL2_RX_CTLE_SHIFT 0 | ||
218 | #define XUSB_PADCTL_UPHY_USB3_PAD_ECTL2_RX_CTLE_MASK 0xffff | ||
219 | #define XUSB_PADCTL_UPHY_USB3_PAD_ECTL2_RX_CTLE_VAL 0x00fc | ||
220 | |||
221 | #define XUSB_PADCTL_UPHY_USB3_PADX_ECTL3(x) (0xa68 + (x) * 0x40) | ||
222 | #define XUSB_PADCTL_UPHY_USB3_PAD_ECTL3_RX_DFE_VAL 0xc0077f1f | ||
223 | |||
224 | #define XUSB_PADCTL_UPHY_USB3_PADX_ECTL4(x) (0xa6c + (x) * 0x40) | ||
225 | #define XUSB_PADCTL_UPHY_USB3_PAD_ECTL4_RX_CDR_CTRL_SHIFT 16 | ||
226 | #define XUSB_PADCTL_UPHY_USB3_PAD_ECTL4_RX_CDR_CTRL_MASK 0xffff | ||
227 | #define XUSB_PADCTL_UPHY_USB3_PAD_ECTL4_RX_CDR_CTRL_VAL 0x01c7 | ||
228 | |||
229 | #define XUSB_PADCTL_UPHY_USB3_PADX_ECTL6(x) (0xa74 + (x) * 0x40) | ||
230 | #define XUSB_PADCTL_UPHY_USB3_PAD_ECTL6_RX_EQ_CTRL_H_VAL 0xfcf01368 | ||
231 | |||
232 | struct tegra210_xusb_fuse_calibration { | ||
233 | u32 hs_curr_level[4]; | ||
234 | u32 hs_term_range_adj; | ||
235 | u32 rpd_ctrl; | ||
236 | }; | ||
237 | |||
238 | struct tegra210_xusb_padctl { | ||
239 | struct tegra_xusb_padctl base; | ||
240 | |||
241 | struct tegra210_xusb_fuse_calibration fuse; | ||
242 | }; | ||
243 | |||
244 | static inline struct tegra210_xusb_padctl * | ||
245 | to_tegra210_xusb_padctl(struct tegra_xusb_padctl *padctl) | ||
246 | { | ||
247 | return container_of(padctl, struct tegra210_xusb_padctl, base); | ||
248 | } | ||
249 | |||
250 | /* must be called under padctl->lock */ | ||
251 | static int tegra210_pex_uphy_enable(struct tegra_xusb_padctl *padctl) | ||
252 | { | ||
253 | struct tegra_xusb_pcie_pad *pcie = to_pcie_pad(padctl->pcie); | ||
254 | unsigned long timeout; | ||
255 | u32 value; | ||
256 | int err; | ||
257 | |||
258 | if (pcie->enable > 0) { | ||
259 | pcie->enable++; | ||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | err = clk_prepare_enable(pcie->pll); | ||
264 | if (err < 0) | ||
265 | return err; | ||
266 | |||
267 | err = reset_control_deassert(pcie->rst); | ||
268 | if (err < 0) | ||
269 | goto disable; | ||
270 | |||
271 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2); | ||
272 | value &= ~(XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_MASK << | ||
273 | XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_SHIFT); | ||
274 | value |= XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_VAL << | ||
275 | XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_SHIFT; | ||
276 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2); | ||
277 | |||
278 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL5); | ||
279 | value &= ~(XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_MASK << | ||
280 | XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_SHIFT); | ||
281 | value |= XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_VAL << | ||
282 | XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_SHIFT; | ||
283 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL5); | ||
284 | |||
285 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1); | ||
286 | value |= XUSB_PADCTL_UPHY_PLL_CTL1_PWR_OVRD; | ||
287 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1); | ||
288 | |||
289 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2); | ||
290 | value |= XUSB_PADCTL_UPHY_PLL_CTL2_CAL_OVRD; | ||
291 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2); | ||
292 | |||
293 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8); | ||
294 | value |= XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_OVRD; | ||
295 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8); | ||
296 | |||
297 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL4); | ||
298 | value &= ~((XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_MASK << | ||
299 | XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_SHIFT) | | ||
300 | (XUSB_PADCTL_UPHY_PLL_CTL4_REFCLK_SEL_MASK << | ||
301 | XUSB_PADCTL_UPHY_PLL_CTL4_REFCLK_SEL_SHIFT)); | ||
302 | value |= (XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_USB_VAL << | ||
303 | XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_SHIFT) | | ||
304 | XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_EN; | ||
305 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL4); | ||
306 | |||
307 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1); | ||
308 | value &= ~((XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_MDIV_MASK << | ||
309 | XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_MDIV_SHIFT) | | ||
310 | (XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_MASK << | ||
311 | XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_SHIFT)); | ||
312 | value |= XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_USB_VAL << | ||
313 | XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_SHIFT; | ||
314 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1); | ||
315 | |||
316 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1); | ||
317 | value &= ~XUSB_PADCTL_UPHY_PLL_CTL1_IDDQ; | ||
318 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1); | ||
319 | |||
320 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1); | ||
321 | value &= ~(XUSB_PADCTL_UPHY_PLL_CTL1_SLEEP_MASK << | ||
322 | XUSB_PADCTL_UPHY_PLL_CTL1_SLEEP_SHIFT); | ||
323 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1); | ||
324 | |||
325 | usleep_range(10, 20); | ||
326 | |||
327 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL4); | ||
328 | value |= XUSB_PADCTL_UPHY_PLL_CTL4_REFCLKBUF_EN; | ||
329 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL4); | ||
330 | |||
331 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2); | ||
332 | value |= XUSB_PADCTL_UPHY_PLL_CTL2_CAL_EN; | ||
333 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2); | ||
334 | |||
335 | timeout = jiffies + msecs_to_jiffies(100); | ||
336 | |||
337 | while (time_before(jiffies, timeout)) { | ||
338 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2); | ||
339 | if (value & XUSB_PADCTL_UPHY_PLL_CTL2_CAL_DONE) | ||
340 | break; | ||
341 | |||
342 | usleep_range(10, 20); | ||
343 | } | ||
344 | |||
345 | if (time_after_eq(jiffies, timeout)) { | ||
346 | err = -ETIMEDOUT; | ||
347 | goto reset; | ||
348 | } | ||
349 | |||
350 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2); | ||
351 | value &= ~XUSB_PADCTL_UPHY_PLL_CTL2_CAL_EN; | ||
352 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2); | ||
353 | |||
354 | timeout = jiffies + msecs_to_jiffies(100); | ||
355 | |||
356 | while (time_before(jiffies, timeout)) { | ||
357 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2); | ||
358 | if (!(value & XUSB_PADCTL_UPHY_PLL_CTL2_CAL_DONE)) | ||
359 | break; | ||
360 | |||
361 | usleep_range(10, 20); | ||
362 | } | ||
363 | |||
364 | if (time_after_eq(jiffies, timeout)) { | ||
365 | err = -ETIMEDOUT; | ||
366 | goto reset; | ||
367 | } | ||
368 | |||
369 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1); | ||
370 | value |= XUSB_PADCTL_UPHY_PLL_CTL1_ENABLE; | ||
371 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1); | ||
372 | |||
373 | timeout = jiffies + msecs_to_jiffies(100); | ||
374 | |||
375 | while (time_before(jiffies, timeout)) { | ||
376 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1); | ||
377 | if (value & XUSB_PADCTL_UPHY_PLL_CTL1_LOCKDET_STATUS) | ||
378 | break; | ||
379 | |||
380 | usleep_range(10, 20); | ||
381 | } | ||
382 | |||
383 | if (time_after_eq(jiffies, timeout)) { | ||
384 | err = -ETIMEDOUT; | ||
385 | goto reset; | ||
386 | } | ||
387 | |||
388 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8); | ||
389 | value |= XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_EN | | ||
390 | XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_CLK_EN; | ||
391 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8); | ||
392 | |||
393 | timeout = jiffies + msecs_to_jiffies(100); | ||
394 | |||
395 | while (time_before(jiffies, timeout)) { | ||
396 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8); | ||
397 | if (value & XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_DONE) | ||
398 | break; | ||
399 | |||
400 | usleep_range(10, 20); | ||
401 | } | ||
402 | |||
403 | if (time_after_eq(jiffies, timeout)) { | ||
404 | err = -ETIMEDOUT; | ||
405 | goto reset; | ||
406 | } | ||
407 | |||
408 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8); | ||
409 | value &= ~XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_EN; | ||
410 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8); | ||
411 | |||
412 | timeout = jiffies + msecs_to_jiffies(100); | ||
413 | |||
414 | while (time_before(jiffies, timeout)) { | ||
415 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8); | ||
416 | if (!(value & XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_DONE)) | ||
417 | break; | ||
418 | |||
419 | usleep_range(10, 20); | ||
420 | } | ||
421 | |||
422 | if (time_after_eq(jiffies, timeout)) { | ||
423 | err = -ETIMEDOUT; | ||
424 | goto reset; | ||
425 | } | ||
426 | |||
427 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8); | ||
428 | value &= ~XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_CLK_EN; | ||
429 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8); | ||
430 | |||
431 | tegra210_xusb_pll_hw_control_enable(); | ||
432 | |||
433 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1); | ||
434 | value &= ~XUSB_PADCTL_UPHY_PLL_CTL1_PWR_OVRD; | ||
435 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1); | ||
436 | |||
437 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2); | ||
438 | value &= ~XUSB_PADCTL_UPHY_PLL_CTL2_CAL_OVRD; | ||
439 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2); | ||
440 | |||
441 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8); | ||
442 | value &= ~XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_OVRD; | ||
443 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8); | ||
444 | |||
445 | usleep_range(10, 20); | ||
446 | |||
447 | tegra210_xusb_pll_hw_sequence_start(); | ||
448 | |||
449 | pcie->enable++; | ||
450 | |||
451 | return 0; | ||
452 | |||
453 | reset: | ||
454 | reset_control_assert(pcie->rst); | ||
455 | disable: | ||
456 | clk_disable_unprepare(pcie->pll); | ||
457 | return err; | ||
458 | } | ||
459 | |||
460 | static void tegra210_pex_uphy_disable(struct tegra_xusb_padctl *padctl) | ||
461 | { | ||
462 | struct tegra_xusb_pcie_pad *pcie = to_pcie_pad(padctl->pcie); | ||
463 | |||
464 | mutex_lock(&padctl->lock); | ||
465 | |||
466 | if (WARN_ON(pcie->enable == 0)) | ||
467 | goto unlock; | ||
468 | |||
469 | if (--pcie->enable > 0) | ||
470 | goto unlock; | ||
471 | |||
472 | reset_control_assert(pcie->rst); | ||
473 | clk_disable_unprepare(pcie->pll); | ||
474 | |||
475 | unlock: | ||
476 | mutex_unlock(&padctl->lock); | ||
477 | } | ||
478 | |||
479 | /* must be called under padctl->lock */ | ||
480 | static int tegra210_sata_uphy_enable(struct tegra_xusb_padctl *padctl, bool usb) | ||
481 | { | ||
482 | struct tegra_xusb_sata_pad *sata = to_sata_pad(padctl->sata); | ||
483 | unsigned long timeout; | ||
484 | u32 value; | ||
485 | int err; | ||
486 | |||
487 | if (sata->enable > 0) { | ||
488 | sata->enable++; | ||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | err = clk_prepare_enable(sata->pll); | ||
493 | if (err < 0) | ||
494 | return err; | ||
495 | |||
496 | err = reset_control_deassert(sata->rst); | ||
497 | if (err < 0) | ||
498 | goto disable; | ||
499 | |||
500 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL2); | ||
501 | value &= ~(XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_MASK << | ||
502 | XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_SHIFT); | ||
503 | value |= XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_VAL << | ||
504 | XUSB_PADCTL_UPHY_PLL_CTL2_CAL_CTRL_SHIFT; | ||
505 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL2); | ||
506 | |||
507 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL5); | ||
508 | value &= ~(XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_MASK << | ||
509 | XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_SHIFT); | ||
510 | value |= XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_VAL << | ||
511 | XUSB_PADCTL_UPHY_PLL_CTL5_DCO_CTRL_SHIFT; | ||
512 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL5); | ||
513 | |||
514 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL1); | ||
515 | value |= XUSB_PADCTL_UPHY_PLL_CTL1_PWR_OVRD; | ||
516 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL1); | ||
517 | |||
518 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL2); | ||
519 | value |= XUSB_PADCTL_UPHY_PLL_CTL2_CAL_OVRD; | ||
520 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL2); | ||
521 | |||
522 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL8); | ||
523 | value |= XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_OVRD; | ||
524 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL8); | ||
525 | |||
526 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL4); | ||
527 | value &= ~((XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_MASK << | ||
528 | XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_SHIFT) | | ||
529 | (XUSB_PADCTL_UPHY_PLL_CTL4_REFCLK_SEL_MASK << | ||
530 | XUSB_PADCTL_UPHY_PLL_CTL4_REFCLK_SEL_SHIFT)); | ||
531 | value |= XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_EN; | ||
532 | |||
533 | if (usb) | ||
534 | value |= (XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_USB_VAL << | ||
535 | XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_SHIFT); | ||
536 | else | ||
537 | value |= (XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_SATA_VAL << | ||
538 | XUSB_PADCTL_UPHY_PLL_CTL4_TXCLKREF_SEL_SHIFT); | ||
539 | |||
540 | /* XXX PLL0_XDIGCLK_EN */ | ||
541 | /* | ||
542 | value &= ~(1 << 19); | ||
543 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL4); | ||
544 | */ | ||
545 | |||
546 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL1); | ||
547 | value &= ~((XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_MDIV_MASK << | ||
548 | XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_MDIV_SHIFT) | | ||
549 | (XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_MASK << | ||
550 | XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_SHIFT)); | ||
551 | |||
552 | if (usb) | ||
553 | value |= XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_USB_VAL << | ||
554 | XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_SHIFT; | ||
555 | else | ||
556 | value |= XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_SATA_VAL << | ||
557 | XUSB_PADCTL_UPHY_PLL_CTL1_FREQ_NDIV_SHIFT; | ||
558 | |||
559 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL1); | ||
560 | |||
561 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL1); | ||
562 | value &= ~XUSB_PADCTL_UPHY_PLL_CTL1_IDDQ; | ||
563 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL1); | ||
564 | |||
565 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL1); | ||
566 | value &= ~(XUSB_PADCTL_UPHY_PLL_CTL1_SLEEP_MASK << | ||
567 | XUSB_PADCTL_UPHY_PLL_CTL1_SLEEP_SHIFT); | ||
568 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL1); | ||
569 | |||
570 | usleep_range(10, 20); | ||
571 | |||
572 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL4); | ||
573 | value |= XUSB_PADCTL_UPHY_PLL_CTL4_REFCLKBUF_EN; | ||
574 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL4); | ||
575 | |||
576 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL2); | ||
577 | value |= XUSB_PADCTL_UPHY_PLL_CTL2_CAL_EN; | ||
578 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL2); | ||
579 | |||
580 | timeout = jiffies + msecs_to_jiffies(100); | ||
581 | |||
582 | while (time_before(jiffies, timeout)) { | ||
583 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL2); | ||
584 | if (value & XUSB_PADCTL_UPHY_PLL_CTL2_CAL_DONE) | ||
585 | break; | ||
586 | |||
587 | usleep_range(10, 20); | ||
588 | } | ||
589 | |||
590 | if (time_after_eq(jiffies, timeout)) { | ||
591 | err = -ETIMEDOUT; | ||
592 | goto reset; | ||
593 | } | ||
594 | |||
595 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL2); | ||
596 | value &= ~XUSB_PADCTL_UPHY_PLL_CTL2_CAL_EN; | ||
597 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL2); | ||
598 | |||
599 | timeout = jiffies + msecs_to_jiffies(100); | ||
600 | |||
601 | while (time_before(jiffies, timeout)) { | ||
602 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL2); | ||
603 | if (!(value & XUSB_PADCTL_UPHY_PLL_CTL2_CAL_DONE)) | ||
604 | break; | ||
605 | |||
606 | usleep_range(10, 20); | ||
607 | } | ||
608 | |||
609 | if (time_after_eq(jiffies, timeout)) { | ||
610 | err = -ETIMEDOUT; | ||
611 | goto reset; | ||
612 | } | ||
613 | |||
614 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL1); | ||
615 | value |= XUSB_PADCTL_UPHY_PLL_CTL1_ENABLE; | ||
616 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL1); | ||
617 | |||
618 | timeout = jiffies + msecs_to_jiffies(100); | ||
619 | |||
620 | while (time_before(jiffies, timeout)) { | ||
621 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL1); | ||
622 | if (value & XUSB_PADCTL_UPHY_PLL_CTL1_LOCKDET_STATUS) | ||
623 | break; | ||
624 | |||
625 | usleep_range(10, 20); | ||
626 | } | ||
627 | |||
628 | if (time_after_eq(jiffies, timeout)) { | ||
629 | err = -ETIMEDOUT; | ||
630 | goto reset; | ||
631 | } | ||
632 | |||
633 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL8); | ||
634 | value |= XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_EN | | ||
635 | XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_CLK_EN; | ||
636 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL8); | ||
637 | |||
638 | timeout = jiffies + msecs_to_jiffies(100); | ||
639 | |||
640 | while (time_before(jiffies, timeout)) { | ||
641 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL8); | ||
642 | if (value & XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_DONE) | ||
643 | break; | ||
644 | |||
645 | usleep_range(10, 20); | ||
646 | } | ||
647 | |||
648 | if (time_after_eq(jiffies, timeout)) { | ||
649 | err = -ETIMEDOUT; | ||
650 | goto reset; | ||
651 | } | ||
652 | |||
653 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL8); | ||
654 | value &= ~XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_EN; | ||
655 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL8); | ||
656 | |||
657 | timeout = jiffies + msecs_to_jiffies(100); | ||
658 | |||
659 | while (time_before(jiffies, timeout)) { | ||
660 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL8); | ||
661 | if (!(value & XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_DONE)) | ||
662 | break; | ||
663 | |||
664 | usleep_range(10, 20); | ||
665 | } | ||
666 | |||
667 | if (time_after_eq(jiffies, timeout)) { | ||
668 | err = -ETIMEDOUT; | ||
669 | goto reset; | ||
670 | } | ||
671 | |||
672 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL8); | ||
673 | value &= ~XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_CLK_EN; | ||
674 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL8); | ||
675 | |||
676 | tegra210_sata_pll_hw_control_enable(); | ||
677 | |||
678 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL1); | ||
679 | value &= ~XUSB_PADCTL_UPHY_PLL_CTL1_PWR_OVRD; | ||
680 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL1); | ||
681 | |||
682 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL2); | ||
683 | value &= ~XUSB_PADCTL_UPHY_PLL_CTL2_CAL_OVRD; | ||
684 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL2); | ||
685 | |||
686 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_S0_CTL8); | ||
687 | value &= ~XUSB_PADCTL_UPHY_PLL_CTL8_RCAL_OVRD; | ||
688 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_S0_CTL8); | ||
689 | |||
690 | usleep_range(10, 20); | ||
691 | |||
692 | tegra210_sata_pll_hw_sequence_start(); | ||
693 | |||
694 | sata->enable++; | ||
695 | |||
696 | return 0; | ||
697 | |||
698 | reset: | ||
699 | reset_control_assert(sata->rst); | ||
700 | disable: | ||
701 | clk_disable_unprepare(sata->pll); | ||
702 | return err; | ||
703 | } | ||
704 | |||
705 | static void tegra210_sata_uphy_disable(struct tegra_xusb_padctl *padctl) | ||
706 | { | ||
707 | struct tegra_xusb_sata_pad *sata = to_sata_pad(padctl->sata); | ||
708 | |||
709 | mutex_lock(&padctl->lock); | ||
710 | |||
711 | if (WARN_ON(sata->enable == 0)) | ||
712 | goto unlock; | ||
713 | |||
714 | if (--sata->enable > 0) | ||
715 | goto unlock; | ||
716 | |||
717 | reset_control_assert(sata->rst); | ||
718 | clk_disable_unprepare(sata->pll); | ||
719 | |||
720 | unlock: | ||
721 | mutex_unlock(&padctl->lock); | ||
722 | } | ||
723 | |||
724 | static int tegra210_xusb_padctl_enable(struct tegra_xusb_padctl *padctl) | ||
725 | { | ||
726 | u32 value; | ||
727 | |||
728 | mutex_lock(&padctl->lock); | ||
729 | |||
730 | if (padctl->enable++ > 0) | ||
731 | goto out; | ||
732 | |||
733 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); | ||
734 | value &= ~XUSB_PADCTL_ELPG_PROGRAM1_AUX_MUX_LP0_CLAMP_EN; | ||
735 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1); | ||
736 | |||
737 | usleep_range(100, 200); | ||
738 | |||
739 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); | ||
740 | value &= ~XUSB_PADCTL_ELPG_PROGRAM1_AUX_MUX_LP0_CLAMP_EN_EARLY; | ||
741 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1); | ||
742 | |||
743 | usleep_range(100, 200); | ||
744 | |||
745 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); | ||
746 | value &= ~XUSB_PADCTL_ELPG_PROGRAM1_AUX_MUX_LP0_VCORE_DOWN; | ||
747 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1); | ||
748 | |||
749 | out: | ||
750 | mutex_unlock(&padctl->lock); | ||
751 | return 0; | ||
752 | } | ||
753 | |||
754 | static int tegra210_xusb_padctl_disable(struct tegra_xusb_padctl *padctl) | ||
755 | { | ||
756 | u32 value; | ||
757 | |||
758 | mutex_lock(&padctl->lock); | ||
759 | |||
760 | if (WARN_ON(padctl->enable == 0)) | ||
761 | goto out; | ||
762 | |||
763 | if (--padctl->enable > 0) | ||
764 | goto out; | ||
765 | |||
766 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); | ||
767 | value |= XUSB_PADCTL_ELPG_PROGRAM1_AUX_MUX_LP0_VCORE_DOWN; | ||
768 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1); | ||
769 | |||
770 | usleep_range(100, 200); | ||
771 | |||
772 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); | ||
773 | value |= XUSB_PADCTL_ELPG_PROGRAM1_AUX_MUX_LP0_CLAMP_EN_EARLY; | ||
774 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1); | ||
775 | |||
776 | usleep_range(100, 200); | ||
777 | |||
778 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); | ||
779 | value |= XUSB_PADCTL_ELPG_PROGRAM1_AUX_MUX_LP0_CLAMP_EN; | ||
780 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1); | ||
781 | |||
782 | out: | ||
783 | mutex_unlock(&padctl->lock); | ||
784 | return 0; | ||
785 | } | ||
786 | |||
787 | static int tegra210_hsic_set_idle(struct tegra_xusb_padctl *padctl, | ||
788 | unsigned int index, bool idle) | ||
789 | { | ||
790 | u32 value; | ||
791 | |||
792 | value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL0(index)); | ||
793 | |||
794 | value &= ~(XUSB_PADCTL_HSIC_PAD_CTL0_RPU_DATA0 | | ||
795 | XUSB_PADCTL_HSIC_PAD_CTL0_RPU_DATA1 | | ||
796 | XUSB_PADCTL_HSIC_PAD_CTL0_RPD_STROBE); | ||
797 | |||
798 | if (idle) | ||
799 | value |= XUSB_PADCTL_HSIC_PAD_CTL0_RPD_DATA0 | | ||
800 | XUSB_PADCTL_HSIC_PAD_CTL0_RPD_DATA1 | | ||
801 | XUSB_PADCTL_HSIC_PAD_CTL0_RPU_STROBE; | ||
802 | else | ||
803 | value &= ~(XUSB_PADCTL_HSIC_PAD_CTL0_RPD_DATA0 | | ||
804 | XUSB_PADCTL_HSIC_PAD_CTL0_RPD_DATA1 | | ||
805 | XUSB_PADCTL_HSIC_PAD_CTL0_RPU_STROBE); | ||
806 | |||
807 | padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL0(index)); | ||
808 | |||
809 | return 0; | ||
810 | } | ||
811 | |||
812 | static int tegra210_usb3_set_lfps_detect(struct tegra_xusb_padctl *padctl, | ||
813 | unsigned int index, bool enable) | ||
814 | { | ||
815 | struct tegra_xusb_port *port; | ||
816 | struct tegra_xusb_lane *lane; | ||
817 | u32 value, offset; | ||
818 | |||
819 | port = tegra_xusb_find_port(padctl, "usb3", index); | ||
820 | if (!port) | ||
821 | return -ENODEV; | ||
822 | |||
823 | lane = port->lane; | ||
824 | |||
825 | if (lane->pad == padctl->pcie) | ||
826 | offset = XUSB_PADCTL_UPHY_MISC_PAD_PX_CTL1(lane->index); | ||
827 | else | ||
828 | offset = XUSB_PADCTL_UPHY_MISC_PAD_S0_CTL1; | ||
829 | |||
830 | value = padctl_readl(padctl, offset); | ||
831 | |||
832 | value &= ~((XUSB_PADCTL_UPHY_MISC_PAD_CTL1_AUX_RX_IDLE_MODE_MASK << | ||
833 | XUSB_PADCTL_UPHY_MISC_PAD_CTL1_AUX_RX_IDLE_MODE_SHIFT) | | ||
834 | XUSB_PADCTL_UPHY_MISC_PAD_CTL1_AUX_RX_TERM_EN | | ||
835 | XUSB_PADCTL_UPHY_MISC_PAD_CTL1_AUX_RX_MODE_OVRD); | ||
836 | |||
837 | if (!enable) { | ||
838 | value |= (XUSB_PADCTL_UPHY_MISC_PAD_CTL1_AUX_RX_IDLE_MODE_VAL << | ||
839 | XUSB_PADCTL_UPHY_MISC_PAD_CTL1_AUX_RX_IDLE_MODE_SHIFT) | | ||
840 | XUSB_PADCTL_UPHY_MISC_PAD_CTL1_AUX_RX_TERM_EN | | ||
841 | XUSB_PADCTL_UPHY_MISC_PAD_CTL1_AUX_RX_MODE_OVRD; | ||
842 | } | ||
843 | |||
844 | padctl_writel(padctl, value, offset); | ||
845 | |||
846 | return 0; | ||
847 | } | ||
848 | |||
849 | #define TEGRA210_LANE(_name, _offset, _shift, _mask, _type) \ | ||
850 | { \ | ||
851 | .name = _name, \ | ||
852 | .offset = _offset, \ | ||
853 | .shift = _shift, \ | ||
854 | .mask = _mask, \ | ||
855 | .num_funcs = ARRAY_SIZE(tegra210_##_type##_functions), \ | ||
856 | .funcs = tegra210_##_type##_functions, \ | ||
857 | } | ||
858 | |||
859 | static const char *tegra210_usb2_functions[] = { | ||
860 | "snps", | ||
861 | "xusb", | ||
862 | "uart" | ||
863 | }; | ||
864 | |||
865 | static const struct tegra_xusb_lane_soc tegra210_usb2_lanes[] = { | ||
866 | TEGRA210_LANE("usb2-0", 0x004, 0, 0x3, usb2), | ||
867 | TEGRA210_LANE("usb2-1", 0x004, 2, 0x3, usb2), | ||
868 | TEGRA210_LANE("usb2-2", 0x004, 4, 0x3, usb2), | ||
869 | TEGRA210_LANE("usb2-3", 0x004, 6, 0x3, usb2), | ||
870 | }; | ||
871 | |||
872 | static struct tegra_xusb_lane * | ||
873 | tegra210_usb2_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, | ||
874 | unsigned int index) | ||
875 | { | ||
876 | struct tegra_xusb_usb2_lane *usb2; | ||
877 | int err; | ||
878 | |||
879 | usb2 = kzalloc(sizeof(*usb2), GFP_KERNEL); | ||
880 | if (!usb2) | ||
881 | return ERR_PTR(-ENOMEM); | ||
882 | |||
883 | INIT_LIST_HEAD(&usb2->base.list); | ||
884 | usb2->base.soc = &pad->soc->lanes[index]; | ||
885 | usb2->base.index = index; | ||
886 | usb2->base.pad = pad; | ||
887 | usb2->base.np = np; | ||
888 | |||
889 | err = tegra_xusb_lane_parse_dt(&usb2->base, np); | ||
890 | if (err < 0) { | ||
891 | kfree(usb2); | ||
892 | return ERR_PTR(err); | ||
893 | } | ||
894 | |||
895 | return &usb2->base; | ||
896 | } | ||
897 | |||
898 | static void tegra210_usb2_lane_remove(struct tegra_xusb_lane *lane) | ||
899 | { | ||
900 | struct tegra_xusb_usb2_lane *usb2 = to_usb2_lane(lane); | ||
901 | |||
902 | kfree(usb2); | ||
903 | } | ||
904 | |||
905 | static const struct tegra_xusb_lane_ops tegra210_usb2_lane_ops = { | ||
906 | .probe = tegra210_usb2_lane_probe, | ||
907 | .remove = tegra210_usb2_lane_remove, | ||
908 | }; | ||
909 | |||
910 | static int tegra210_usb2_phy_init(struct phy *phy) | ||
911 | { | ||
912 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
913 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
914 | u32 value; | ||
915 | |||
916 | value = padctl_readl(padctl, XUSB_PADCTL_USB2_PAD_MUX); | ||
917 | value &= ~(XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_MASK << | ||
918 | XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_SHIFT); | ||
919 | value |= XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_XUSB << | ||
920 | XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_SHIFT; | ||
921 | padctl_writel(padctl, value, XUSB_PADCTL_USB2_PAD_MUX); | ||
922 | |||
923 | return tegra210_xusb_padctl_enable(padctl); | ||
924 | } | ||
925 | |||
926 | static int tegra210_usb2_phy_exit(struct phy *phy) | ||
927 | { | ||
928 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
929 | |||
930 | return tegra210_xusb_padctl_disable(lane->pad->padctl); | ||
931 | } | ||
932 | |||
933 | static int tegra210_usb2_phy_power_on(struct phy *phy) | ||
934 | { | ||
935 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
936 | struct tegra_xusb_usb2_lane *usb2 = to_usb2_lane(lane); | ||
937 | struct tegra_xusb_usb2_pad *pad = to_usb2_pad(lane->pad); | ||
938 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
939 | struct tegra210_xusb_padctl *priv; | ||
940 | struct tegra_xusb_usb2_port *port; | ||
941 | unsigned int index = lane->index; | ||
942 | u32 value; | ||
943 | int err; | ||
944 | |||
945 | port = tegra_xusb_find_usb2_port(padctl, index); | ||
946 | if (!port) { | ||
947 | dev_err(&phy->dev, "no port found for USB2 lane %u\n", index); | ||
948 | return -ENODEV; | ||
949 | } | ||
950 | |||
951 | priv = to_tegra210_xusb_padctl(padctl); | ||
952 | |||
953 | value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); | ||
954 | value &= ~((XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_MASK << | ||
955 | XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_SHIFT) | | ||
956 | (XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_MASK << | ||
957 | XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_SHIFT)); | ||
958 | value |= (XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_VAL << | ||
959 | XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_DISCON_LEVEL_SHIFT); | ||
960 | |||
961 | if (tegra_sku_info.revision < TEGRA_REVISION_A02) | ||
962 | value |= | ||
963 | (XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_VAL << | ||
964 | XUSB_PADCTL_USB2_BIAS_PAD_CTL0_HS_SQUELCH_LEVEL_SHIFT); | ||
965 | |||
966 | padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); | ||
967 | |||
968 | value = padctl_readl(padctl, XUSB_PADCTL_USB2_PORT_CAP); | ||
969 | value &= ~XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_MASK(index); | ||
970 | value |= XUSB_PADCTL_USB2_PORT_CAP_PORTX_CAP_HOST(index); | ||
971 | padctl_writel(padctl, value, XUSB_PADCTL_USB2_PORT_CAP); | ||
972 | |||
973 | value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index)); | ||
974 | value &= ~((XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_MASK << | ||
975 | XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_SHIFT) | | ||
976 | XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD | | ||
977 | XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD2 | | ||
978 | XUSB_PADCTL_USB2_OTG_PAD_CTL0_PD_ZI); | ||
979 | value |= (priv->fuse.hs_curr_level[index] + | ||
980 | usb2->hs_curr_level_offset) << | ||
981 | XUSB_PADCTL_USB2_OTG_PAD_CTL0_HS_CURR_LEVEL_SHIFT; | ||
982 | padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL0(index)); | ||
983 | |||
984 | value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index)); | ||
985 | value &= ~((XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_MASK << | ||
986 | XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_SHIFT) | | ||
987 | (XUSB_PADCTL_USB2_OTG_PAD_CTL1_RPD_CTRL_MASK << | ||
988 | XUSB_PADCTL_USB2_OTG_PAD_CTL1_RPD_CTRL_SHIFT) | | ||
989 | XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_DR | | ||
990 | XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_CHRP_OVRD | | ||
991 | XUSB_PADCTL_USB2_OTG_PAD_CTL1_PD_DISC_OVRD); | ||
992 | value |= (priv->fuse.hs_term_range_adj << | ||
993 | XUSB_PADCTL_USB2_OTG_PAD_CTL1_TERM_RANGE_ADJ_SHIFT) | | ||
994 | (priv->fuse.rpd_ctrl << | ||
995 | XUSB_PADCTL_USB2_OTG_PAD_CTL1_RPD_CTRL_SHIFT); | ||
996 | padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index)); | ||
997 | |||
998 | value = padctl_readl(padctl, | ||
999 | XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL1(index)); | ||
1000 | value &= ~(XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV_MASK << | ||
1001 | XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_LEV_SHIFT); | ||
1002 | value |= XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPAD_CTL1_VREG_FIX18; | ||
1003 | padctl_writel(padctl, value, | ||
1004 | XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL1(index)); | ||
1005 | |||
1006 | err = regulator_enable(port->supply); | ||
1007 | if (err) | ||
1008 | return err; | ||
1009 | |||
1010 | mutex_lock(&padctl->lock); | ||
1011 | |||
1012 | if (pad->enable > 0) { | ||
1013 | pad->enable++; | ||
1014 | mutex_unlock(&padctl->lock); | ||
1015 | return 0; | ||
1016 | } | ||
1017 | |||
1018 | err = clk_prepare_enable(pad->clk); | ||
1019 | if (err) | ||
1020 | goto disable_regulator; | ||
1021 | |||
1022 | value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); | ||
1023 | value &= ~((XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_MASK << | ||
1024 | XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_SHIFT) | | ||
1025 | (XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_MASK << | ||
1026 | XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_SHIFT)); | ||
1027 | value |= (XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_VAL << | ||
1028 | XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_SHIFT) | | ||
1029 | (XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_VAL << | ||
1030 | XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_DONE_RESET_TIMER_SHIFT); | ||
1031 | padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); | ||
1032 | |||
1033 | value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); | ||
1034 | value &= ~XUSB_PADCTL_USB2_BIAS_PAD_CTL0_PD; | ||
1035 | padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); | ||
1036 | |||
1037 | udelay(1); | ||
1038 | |||
1039 | value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); | ||
1040 | value &= ~XUSB_PADCTL_USB2_BIAS_PAD_CTL1_PD_TRK; | ||
1041 | padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1); | ||
1042 | |||
1043 | udelay(50); | ||
1044 | |||
1045 | clk_disable_unprepare(pad->clk); | ||
1046 | |||
1047 | pad->enable++; | ||
1048 | mutex_unlock(&padctl->lock); | ||
1049 | |||
1050 | return 0; | ||
1051 | |||
1052 | disable_regulator: | ||
1053 | regulator_disable(port->supply); | ||
1054 | mutex_unlock(&padctl->lock); | ||
1055 | return err; | ||
1056 | } | ||
1057 | |||
1058 | static int tegra210_usb2_phy_power_off(struct phy *phy) | ||
1059 | { | ||
1060 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1061 | struct tegra_xusb_usb2_pad *pad = to_usb2_pad(lane->pad); | ||
1062 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
1063 | struct tegra_xusb_usb2_port *port; | ||
1064 | u32 value; | ||
1065 | |||
1066 | port = tegra_xusb_find_usb2_port(padctl, lane->index); | ||
1067 | if (!port) { | ||
1068 | dev_err(&phy->dev, "no port found for USB2 lane %u\n", | ||
1069 | lane->index); | ||
1070 | return -ENODEV; | ||
1071 | } | ||
1072 | |||
1073 | mutex_lock(&padctl->lock); | ||
1074 | |||
1075 | if (WARN_ON(pad->enable == 0)) | ||
1076 | goto out; | ||
1077 | |||
1078 | if (--pad->enable > 0) | ||
1079 | goto out; | ||
1080 | |||
1081 | value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); | ||
1082 | value |= XUSB_PADCTL_USB2_BIAS_PAD_CTL0_PD; | ||
1083 | padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0); | ||
1084 | |||
1085 | out: | ||
1086 | regulator_disable(port->supply); | ||
1087 | mutex_unlock(&padctl->lock); | ||
1088 | return 0; | ||
1089 | } | ||
1090 | |||
1091 | static const struct phy_ops tegra210_usb2_phy_ops = { | ||
1092 | .init = tegra210_usb2_phy_init, | ||
1093 | .exit = tegra210_usb2_phy_exit, | ||
1094 | .power_on = tegra210_usb2_phy_power_on, | ||
1095 | .power_off = tegra210_usb2_phy_power_off, | ||
1096 | .owner = THIS_MODULE, | ||
1097 | }; | ||
1098 | |||
1099 | static struct tegra_xusb_pad * | ||
1100 | tegra210_usb2_pad_probe(struct tegra_xusb_padctl *padctl, | ||
1101 | const struct tegra_xusb_pad_soc *soc, | ||
1102 | struct device_node *np) | ||
1103 | { | ||
1104 | struct tegra_xusb_usb2_pad *usb2; | ||
1105 | struct tegra_xusb_pad *pad; | ||
1106 | int err; | ||
1107 | |||
1108 | usb2 = kzalloc(sizeof(*usb2), GFP_KERNEL); | ||
1109 | if (!usb2) | ||
1110 | return ERR_PTR(-ENOMEM); | ||
1111 | |||
1112 | pad = &usb2->base; | ||
1113 | pad->ops = &tegra210_usb2_lane_ops; | ||
1114 | pad->soc = soc; | ||
1115 | |||
1116 | err = tegra_xusb_pad_init(pad, padctl, np); | ||
1117 | if (err < 0) { | ||
1118 | kfree(usb2); | ||
1119 | goto out; | ||
1120 | } | ||
1121 | |||
1122 | usb2->clk = devm_clk_get(&pad->dev, "trk"); | ||
1123 | if (IS_ERR(usb2->clk)) { | ||
1124 | err = PTR_ERR(usb2->clk); | ||
1125 | dev_err(&pad->dev, "failed to get trk clock: %d\n", err); | ||
1126 | goto unregister; | ||
1127 | } | ||
1128 | |||
1129 | err = tegra_xusb_pad_register(pad, &tegra210_usb2_phy_ops); | ||
1130 | if (err < 0) | ||
1131 | goto unregister; | ||
1132 | |||
1133 | dev_set_drvdata(&pad->dev, pad); | ||
1134 | |||
1135 | return pad; | ||
1136 | |||
1137 | unregister: | ||
1138 | device_unregister(&pad->dev); | ||
1139 | out: | ||
1140 | return ERR_PTR(err); | ||
1141 | } | ||
1142 | |||
1143 | static void tegra210_usb2_pad_remove(struct tegra_xusb_pad *pad) | ||
1144 | { | ||
1145 | struct tegra_xusb_usb2_pad *usb2 = to_usb2_pad(pad); | ||
1146 | |||
1147 | kfree(usb2); | ||
1148 | } | ||
1149 | |||
1150 | static const struct tegra_xusb_pad_ops tegra210_usb2_ops = { | ||
1151 | .probe = tegra210_usb2_pad_probe, | ||
1152 | .remove = tegra210_usb2_pad_remove, | ||
1153 | }; | ||
1154 | |||
1155 | static const struct tegra_xusb_pad_soc tegra210_usb2_pad = { | ||
1156 | .name = "usb2", | ||
1157 | .num_lanes = ARRAY_SIZE(tegra210_usb2_lanes), | ||
1158 | .lanes = tegra210_usb2_lanes, | ||
1159 | .ops = &tegra210_usb2_ops, | ||
1160 | }; | ||
1161 | |||
1162 | static const char *tegra210_hsic_functions[] = { | ||
1163 | "snps", | ||
1164 | "xusb", | ||
1165 | }; | ||
1166 | |||
1167 | static const struct tegra_xusb_lane_soc tegra210_hsic_lanes[] = { | ||
1168 | TEGRA210_LANE("hsic-0", 0x004, 14, 0x1, hsic), | ||
1169 | }; | ||
1170 | |||
1171 | static struct tegra_xusb_lane * | ||
1172 | tegra210_hsic_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, | ||
1173 | unsigned int index) | ||
1174 | { | ||
1175 | struct tegra_xusb_hsic_lane *hsic; | ||
1176 | int err; | ||
1177 | |||
1178 | hsic = kzalloc(sizeof(*hsic), GFP_KERNEL); | ||
1179 | if (!hsic) | ||
1180 | return ERR_PTR(-ENOMEM); | ||
1181 | |||
1182 | INIT_LIST_HEAD(&hsic->base.list); | ||
1183 | hsic->base.soc = &pad->soc->lanes[index]; | ||
1184 | hsic->base.index = index; | ||
1185 | hsic->base.pad = pad; | ||
1186 | hsic->base.np = np; | ||
1187 | |||
1188 | err = tegra_xusb_lane_parse_dt(&hsic->base, np); | ||
1189 | if (err < 0) { | ||
1190 | kfree(hsic); | ||
1191 | return ERR_PTR(err); | ||
1192 | } | ||
1193 | |||
1194 | return &hsic->base; | ||
1195 | } | ||
1196 | |||
1197 | static void tegra210_hsic_lane_remove(struct tegra_xusb_lane *lane) | ||
1198 | { | ||
1199 | struct tegra_xusb_hsic_lane *hsic = to_hsic_lane(lane); | ||
1200 | |||
1201 | kfree(hsic); | ||
1202 | } | ||
1203 | |||
1204 | static const struct tegra_xusb_lane_ops tegra210_hsic_lane_ops = { | ||
1205 | .probe = tegra210_hsic_lane_probe, | ||
1206 | .remove = tegra210_hsic_lane_remove, | ||
1207 | }; | ||
1208 | |||
1209 | static int tegra210_hsic_phy_init(struct phy *phy) | ||
1210 | { | ||
1211 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1212 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
1213 | u32 value; | ||
1214 | |||
1215 | value = padctl_readl(padctl, XUSB_PADCTL_USB2_PAD_MUX); | ||
1216 | value &= ~(XUSB_PADCTL_USB2_PAD_MUX_HSIC_PAD_TRK_MASK << | ||
1217 | XUSB_PADCTL_USB2_PAD_MUX_HSIC_PAD_TRK_SHIFT); | ||
1218 | value |= XUSB_PADCTL_USB2_PAD_MUX_HSIC_PAD_TRK_XUSB << | ||
1219 | XUSB_PADCTL_USB2_PAD_MUX_HSIC_PAD_TRK_SHIFT; | ||
1220 | padctl_writel(padctl, value, XUSB_PADCTL_USB2_PAD_MUX); | ||
1221 | |||
1222 | return tegra210_xusb_padctl_enable(padctl); | ||
1223 | } | ||
1224 | |||
1225 | static int tegra210_hsic_phy_exit(struct phy *phy) | ||
1226 | { | ||
1227 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1228 | |||
1229 | return tegra210_xusb_padctl_disable(lane->pad->padctl); | ||
1230 | } | ||
1231 | |||
1232 | static int tegra210_hsic_phy_power_on(struct phy *phy) | ||
1233 | { | ||
1234 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1235 | struct tegra_xusb_hsic_lane *hsic = to_hsic_lane(lane); | ||
1236 | struct tegra_xusb_hsic_pad *pad = to_hsic_pad(lane->pad); | ||
1237 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
1238 | struct tegra210_xusb_padctl *priv; | ||
1239 | unsigned int index = lane->index; | ||
1240 | u32 value; | ||
1241 | int err; | ||
1242 | |||
1243 | priv = to_tegra210_xusb_padctl(padctl); | ||
1244 | |||
1245 | err = regulator_enable(pad->supply); | ||
1246 | if (err) | ||
1247 | return err; | ||
1248 | |||
1249 | padctl_writel(padctl, hsic->strobe_trim, | ||
1250 | XUSB_PADCTL_HSIC_STRB_TRIM_CONTROL); | ||
1251 | |||
1252 | value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL1(index)); | ||
1253 | value &= ~(XUSB_PADCTL_HSIC_PAD_CTL1_TX_RTUNEP_MASK << | ||
1254 | XUSB_PADCTL_HSIC_PAD_CTL1_TX_RTUNEP_SHIFT); | ||
1255 | value |= (hsic->tx_rtune_p << | ||
1256 | XUSB_PADCTL_HSIC_PAD_CTL1_TX_RTUNEP_SHIFT); | ||
1257 | padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL1(index)); | ||
1258 | |||
1259 | value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL2(index)); | ||
1260 | value &= ~((XUSB_PADCTL_HSIC_PAD_CTL2_RX_STROBE_TRIM_MASK << | ||
1261 | XUSB_PADCTL_HSIC_PAD_CTL2_RX_STROBE_TRIM_SHIFT) | | ||
1262 | (XUSB_PADCTL_HSIC_PAD_CTL2_RX_DATA_TRIM_MASK << | ||
1263 | XUSB_PADCTL_HSIC_PAD_CTL2_RX_DATA_TRIM_SHIFT)); | ||
1264 | value |= (hsic->rx_strobe_trim << | ||
1265 | XUSB_PADCTL_HSIC_PAD_CTL2_RX_STROBE_TRIM_SHIFT) | | ||
1266 | (hsic->rx_data_trim << | ||
1267 | XUSB_PADCTL_HSIC_PAD_CTL2_RX_DATA_TRIM_SHIFT); | ||
1268 | padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL2(index)); | ||
1269 | |||
1270 | value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL0(index)); | ||
1271 | value &= ~(XUSB_PADCTL_HSIC_PAD_CTL0_RPU_DATA0 | | ||
1272 | XUSB_PADCTL_HSIC_PAD_CTL0_RPU_DATA1 | | ||
1273 | XUSB_PADCTL_HSIC_PAD_CTL0_RPU_STROBE | | ||
1274 | XUSB_PADCTL_HSIC_PAD_CTL0_PD_RX_DATA0 | | ||
1275 | XUSB_PADCTL_HSIC_PAD_CTL0_PD_RX_DATA1 | | ||
1276 | XUSB_PADCTL_HSIC_PAD_CTL0_PD_RX_STROBE | | ||
1277 | XUSB_PADCTL_HSIC_PAD_CTL0_PD_ZI_DATA0 | | ||
1278 | XUSB_PADCTL_HSIC_PAD_CTL0_PD_ZI_DATA1 | | ||
1279 | XUSB_PADCTL_HSIC_PAD_CTL0_PD_ZI_STROBE | | ||
1280 | XUSB_PADCTL_HSIC_PAD_CTL0_PD_TX_DATA0 | | ||
1281 | XUSB_PADCTL_HSIC_PAD_CTL0_PD_TX_DATA1 | | ||
1282 | XUSB_PADCTL_HSIC_PAD_CTL0_PD_TX_STROBE); | ||
1283 | value |= XUSB_PADCTL_HSIC_PAD_CTL0_RPD_DATA0 | | ||
1284 | XUSB_PADCTL_HSIC_PAD_CTL0_RPD_DATA1 | | ||
1285 | XUSB_PADCTL_HSIC_PAD_CTL0_RPD_STROBE; | ||
1286 | padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL0(index)); | ||
1287 | |||
1288 | err = clk_prepare_enable(pad->clk); | ||
1289 | if (err) | ||
1290 | goto disable; | ||
1291 | |||
1292 | value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PAD_TRK_CTL); | ||
1293 | value &= ~((XUSB_PADCTL_HSIC_PAD_TRK_CTL_TRK_START_TIMER_MASK << | ||
1294 | XUSB_PADCTL_HSIC_PAD_TRK_CTL_TRK_START_TIMER_SHIFT) | | ||
1295 | (XUSB_PADCTL_HSIC_PAD_TRK_CTL_TRK_DONE_RESET_TIMER_MASK << | ||
1296 | XUSB_PADCTL_HSIC_PAD_TRK_CTL_TRK_DONE_RESET_TIMER_SHIFT)); | ||
1297 | value |= (XUSB_PADCTL_HSIC_PAD_TRK_CTL_TRK_START_TIMER_VAL << | ||
1298 | XUSB_PADCTL_HSIC_PAD_TRK_CTL_TRK_START_TIMER_SHIFT) | | ||
1299 | (XUSB_PADCTL_HSIC_PAD_TRK_CTL_TRK_DONE_RESET_TIMER_VAL << | ||
1300 | XUSB_PADCTL_HSIC_PAD_TRK_CTL_TRK_DONE_RESET_TIMER_SHIFT); | ||
1301 | padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PAD_TRK_CTL); | ||
1302 | |||
1303 | udelay(1); | ||
1304 | |||
1305 | value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PAD_TRK_CTL); | ||
1306 | value &= ~XUSB_PADCTL_HSIC_PAD_TRK_CTL_PD_TRK; | ||
1307 | padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PAD_TRK_CTL); | ||
1308 | |||
1309 | udelay(50); | ||
1310 | |||
1311 | clk_disable_unprepare(pad->clk); | ||
1312 | |||
1313 | return 0; | ||
1314 | |||
1315 | disable: | ||
1316 | regulator_disable(pad->supply); | ||
1317 | return err; | ||
1318 | } | ||
1319 | |||
1320 | static int tegra210_hsic_phy_power_off(struct phy *phy) | ||
1321 | { | ||
1322 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1323 | struct tegra_xusb_hsic_pad *pad = to_hsic_pad(lane->pad); | ||
1324 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
1325 | unsigned int index = lane->index; | ||
1326 | u32 value; | ||
1327 | |||
1328 | value = padctl_readl(padctl, XUSB_PADCTL_HSIC_PADX_CTL0(index)); | ||
1329 | value |= XUSB_PADCTL_HSIC_PAD_CTL0_PD_RX_DATA0 | | ||
1330 | XUSB_PADCTL_HSIC_PAD_CTL0_PD_RX_DATA1 | | ||
1331 | XUSB_PADCTL_HSIC_PAD_CTL0_PD_RX_STROBE | | ||
1332 | XUSB_PADCTL_HSIC_PAD_CTL0_PD_ZI_DATA0 | | ||
1333 | XUSB_PADCTL_HSIC_PAD_CTL0_PD_ZI_DATA1 | | ||
1334 | XUSB_PADCTL_HSIC_PAD_CTL0_PD_ZI_STROBE | | ||
1335 | XUSB_PADCTL_HSIC_PAD_CTL0_PD_TX_DATA0 | | ||
1336 | XUSB_PADCTL_HSIC_PAD_CTL0_PD_TX_DATA1 | | ||
1337 | XUSB_PADCTL_HSIC_PAD_CTL0_PD_TX_STROBE; | ||
1338 | padctl_writel(padctl, value, XUSB_PADCTL_HSIC_PADX_CTL1(index)); | ||
1339 | |||
1340 | regulator_disable(pad->supply); | ||
1341 | |||
1342 | return 0; | ||
1343 | } | ||
1344 | |||
1345 | static const struct phy_ops tegra210_hsic_phy_ops = { | ||
1346 | .init = tegra210_hsic_phy_init, | ||
1347 | .exit = tegra210_hsic_phy_exit, | ||
1348 | .power_on = tegra210_hsic_phy_power_on, | ||
1349 | .power_off = tegra210_hsic_phy_power_off, | ||
1350 | .owner = THIS_MODULE, | ||
1351 | }; | ||
1352 | |||
1353 | static struct tegra_xusb_pad * | ||
1354 | tegra210_hsic_pad_probe(struct tegra_xusb_padctl *padctl, | ||
1355 | const struct tegra_xusb_pad_soc *soc, | ||
1356 | struct device_node *np) | ||
1357 | { | ||
1358 | struct tegra_xusb_hsic_pad *hsic; | ||
1359 | struct tegra_xusb_pad *pad; | ||
1360 | int err; | ||
1361 | |||
1362 | hsic = kzalloc(sizeof(*hsic), GFP_KERNEL); | ||
1363 | if (!hsic) | ||
1364 | return ERR_PTR(-ENOMEM); | ||
1365 | |||
1366 | pad = &hsic->base; | ||
1367 | pad->ops = &tegra210_hsic_lane_ops; | ||
1368 | pad->soc = soc; | ||
1369 | |||
1370 | err = tegra_xusb_pad_init(pad, padctl, np); | ||
1371 | if (err < 0) { | ||
1372 | kfree(hsic); | ||
1373 | goto out; | ||
1374 | } | ||
1375 | |||
1376 | hsic->clk = devm_clk_get(&pad->dev, "trk"); | ||
1377 | if (IS_ERR(hsic->clk)) { | ||
1378 | err = PTR_ERR(hsic->clk); | ||
1379 | dev_err(&pad->dev, "failed to get trk clock: %d\n", err); | ||
1380 | goto unregister; | ||
1381 | } | ||
1382 | |||
1383 | err = tegra_xusb_pad_register(pad, &tegra210_hsic_phy_ops); | ||
1384 | if (err < 0) | ||
1385 | goto unregister; | ||
1386 | |||
1387 | dev_set_drvdata(&pad->dev, pad); | ||
1388 | |||
1389 | return pad; | ||
1390 | |||
1391 | unregister: | ||
1392 | device_unregister(&pad->dev); | ||
1393 | out: | ||
1394 | return ERR_PTR(err); | ||
1395 | } | ||
1396 | |||
1397 | static void tegra210_hsic_pad_remove(struct tegra_xusb_pad *pad) | ||
1398 | { | ||
1399 | struct tegra_xusb_hsic_pad *hsic = to_hsic_pad(pad); | ||
1400 | |||
1401 | kfree(hsic); | ||
1402 | } | ||
1403 | |||
1404 | static const struct tegra_xusb_pad_ops tegra210_hsic_ops = { | ||
1405 | .probe = tegra210_hsic_pad_probe, | ||
1406 | .remove = tegra210_hsic_pad_remove, | ||
1407 | }; | ||
1408 | |||
1409 | static const struct tegra_xusb_pad_soc tegra210_hsic_pad = { | ||
1410 | .name = "hsic", | ||
1411 | .num_lanes = ARRAY_SIZE(tegra210_hsic_lanes), | ||
1412 | .lanes = tegra210_hsic_lanes, | ||
1413 | .ops = &tegra210_hsic_ops, | ||
1414 | }; | ||
1415 | |||
1416 | static const char *tegra210_pcie_functions[] = { | ||
1417 | "pcie-x1", | ||
1418 | "usb3-ss", | ||
1419 | "sata", | ||
1420 | "pcie-x4", | ||
1421 | }; | ||
1422 | |||
1423 | static const struct tegra_xusb_lane_soc tegra210_pcie_lanes[] = { | ||
1424 | TEGRA210_LANE("pcie-0", 0x028, 12, 0x3, pcie), | ||
1425 | TEGRA210_LANE("pcie-1", 0x028, 14, 0x3, pcie), | ||
1426 | TEGRA210_LANE("pcie-2", 0x028, 16, 0x3, pcie), | ||
1427 | TEGRA210_LANE("pcie-3", 0x028, 18, 0x3, pcie), | ||
1428 | TEGRA210_LANE("pcie-4", 0x028, 20, 0x3, pcie), | ||
1429 | TEGRA210_LANE("pcie-5", 0x028, 22, 0x3, pcie), | ||
1430 | TEGRA210_LANE("pcie-6", 0x028, 24, 0x3, pcie), | ||
1431 | }; | ||
1432 | |||
1433 | static struct tegra_xusb_lane * | ||
1434 | tegra210_pcie_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, | ||
1435 | unsigned int index) | ||
1436 | { | ||
1437 | struct tegra_xusb_pcie_lane *pcie; | ||
1438 | int err; | ||
1439 | |||
1440 | pcie = kzalloc(sizeof(*pcie), GFP_KERNEL); | ||
1441 | if (!pcie) | ||
1442 | return ERR_PTR(-ENOMEM); | ||
1443 | |||
1444 | INIT_LIST_HEAD(&pcie->base.list); | ||
1445 | pcie->base.soc = &pad->soc->lanes[index]; | ||
1446 | pcie->base.index = index; | ||
1447 | pcie->base.pad = pad; | ||
1448 | pcie->base.np = np; | ||
1449 | |||
1450 | err = tegra_xusb_lane_parse_dt(&pcie->base, np); | ||
1451 | if (err < 0) { | ||
1452 | kfree(pcie); | ||
1453 | return ERR_PTR(err); | ||
1454 | } | ||
1455 | |||
1456 | return &pcie->base; | ||
1457 | } | ||
1458 | |||
1459 | static void tegra210_pcie_lane_remove(struct tegra_xusb_lane *lane) | ||
1460 | { | ||
1461 | struct tegra_xusb_pcie_lane *pcie = to_pcie_lane(lane); | ||
1462 | |||
1463 | kfree(pcie); | ||
1464 | } | ||
1465 | |||
1466 | static const struct tegra_xusb_lane_ops tegra210_pcie_lane_ops = { | ||
1467 | .probe = tegra210_pcie_lane_probe, | ||
1468 | .remove = tegra210_pcie_lane_remove, | ||
1469 | }; | ||
1470 | |||
1471 | static int tegra210_pcie_phy_init(struct phy *phy) | ||
1472 | { | ||
1473 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1474 | |||
1475 | return tegra210_xusb_padctl_enable(lane->pad->padctl); | ||
1476 | } | ||
1477 | |||
1478 | static int tegra210_pcie_phy_exit(struct phy *phy) | ||
1479 | { | ||
1480 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1481 | |||
1482 | return tegra210_xusb_padctl_disable(lane->pad->padctl); | ||
1483 | } | ||
1484 | |||
1485 | static int tegra210_pcie_phy_power_on(struct phy *phy) | ||
1486 | { | ||
1487 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1488 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
1489 | u32 value; | ||
1490 | int err; | ||
1491 | |||
1492 | mutex_lock(&padctl->lock); | ||
1493 | |||
1494 | err = tegra210_pex_uphy_enable(padctl); | ||
1495 | if (err < 0) | ||
1496 | goto unlock; | ||
1497 | |||
1498 | value = padctl_readl(padctl, XUSB_PADCTL_USB3_PAD_MUX); | ||
1499 | value |= XUSB_PADCTL_USB3_PAD_MUX_PCIE_IDDQ_DISABLE(lane->index); | ||
1500 | padctl_writel(padctl, value, XUSB_PADCTL_USB3_PAD_MUX); | ||
1501 | |||
1502 | unlock: | ||
1503 | mutex_unlock(&padctl->lock); | ||
1504 | return err; | ||
1505 | } | ||
1506 | |||
1507 | static int tegra210_pcie_phy_power_off(struct phy *phy) | ||
1508 | { | ||
1509 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1510 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
1511 | u32 value; | ||
1512 | |||
1513 | value = padctl_readl(padctl, XUSB_PADCTL_USB3_PAD_MUX); | ||
1514 | value &= ~XUSB_PADCTL_USB3_PAD_MUX_PCIE_IDDQ_DISABLE(lane->index); | ||
1515 | padctl_writel(padctl, value, XUSB_PADCTL_USB3_PAD_MUX); | ||
1516 | |||
1517 | tegra210_pex_uphy_disable(padctl); | ||
1518 | |||
1519 | return 0; | ||
1520 | } | ||
1521 | |||
1522 | static const struct phy_ops tegra210_pcie_phy_ops = { | ||
1523 | .init = tegra210_pcie_phy_init, | ||
1524 | .exit = tegra210_pcie_phy_exit, | ||
1525 | .power_on = tegra210_pcie_phy_power_on, | ||
1526 | .power_off = tegra210_pcie_phy_power_off, | ||
1527 | .owner = THIS_MODULE, | ||
1528 | }; | ||
1529 | |||
1530 | static struct tegra_xusb_pad * | ||
1531 | tegra210_pcie_pad_probe(struct tegra_xusb_padctl *padctl, | ||
1532 | const struct tegra_xusb_pad_soc *soc, | ||
1533 | struct device_node *np) | ||
1534 | { | ||
1535 | struct tegra_xusb_pcie_pad *pcie; | ||
1536 | struct tegra_xusb_pad *pad; | ||
1537 | int err; | ||
1538 | |||
1539 | pcie = kzalloc(sizeof(*pcie), GFP_KERNEL); | ||
1540 | if (!pcie) | ||
1541 | return ERR_PTR(-ENOMEM); | ||
1542 | |||
1543 | pad = &pcie->base; | ||
1544 | pad->ops = &tegra210_pcie_lane_ops; | ||
1545 | pad->soc = soc; | ||
1546 | |||
1547 | err = tegra_xusb_pad_init(pad, padctl, np); | ||
1548 | if (err < 0) { | ||
1549 | kfree(pcie); | ||
1550 | goto out; | ||
1551 | } | ||
1552 | |||
1553 | pcie->pll = devm_clk_get(&pad->dev, "pll"); | ||
1554 | if (IS_ERR(pcie->pll)) { | ||
1555 | err = PTR_ERR(pcie->pll); | ||
1556 | dev_err(&pad->dev, "failed to get PLL: %d\n", err); | ||
1557 | goto unregister; | ||
1558 | } | ||
1559 | |||
1560 | pcie->rst = devm_reset_control_get(&pad->dev, "phy"); | ||
1561 | if (IS_ERR(pcie->rst)) { | ||
1562 | err = PTR_ERR(pcie->rst); | ||
1563 | dev_err(&pad->dev, "failed to get PCIe pad reset: %d\n", err); | ||
1564 | goto unregister; | ||
1565 | } | ||
1566 | |||
1567 | err = tegra_xusb_pad_register(pad, &tegra210_pcie_phy_ops); | ||
1568 | if (err < 0) | ||
1569 | goto unregister; | ||
1570 | |||
1571 | dev_set_drvdata(&pad->dev, pad); | ||
1572 | |||
1573 | return pad; | ||
1574 | |||
1575 | unregister: | ||
1576 | device_unregister(&pad->dev); | ||
1577 | out: | ||
1578 | return ERR_PTR(err); | ||
1579 | } | ||
1580 | |||
1581 | static void tegra210_pcie_pad_remove(struct tegra_xusb_pad *pad) | ||
1582 | { | ||
1583 | struct tegra_xusb_pcie_pad *pcie = to_pcie_pad(pad); | ||
1584 | |||
1585 | kfree(pcie); | ||
1586 | } | ||
1587 | |||
1588 | static const struct tegra_xusb_pad_ops tegra210_pcie_ops = { | ||
1589 | .probe = tegra210_pcie_pad_probe, | ||
1590 | .remove = tegra210_pcie_pad_remove, | ||
1591 | }; | ||
1592 | |||
1593 | static const struct tegra_xusb_pad_soc tegra210_pcie_pad = { | ||
1594 | .name = "pcie", | ||
1595 | .num_lanes = ARRAY_SIZE(tegra210_pcie_lanes), | ||
1596 | .lanes = tegra210_pcie_lanes, | ||
1597 | .ops = &tegra210_pcie_ops, | ||
1598 | }; | ||
1599 | |||
1600 | static const struct tegra_xusb_lane_soc tegra210_sata_lanes[] = { | ||
1601 | TEGRA210_LANE("sata-0", 0x028, 30, 0x3, pcie), | ||
1602 | }; | ||
1603 | |||
1604 | static struct tegra_xusb_lane * | ||
1605 | tegra210_sata_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, | ||
1606 | unsigned int index) | ||
1607 | { | ||
1608 | struct tegra_xusb_sata_lane *sata; | ||
1609 | int err; | ||
1610 | |||
1611 | sata = kzalloc(sizeof(*sata), GFP_KERNEL); | ||
1612 | if (!sata) | ||
1613 | return ERR_PTR(-ENOMEM); | ||
1614 | |||
1615 | INIT_LIST_HEAD(&sata->base.list); | ||
1616 | sata->base.soc = &pad->soc->lanes[index]; | ||
1617 | sata->base.index = index; | ||
1618 | sata->base.pad = pad; | ||
1619 | sata->base.np = np; | ||
1620 | |||
1621 | err = tegra_xusb_lane_parse_dt(&sata->base, np); | ||
1622 | if (err < 0) { | ||
1623 | kfree(sata); | ||
1624 | return ERR_PTR(err); | ||
1625 | } | ||
1626 | |||
1627 | return &sata->base; | ||
1628 | } | ||
1629 | |||
1630 | static void tegra210_sata_lane_remove(struct tegra_xusb_lane *lane) | ||
1631 | { | ||
1632 | struct tegra_xusb_sata_lane *sata = to_sata_lane(lane); | ||
1633 | |||
1634 | kfree(sata); | ||
1635 | } | ||
1636 | |||
1637 | static const struct tegra_xusb_lane_ops tegra210_sata_lane_ops = { | ||
1638 | .probe = tegra210_sata_lane_probe, | ||
1639 | .remove = tegra210_sata_lane_remove, | ||
1640 | }; | ||
1641 | |||
1642 | static int tegra210_sata_phy_init(struct phy *phy) | ||
1643 | { | ||
1644 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1645 | |||
1646 | return tegra210_xusb_padctl_enable(lane->pad->padctl); | ||
1647 | } | ||
1648 | |||
1649 | static int tegra210_sata_phy_exit(struct phy *phy) | ||
1650 | { | ||
1651 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1652 | |||
1653 | return tegra210_xusb_padctl_disable(lane->pad->padctl); | ||
1654 | } | ||
1655 | |||
1656 | static int tegra210_sata_phy_power_on(struct phy *phy) | ||
1657 | { | ||
1658 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1659 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
1660 | u32 value; | ||
1661 | int err; | ||
1662 | |||
1663 | mutex_lock(&padctl->lock); | ||
1664 | |||
1665 | err = tegra210_sata_uphy_enable(padctl, false); | ||
1666 | if (err < 0) | ||
1667 | goto unlock; | ||
1668 | |||
1669 | value = padctl_readl(padctl, XUSB_PADCTL_USB3_PAD_MUX); | ||
1670 | value |= XUSB_PADCTL_USB3_PAD_MUX_SATA_IDDQ_DISABLE(lane->index); | ||
1671 | padctl_writel(padctl, value, XUSB_PADCTL_USB3_PAD_MUX); | ||
1672 | |||
1673 | unlock: | ||
1674 | mutex_unlock(&padctl->lock); | ||
1675 | return err; | ||
1676 | } | ||
1677 | |||
1678 | static int tegra210_sata_phy_power_off(struct phy *phy) | ||
1679 | { | ||
1680 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
1681 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
1682 | u32 value; | ||
1683 | |||
1684 | value = padctl_readl(padctl, XUSB_PADCTL_USB3_PAD_MUX); | ||
1685 | value &= ~XUSB_PADCTL_USB3_PAD_MUX_SATA_IDDQ_DISABLE(lane->index); | ||
1686 | padctl_writel(padctl, value, XUSB_PADCTL_USB3_PAD_MUX); | ||
1687 | |||
1688 | tegra210_sata_uphy_disable(lane->pad->padctl); | ||
1689 | |||
1690 | return 0; | ||
1691 | } | ||
1692 | |||
1693 | static const struct phy_ops tegra210_sata_phy_ops = { | ||
1694 | .init = tegra210_sata_phy_init, | ||
1695 | .exit = tegra210_sata_phy_exit, | ||
1696 | .power_on = tegra210_sata_phy_power_on, | ||
1697 | .power_off = tegra210_sata_phy_power_off, | ||
1698 | .owner = THIS_MODULE, | ||
1699 | }; | ||
1700 | |||
1701 | static struct tegra_xusb_pad * | ||
1702 | tegra210_sata_pad_probe(struct tegra_xusb_padctl *padctl, | ||
1703 | const struct tegra_xusb_pad_soc *soc, | ||
1704 | struct device_node *np) | ||
1705 | { | ||
1706 | struct tegra_xusb_sata_pad *sata; | ||
1707 | struct tegra_xusb_pad *pad; | ||
1708 | int err; | ||
1709 | |||
1710 | sata = kzalloc(sizeof(*sata), GFP_KERNEL); | ||
1711 | if (!sata) | ||
1712 | return ERR_PTR(-ENOMEM); | ||
1713 | |||
1714 | pad = &sata->base; | ||
1715 | pad->ops = &tegra210_sata_lane_ops; | ||
1716 | pad->soc = soc; | ||
1717 | |||
1718 | err = tegra_xusb_pad_init(pad, padctl, np); | ||
1719 | if (err < 0) { | ||
1720 | kfree(sata); | ||
1721 | goto out; | ||
1722 | } | ||
1723 | |||
1724 | sata->rst = devm_reset_control_get(&pad->dev, "phy"); | ||
1725 | if (IS_ERR(sata->rst)) { | ||
1726 | err = PTR_ERR(sata->rst); | ||
1727 | dev_err(&pad->dev, "failed to get SATA pad reset: %d\n", err); | ||
1728 | goto unregister; | ||
1729 | } | ||
1730 | |||
1731 | err = tegra_xusb_pad_register(pad, &tegra210_sata_phy_ops); | ||
1732 | if (err < 0) | ||
1733 | goto unregister; | ||
1734 | |||
1735 | dev_set_drvdata(&pad->dev, pad); | ||
1736 | |||
1737 | return pad; | ||
1738 | |||
1739 | unregister: | ||
1740 | device_unregister(&pad->dev); | ||
1741 | out: | ||
1742 | return ERR_PTR(err); | ||
1743 | } | ||
1744 | |||
1745 | static void tegra210_sata_pad_remove(struct tegra_xusb_pad *pad) | ||
1746 | { | ||
1747 | struct tegra_xusb_sata_pad *sata = to_sata_pad(pad); | ||
1748 | |||
1749 | kfree(sata); | ||
1750 | } | ||
1751 | |||
1752 | static const struct tegra_xusb_pad_ops tegra210_sata_ops = { | ||
1753 | .probe = tegra210_sata_pad_probe, | ||
1754 | .remove = tegra210_sata_pad_remove, | ||
1755 | }; | ||
1756 | |||
1757 | static const struct tegra_xusb_pad_soc tegra210_sata_pad = { | ||
1758 | .name = "sata", | ||
1759 | .num_lanes = ARRAY_SIZE(tegra210_sata_lanes), | ||
1760 | .lanes = tegra210_sata_lanes, | ||
1761 | .ops = &tegra210_sata_ops, | ||
1762 | }; | ||
1763 | |||
1764 | static const struct tegra_xusb_pad_soc * const tegra210_pads[] = { | ||
1765 | &tegra210_usb2_pad, | ||
1766 | &tegra210_hsic_pad, | ||
1767 | &tegra210_pcie_pad, | ||
1768 | &tegra210_sata_pad, | ||
1769 | }; | ||
1770 | |||
1771 | static int tegra210_usb2_port_enable(struct tegra_xusb_port *port) | ||
1772 | { | ||
1773 | return 0; | ||
1774 | } | ||
1775 | |||
1776 | static void tegra210_usb2_port_disable(struct tegra_xusb_port *port) | ||
1777 | { | ||
1778 | } | ||
1779 | |||
1780 | static struct tegra_xusb_lane * | ||
1781 | tegra210_usb2_port_map(struct tegra_xusb_port *port) | ||
1782 | { | ||
1783 | return tegra_xusb_find_lane(port->padctl, "usb2", port->index); | ||
1784 | } | ||
1785 | |||
1786 | static const struct tegra_xusb_port_ops tegra210_usb2_port_ops = { | ||
1787 | .enable = tegra210_usb2_port_enable, | ||
1788 | .disable = tegra210_usb2_port_disable, | ||
1789 | .map = tegra210_usb2_port_map, | ||
1790 | }; | ||
1791 | |||
1792 | static int tegra210_hsic_port_enable(struct tegra_xusb_port *port) | ||
1793 | { | ||
1794 | return 0; | ||
1795 | } | ||
1796 | |||
1797 | static void tegra210_hsic_port_disable(struct tegra_xusb_port *port) | ||
1798 | { | ||
1799 | } | ||
1800 | |||
1801 | static struct tegra_xusb_lane * | ||
1802 | tegra210_hsic_port_map(struct tegra_xusb_port *port) | ||
1803 | { | ||
1804 | return tegra_xusb_find_lane(port->padctl, "hsic", port->index); | ||
1805 | } | ||
1806 | |||
1807 | static const struct tegra_xusb_port_ops tegra210_hsic_port_ops = { | ||
1808 | .enable = tegra210_hsic_port_enable, | ||
1809 | .disable = tegra210_hsic_port_disable, | ||
1810 | .map = tegra210_hsic_port_map, | ||
1811 | }; | ||
1812 | |||
1813 | static int tegra210_usb3_port_enable(struct tegra_xusb_port *port) | ||
1814 | { | ||
1815 | struct tegra_xusb_usb3_port *usb3 = to_usb3_port(port); | ||
1816 | struct tegra_xusb_padctl *padctl = port->padctl; | ||
1817 | struct tegra_xusb_lane *lane = usb3->base.lane; | ||
1818 | unsigned int index = port->index; | ||
1819 | u32 value; | ||
1820 | int err; | ||
1821 | |||
1822 | value = padctl_readl(padctl, XUSB_PADCTL_SS_PORT_MAP); | ||
1823 | |||
1824 | if (!usb3->internal) | ||
1825 | value &= ~XUSB_PADCTL_SS_PORT_MAP_PORTX_INTERNAL(index); | ||
1826 | else | ||
1827 | value |= XUSB_PADCTL_SS_PORT_MAP_PORTX_INTERNAL(index); | ||
1828 | |||
1829 | value &= ~XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_MASK(index); | ||
1830 | value |= XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP(index, usb3->port); | ||
1831 | padctl_writel(padctl, value, XUSB_PADCTL_SS_PORT_MAP); | ||
1832 | |||
1833 | /* | ||
1834 | * TODO: move this code into the PCIe/SATA PHY ->power_on() callbacks | ||
1835 | * and conditionalize based on mux function? This seems to work, but | ||
1836 | * might not be the exact proper sequence. | ||
1837 | */ | ||
1838 | err = regulator_enable(usb3->supply); | ||
1839 | if (err < 0) | ||
1840 | return err; | ||
1841 | |||
1842 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_USB3_PADX_ECTL1(index)); | ||
1843 | value &= ~(XUSB_PADCTL_UPHY_USB3_PAD_ECTL1_TX_TERM_CTRL_MASK << | ||
1844 | XUSB_PADCTL_UPHY_USB3_PAD_ECTL1_TX_TERM_CTRL_SHIFT); | ||
1845 | value |= XUSB_PADCTL_UPHY_USB3_PAD_ECTL1_TX_TERM_CTRL_VAL << | ||
1846 | XUSB_PADCTL_UPHY_USB3_PAD_ECTL1_TX_TERM_CTRL_SHIFT; | ||
1847 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_USB3_PADX_ECTL1(index)); | ||
1848 | |||
1849 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_USB3_PADX_ECTL2(index)); | ||
1850 | value &= ~(XUSB_PADCTL_UPHY_USB3_PAD_ECTL2_RX_CTLE_MASK << | ||
1851 | XUSB_PADCTL_UPHY_USB3_PAD_ECTL2_RX_CTLE_SHIFT); | ||
1852 | value |= XUSB_PADCTL_UPHY_USB3_PAD_ECTL2_RX_CTLE_VAL << | ||
1853 | XUSB_PADCTL_UPHY_USB3_PAD_ECTL2_RX_CTLE_SHIFT; | ||
1854 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_USB3_PADX_ECTL2(index)); | ||
1855 | |||
1856 | padctl_writel(padctl, XUSB_PADCTL_UPHY_USB3_PAD_ECTL3_RX_DFE_VAL, | ||
1857 | XUSB_PADCTL_UPHY_USB3_PADX_ECTL3(index)); | ||
1858 | |||
1859 | value = padctl_readl(padctl, XUSB_PADCTL_UPHY_USB3_PADX_ECTL4(index)); | ||
1860 | value &= ~(XUSB_PADCTL_UPHY_USB3_PAD_ECTL4_RX_CDR_CTRL_MASK << | ||
1861 | XUSB_PADCTL_UPHY_USB3_PAD_ECTL4_RX_CDR_CTRL_SHIFT); | ||
1862 | value |= XUSB_PADCTL_UPHY_USB3_PAD_ECTL4_RX_CDR_CTRL_VAL << | ||
1863 | XUSB_PADCTL_UPHY_USB3_PAD_ECTL4_RX_CDR_CTRL_SHIFT; | ||
1864 | padctl_writel(padctl, value, XUSB_PADCTL_UPHY_USB3_PADX_ECTL4(index)); | ||
1865 | |||
1866 | padctl_writel(padctl, XUSB_PADCTL_UPHY_USB3_PAD_ECTL6_RX_EQ_CTRL_H_VAL, | ||
1867 | XUSB_PADCTL_UPHY_USB3_PADX_ECTL6(index)); | ||
1868 | |||
1869 | if (lane->pad == padctl->sata) | ||
1870 | err = tegra210_sata_uphy_enable(padctl, true); | ||
1871 | else | ||
1872 | err = tegra210_pex_uphy_enable(padctl); | ||
1873 | |||
1874 | if (err) { | ||
1875 | dev_err(&port->dev, "%s: failed to enable UPHY: %d\n", | ||
1876 | __func__, err); | ||
1877 | return err; | ||
1878 | } | ||
1879 | |||
1880 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); | ||
1881 | value &= ~XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_VCORE_DOWN(index); | ||
1882 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1); | ||
1883 | |||
1884 | usleep_range(100, 200); | ||
1885 | |||
1886 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); | ||
1887 | value &= ~XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_CLAMP_EN_EARLY(index); | ||
1888 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1); | ||
1889 | |||
1890 | usleep_range(100, 200); | ||
1891 | |||
1892 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); | ||
1893 | value &= ~XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_CLAMP_EN(index); | ||
1894 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1); | ||
1895 | |||
1896 | return 0; | ||
1897 | } | ||
1898 | |||
1899 | static void tegra210_usb3_port_disable(struct tegra_xusb_port *port) | ||
1900 | { | ||
1901 | struct tegra_xusb_usb3_port *usb3 = to_usb3_port(port); | ||
1902 | struct tegra_xusb_padctl *padctl = port->padctl; | ||
1903 | struct tegra_xusb_lane *lane = port->lane; | ||
1904 | unsigned int index = port->index; | ||
1905 | u32 value; | ||
1906 | |||
1907 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); | ||
1908 | value |= XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_CLAMP_EN_EARLY(index); | ||
1909 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1); | ||
1910 | |||
1911 | usleep_range(100, 200); | ||
1912 | |||
1913 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); | ||
1914 | value |= XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_CLAMP_EN(index); | ||
1915 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1); | ||
1916 | |||
1917 | usleep_range(250, 350); | ||
1918 | |||
1919 | value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM1); | ||
1920 | value |= XUSB_PADCTL_ELPG_PROGRAM1_SSPX_ELPG_VCORE_DOWN(index); | ||
1921 | padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM1); | ||
1922 | |||
1923 | if (lane->pad == padctl->sata) | ||
1924 | tegra210_sata_uphy_disable(padctl); | ||
1925 | else | ||
1926 | tegra210_pex_uphy_disable(padctl); | ||
1927 | |||
1928 | regulator_disable(usb3->supply); | ||
1929 | |||
1930 | value = padctl_readl(padctl, XUSB_PADCTL_SS_PORT_MAP); | ||
1931 | value &= ~XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_MASK(index); | ||
1932 | value |= XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP(index, 0x7); | ||
1933 | padctl_writel(padctl, value, XUSB_PADCTL_SS_PORT_MAP); | ||
1934 | } | ||
1935 | |||
1936 | static const struct tegra_xusb_lane_map tegra210_usb3_map[] = { | ||
1937 | { 0, "pcie", 6 }, | ||
1938 | { 1, "pcie", 5 }, | ||
1939 | { 2, "pcie", 0 }, | ||
1940 | { 2, "pcie", 3 }, | ||
1941 | { 3, "pcie", 4 }, | ||
1942 | { 3, "pcie", 4 }, | ||
1943 | { 0, NULL, 0 } | ||
1944 | }; | ||
1945 | |||
1946 | static struct tegra_xusb_lane * | ||
1947 | tegra210_usb3_port_map(struct tegra_xusb_port *port) | ||
1948 | { | ||
1949 | return tegra_xusb_port_find_lane(port, tegra210_usb3_map, "usb3-ss"); | ||
1950 | } | ||
1951 | |||
1952 | static const struct tegra_xusb_port_ops tegra210_usb3_port_ops = { | ||
1953 | .enable = tegra210_usb3_port_enable, | ||
1954 | .disable = tegra210_usb3_port_disable, | ||
1955 | .map = tegra210_usb3_port_map, | ||
1956 | }; | ||
1957 | |||
1958 | static int | ||
1959 | tegra210_xusb_read_fuse_calibration(struct tegra210_xusb_fuse_calibration *fuse) | ||
1960 | { | ||
1961 | unsigned int i; | ||
1962 | u32 value; | ||
1963 | int err; | ||
1964 | |||
1965 | err = tegra_fuse_readl(TEGRA_FUSE_SKU_CALIB_0, &value); | ||
1966 | if (err < 0) | ||
1967 | return err; | ||
1968 | |||
1969 | for (i = 0; i < ARRAY_SIZE(fuse->hs_curr_level); i++) { | ||
1970 | fuse->hs_curr_level[i] = | ||
1971 | (value >> FUSE_SKU_CALIB_HS_CURR_LEVEL_PADX_SHIFT(i)) & | ||
1972 | FUSE_SKU_CALIB_HS_CURR_LEVEL_PAD_MASK; | ||
1973 | } | ||
1974 | |||
1975 | fuse->hs_term_range_adj = | ||
1976 | (value >> FUSE_SKU_CALIB_HS_TERM_RANGE_ADJ_SHIFT) & | ||
1977 | FUSE_SKU_CALIB_HS_TERM_RANGE_ADJ_MASK; | ||
1978 | |||
1979 | err = tegra_fuse_readl(TEGRA_FUSE_USB_CALIB_EXT_0, &value); | ||
1980 | if (err < 0) | ||
1981 | return err; | ||
1982 | |||
1983 | fuse->rpd_ctrl = | ||
1984 | (value >> FUSE_USB_CALIB_EXT_RPD_CTRL_SHIFT) & | ||
1985 | FUSE_USB_CALIB_EXT_RPD_CTRL_MASK; | ||
1986 | |||
1987 | return 0; | ||
1988 | } | ||
1989 | |||
1990 | static struct tegra_xusb_padctl * | ||
1991 | tegra210_xusb_padctl_probe(struct device *dev, | ||
1992 | const struct tegra_xusb_padctl_soc *soc) | ||
1993 | { | ||
1994 | struct tegra210_xusb_padctl *padctl; | ||
1995 | int err; | ||
1996 | |||
1997 | padctl = devm_kzalloc(dev, sizeof(*padctl), GFP_KERNEL); | ||
1998 | if (!padctl) | ||
1999 | return ERR_PTR(-ENOMEM); | ||
2000 | |||
2001 | padctl->base.dev = dev; | ||
2002 | padctl->base.soc = soc; | ||
2003 | |||
2004 | err = tegra210_xusb_read_fuse_calibration(&padctl->fuse); | ||
2005 | if (err < 0) | ||
2006 | return ERR_PTR(err); | ||
2007 | |||
2008 | return &padctl->base; | ||
2009 | } | ||
2010 | |||
2011 | static void tegra210_xusb_padctl_remove(struct tegra_xusb_padctl *padctl) | ||
2012 | { | ||
2013 | } | ||
2014 | |||
2015 | static const struct tegra_xusb_padctl_ops tegra210_xusb_padctl_ops = { | ||
2016 | .probe = tegra210_xusb_padctl_probe, | ||
2017 | .remove = tegra210_xusb_padctl_remove, | ||
2018 | .usb3_set_lfps_detect = tegra210_usb3_set_lfps_detect, | ||
2019 | .hsic_set_idle = tegra210_hsic_set_idle, | ||
2020 | }; | ||
2021 | |||
2022 | const struct tegra_xusb_padctl_soc tegra210_xusb_padctl_soc = { | ||
2023 | .num_pads = ARRAY_SIZE(tegra210_pads), | ||
2024 | .pads = tegra210_pads, | ||
2025 | .ports = { | ||
2026 | .usb2 = { | ||
2027 | .ops = &tegra210_usb2_port_ops, | ||
2028 | .count = 4, | ||
2029 | }, | ||
2030 | .hsic = { | ||
2031 | .ops = &tegra210_hsic_port_ops, | ||
2032 | .count = 1, | ||
2033 | }, | ||
2034 | .usb3 = { | ||
2035 | .ops = &tegra210_usb3_port_ops, | ||
2036 | .count = 4, | ||
2037 | }, | ||
2038 | }, | ||
2039 | .ops = &tegra210_xusb_padctl_ops, | ||
2040 | }; | ||
2041 | EXPORT_SYMBOL_GPL(tegra210_xusb_padctl_soc); | ||
2042 | |||
2043 | MODULE_AUTHOR("Andrew Bresticker <abrestic@chromium.org>"); | ||
2044 | MODULE_DESCRIPTION("NVIDIA Tegra 210 XUSB Pad Controller driver"); | ||
2045 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c new file mode 100644 index 000000000000..ec83dfdbc206 --- /dev/null +++ b/drivers/phy/tegra/xusb.c | |||
@@ -0,0 +1,1021 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/delay.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/mailbox_client.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_device.h> | ||
20 | #include <linux/phy/phy.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/regulator/consumer.h> | ||
23 | #include <linux/reset.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/workqueue.h> | ||
26 | |||
27 | #include <soc/tegra/fuse.h> | ||
28 | |||
29 | #include "xusb.h" | ||
30 | |||
31 | static struct phy *tegra_xusb_pad_of_xlate(struct device *dev, | ||
32 | struct of_phandle_args *args) | ||
33 | { | ||
34 | struct tegra_xusb_pad *pad = dev_get_drvdata(dev); | ||
35 | struct phy *phy = NULL; | ||
36 | unsigned int i; | ||
37 | |||
38 | if (args->args_count != 0) | ||
39 | return ERR_PTR(-EINVAL); | ||
40 | |||
41 | for (i = 0; i < pad->soc->num_lanes; i++) { | ||
42 | if (!pad->lanes[i]) | ||
43 | continue; | ||
44 | |||
45 | if (pad->lanes[i]->dev.of_node == args->np) { | ||
46 | phy = pad->lanes[i]; | ||
47 | break; | ||
48 | } | ||
49 | } | ||
50 | |||
51 | if (phy == NULL) | ||
52 | phy = ERR_PTR(-ENODEV); | ||
53 | |||
54 | return phy; | ||
55 | } | ||
56 | |||
57 | static const struct of_device_id tegra_xusb_padctl_of_match[] = { | ||
58 | #if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC) | ||
59 | { | ||
60 | .compatible = "nvidia,tegra124-xusb-padctl", | ||
61 | .data = &tegra124_xusb_padctl_soc, | ||
62 | }, | ||
63 | #endif | ||
64 | #if defined(CONFIG_ARCH_TEGRA_210_SOC) | ||
65 | { | ||
66 | .compatible = "nvidia,tegra210-xusb-padctl", | ||
67 | .data = &tegra210_xusb_padctl_soc, | ||
68 | }, | ||
69 | #endif | ||
70 | { } | ||
71 | }; | ||
72 | MODULE_DEVICE_TABLE(of, tegra_xusb_padctl_of_match); | ||
73 | |||
74 | static struct device_node * | ||
75 | tegra_xusb_find_pad_node(struct tegra_xusb_padctl *padctl, const char *name) | ||
76 | { | ||
77 | /* | ||
78 | * of_find_node_by_name() drops a reference, so make sure to grab one. | ||
79 | */ | ||
80 | struct device_node *np = of_node_get(padctl->dev->of_node); | ||
81 | |||
82 | np = of_find_node_by_name(np, "pads"); | ||
83 | if (np) | ||
84 | np = of_find_node_by_name(np, name); | ||
85 | |||
86 | return np; | ||
87 | } | ||
88 | |||
89 | static struct device_node * | ||
90 | tegra_xusb_pad_find_phy_node(struct tegra_xusb_pad *pad, unsigned int index) | ||
91 | { | ||
92 | /* | ||
93 | * of_find_node_by_name() drops a reference, so make sure to grab one. | ||
94 | */ | ||
95 | struct device_node *np = of_node_get(pad->dev.of_node); | ||
96 | |||
97 | np = of_find_node_by_name(np, "lanes"); | ||
98 | if (!np) | ||
99 | return NULL; | ||
100 | |||
101 | return of_find_node_by_name(np, pad->soc->lanes[index].name); | ||
102 | } | ||
103 | |||
104 | int tegra_xusb_lane_lookup_function(struct tegra_xusb_lane *lane, | ||
105 | const char *function) | ||
106 | { | ||
107 | unsigned int i; | ||
108 | |||
109 | for (i = 0; i < lane->soc->num_funcs; i++) | ||
110 | if (strcmp(function, lane->soc->funcs[i]) == 0) | ||
111 | return i; | ||
112 | |||
113 | return -EINVAL; | ||
114 | } | ||
115 | |||
116 | int tegra_xusb_lane_parse_dt(struct tegra_xusb_lane *lane, | ||
117 | struct device_node *np) | ||
118 | { | ||
119 | struct device *dev = &lane->pad->dev; | ||
120 | const char *function; | ||
121 | int err; | ||
122 | |||
123 | err = of_property_read_string(np, "nvidia,function", &function); | ||
124 | if (err < 0) | ||
125 | return err; | ||
126 | |||
127 | err = tegra_xusb_lane_lookup_function(lane, function); | ||
128 | if (err < 0) { | ||
129 | dev_err(dev, "invalid function \"%s\" for lane \"%s\"\n", | ||
130 | function, np->name); | ||
131 | return err; | ||
132 | } | ||
133 | |||
134 | lane->function = err; | ||
135 | |||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static void tegra_xusb_lane_destroy(struct phy *phy) | ||
140 | { | ||
141 | if (phy) { | ||
142 | struct tegra_xusb_lane *lane = phy_get_drvdata(phy); | ||
143 | |||
144 | lane->pad->ops->remove(lane); | ||
145 | phy_destroy(phy); | ||
146 | } | ||
147 | } | ||
148 | |||
149 | static void tegra_xusb_pad_release(struct device *dev) | ||
150 | { | ||
151 | struct tegra_xusb_pad *pad = to_tegra_xusb_pad(dev); | ||
152 | |||
153 | pad->soc->ops->remove(pad); | ||
154 | } | ||
155 | |||
156 | static struct device_type tegra_xusb_pad_type = { | ||
157 | .release = tegra_xusb_pad_release, | ||
158 | }; | ||
159 | |||
160 | int tegra_xusb_pad_init(struct tegra_xusb_pad *pad, | ||
161 | struct tegra_xusb_padctl *padctl, | ||
162 | struct device_node *np) | ||
163 | { | ||
164 | int err; | ||
165 | |||
166 | device_initialize(&pad->dev); | ||
167 | INIT_LIST_HEAD(&pad->list); | ||
168 | pad->dev.parent = padctl->dev; | ||
169 | pad->dev.type = &tegra_xusb_pad_type; | ||
170 | pad->dev.of_node = np; | ||
171 | pad->padctl = padctl; | ||
172 | |||
173 | err = dev_set_name(&pad->dev, "%s", pad->soc->name); | ||
174 | if (err < 0) | ||
175 | goto unregister; | ||
176 | |||
177 | err = device_add(&pad->dev); | ||
178 | if (err < 0) | ||
179 | goto unregister; | ||
180 | |||
181 | return 0; | ||
182 | |||
183 | unregister: | ||
184 | device_unregister(&pad->dev); | ||
185 | return err; | ||
186 | } | ||
187 | |||
188 | int tegra_xusb_pad_register(struct tegra_xusb_pad *pad, | ||
189 | const struct phy_ops *ops) | ||
190 | { | ||
191 | struct device_node *children; | ||
192 | struct phy *lane; | ||
193 | unsigned int i; | ||
194 | int err; | ||
195 | |||
196 | children = of_find_node_by_name(pad->dev.of_node, "lanes"); | ||
197 | if (!children) | ||
198 | return -ENODEV; | ||
199 | |||
200 | pad->lanes = devm_kcalloc(&pad->dev, pad->soc->num_lanes, sizeof(lane), | ||
201 | GFP_KERNEL); | ||
202 | if (!pad->lanes) { | ||
203 | of_node_put(children); | ||
204 | return -ENOMEM; | ||
205 | } | ||
206 | |||
207 | for (i = 0; i < pad->soc->num_lanes; i++) { | ||
208 | struct device_node *np = tegra_xusb_pad_find_phy_node(pad, i); | ||
209 | struct tegra_xusb_lane *lane; | ||
210 | |||
211 | /* skip disabled lanes */ | ||
212 | if (!np || !of_device_is_available(np)) { | ||
213 | of_node_put(np); | ||
214 | continue; | ||
215 | } | ||
216 | |||
217 | pad->lanes[i] = phy_create(&pad->dev, np, ops); | ||
218 | if (IS_ERR(pad->lanes[i])) { | ||
219 | err = PTR_ERR(pad->lanes[i]); | ||
220 | of_node_put(np); | ||
221 | goto remove; | ||
222 | } | ||
223 | |||
224 | lane = pad->ops->probe(pad, np, i); | ||
225 | if (IS_ERR(lane)) { | ||
226 | phy_destroy(pad->lanes[i]); | ||
227 | err = PTR_ERR(lane); | ||
228 | goto remove; | ||
229 | } | ||
230 | |||
231 | list_add_tail(&lane->list, &pad->padctl->lanes); | ||
232 | phy_set_drvdata(pad->lanes[i], lane); | ||
233 | } | ||
234 | |||
235 | pad->provider = of_phy_provider_register_full(&pad->dev, children, | ||
236 | tegra_xusb_pad_of_xlate); | ||
237 | if (IS_ERR(pad->provider)) { | ||
238 | err = PTR_ERR(pad->provider); | ||
239 | goto remove; | ||
240 | } | ||
241 | |||
242 | return 0; | ||
243 | |||
244 | remove: | ||
245 | while (i--) | ||
246 | tegra_xusb_lane_destroy(pad->lanes[i]); | ||
247 | |||
248 | of_node_put(children); | ||
249 | |||
250 | return err; | ||
251 | } | ||
252 | |||
253 | void tegra_xusb_pad_unregister(struct tegra_xusb_pad *pad) | ||
254 | { | ||
255 | unsigned int i = pad->soc->num_lanes; | ||
256 | |||
257 | of_phy_provider_unregister(pad->provider); | ||
258 | |||
259 | while (i--) | ||
260 | tegra_xusb_lane_destroy(pad->lanes[i]); | ||
261 | |||
262 | device_unregister(&pad->dev); | ||
263 | } | ||
264 | |||
265 | static struct tegra_xusb_pad * | ||
266 | tegra_xusb_pad_create(struct tegra_xusb_padctl *padctl, | ||
267 | const struct tegra_xusb_pad_soc *soc) | ||
268 | { | ||
269 | struct tegra_xusb_pad *pad; | ||
270 | struct device_node *np; | ||
271 | int err; | ||
272 | |||
273 | np = tegra_xusb_find_pad_node(padctl, soc->name); | ||
274 | if (!np || !of_device_is_available(np)) | ||
275 | return NULL; | ||
276 | |||
277 | pad = soc->ops->probe(padctl, soc, np); | ||
278 | if (IS_ERR(pad)) { | ||
279 | err = PTR_ERR(pad); | ||
280 | dev_err(padctl->dev, "failed to create pad %s: %d\n", | ||
281 | soc->name, err); | ||
282 | return ERR_PTR(err); | ||
283 | } | ||
284 | |||
285 | /* XXX move this into ->probe() to avoid string comparison */ | ||
286 | if (strcmp(soc->name, "pcie") == 0) | ||
287 | padctl->pcie = pad; | ||
288 | |||
289 | if (strcmp(soc->name, "sata") == 0) | ||
290 | padctl->sata = pad; | ||
291 | |||
292 | if (strcmp(soc->name, "usb2") == 0) | ||
293 | padctl->usb2 = pad; | ||
294 | |||
295 | if (strcmp(soc->name, "ulpi") == 0) | ||
296 | padctl->ulpi = pad; | ||
297 | |||
298 | if (strcmp(soc->name, "hsic") == 0) | ||
299 | padctl->hsic = pad; | ||
300 | |||
301 | return pad; | ||
302 | } | ||
303 | |||
304 | static void __tegra_xusb_remove_pads(struct tegra_xusb_padctl *padctl) | ||
305 | { | ||
306 | struct tegra_xusb_pad *pad, *tmp; | ||
307 | |||
308 | list_for_each_entry_safe_reverse(pad, tmp, &padctl->pads, list) { | ||
309 | list_del(&pad->list); | ||
310 | tegra_xusb_pad_unregister(pad); | ||
311 | } | ||
312 | } | ||
313 | |||
314 | static void tegra_xusb_remove_pads(struct tegra_xusb_padctl *padctl) | ||
315 | { | ||
316 | mutex_lock(&padctl->lock); | ||
317 | __tegra_xusb_remove_pads(padctl); | ||
318 | mutex_unlock(&padctl->lock); | ||
319 | } | ||
320 | |||
321 | static void tegra_xusb_lane_program(struct tegra_xusb_lane *lane) | ||
322 | { | ||
323 | struct tegra_xusb_padctl *padctl = lane->pad->padctl; | ||
324 | const struct tegra_xusb_lane_soc *soc = lane->soc; | ||
325 | u32 value; | ||
326 | |||
327 | /* choose function */ | ||
328 | value = padctl_readl(padctl, soc->offset); | ||
329 | value &= ~(soc->mask << soc->shift); | ||
330 | value |= lane->function << soc->shift; | ||
331 | padctl_writel(padctl, value, soc->offset); | ||
332 | } | ||
333 | |||
334 | static void tegra_xusb_pad_program(struct tegra_xusb_pad *pad) | ||
335 | { | ||
336 | unsigned int i; | ||
337 | |||
338 | for (i = 0; i < pad->soc->num_lanes; i++) { | ||
339 | struct tegra_xusb_lane *lane; | ||
340 | |||
341 | if (pad->lanes[i]) { | ||
342 | lane = phy_get_drvdata(pad->lanes[i]); | ||
343 | tegra_xusb_lane_program(lane); | ||
344 | } | ||
345 | } | ||
346 | } | ||
347 | |||
348 | static int tegra_xusb_setup_pads(struct tegra_xusb_padctl *padctl) | ||
349 | { | ||
350 | struct tegra_xusb_pad *pad; | ||
351 | unsigned int i; | ||
352 | |||
353 | mutex_lock(&padctl->lock); | ||
354 | |||
355 | for (i = 0; i < padctl->soc->num_pads; i++) { | ||
356 | const struct tegra_xusb_pad_soc *soc = padctl->soc->pads[i]; | ||
357 | int err; | ||
358 | |||
359 | pad = tegra_xusb_pad_create(padctl, soc); | ||
360 | if (IS_ERR(pad)) { | ||
361 | err = PTR_ERR(pad); | ||
362 | dev_err(padctl->dev, "failed to create pad %s: %d\n", | ||
363 | soc->name, err); | ||
364 | __tegra_xusb_remove_pads(padctl); | ||
365 | mutex_unlock(&padctl->lock); | ||
366 | return err; | ||
367 | } | ||
368 | |||
369 | if (!pad) | ||
370 | continue; | ||
371 | |||
372 | list_add_tail(&pad->list, &padctl->pads); | ||
373 | } | ||
374 | |||
375 | list_for_each_entry(pad, &padctl->pads, list) | ||
376 | tegra_xusb_pad_program(pad); | ||
377 | |||
378 | mutex_unlock(&padctl->lock); | ||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | static bool tegra_xusb_lane_check(struct tegra_xusb_lane *lane, | ||
383 | const char *function) | ||
384 | { | ||
385 | const char *func = lane->soc->funcs[lane->function]; | ||
386 | |||
387 | return strcmp(function, func) == 0; | ||
388 | } | ||
389 | |||
390 | struct tegra_xusb_lane *tegra_xusb_find_lane(struct tegra_xusb_padctl *padctl, | ||
391 | const char *type, | ||
392 | unsigned int index) | ||
393 | { | ||
394 | struct tegra_xusb_lane *lane, *hit = ERR_PTR(-ENODEV); | ||
395 | char *name; | ||
396 | |||
397 | name = kasprintf(GFP_KERNEL, "%s-%u", type, index); | ||
398 | if (!name) | ||
399 | return ERR_PTR(-ENOMEM); | ||
400 | |||
401 | list_for_each_entry(lane, &padctl->lanes, list) { | ||
402 | if (strcmp(lane->soc->name, name) == 0) { | ||
403 | hit = lane; | ||
404 | break; | ||
405 | } | ||
406 | } | ||
407 | |||
408 | kfree(name); | ||
409 | return hit; | ||
410 | } | ||
411 | |||
412 | struct tegra_xusb_lane * | ||
413 | tegra_xusb_port_find_lane(struct tegra_xusb_port *port, | ||
414 | const struct tegra_xusb_lane_map *map, | ||
415 | const char *function) | ||
416 | { | ||
417 | struct tegra_xusb_lane *lane, *match = ERR_PTR(-ENODEV); | ||
418 | |||
419 | for (map = map; map->type; map++) { | ||
420 | if (port->index != map->port) | ||
421 | continue; | ||
422 | |||
423 | lane = tegra_xusb_find_lane(port->padctl, map->type, | ||
424 | map->index); | ||
425 | if (IS_ERR(lane)) | ||
426 | continue; | ||
427 | |||
428 | if (!tegra_xusb_lane_check(lane, function)) | ||
429 | continue; | ||
430 | |||
431 | if (!IS_ERR(match)) | ||
432 | dev_err(&port->dev, "conflicting match: %s-%u / %s\n", | ||
433 | map->type, map->index, match->soc->name); | ||
434 | else | ||
435 | match = lane; | ||
436 | } | ||
437 | |||
438 | return match; | ||
439 | } | ||
440 | |||
441 | static struct device_node * | ||
442 | tegra_xusb_find_port_node(struct tegra_xusb_padctl *padctl, const char *type, | ||
443 | unsigned int index) | ||
444 | { | ||
445 | /* | ||
446 | * of_find_node_by_name() drops a reference, so make sure to grab one. | ||
447 | */ | ||
448 | struct device_node *np = of_node_get(padctl->dev->of_node); | ||
449 | |||
450 | np = of_find_node_by_name(np, "ports"); | ||
451 | if (np) { | ||
452 | char *name; | ||
453 | |||
454 | name = kasprintf(GFP_KERNEL, "%s-%u", type, index); | ||
455 | np = of_find_node_by_name(np, name); | ||
456 | kfree(name); | ||
457 | } | ||
458 | |||
459 | return np; | ||
460 | } | ||
461 | |||
462 | struct tegra_xusb_port * | ||
463 | tegra_xusb_find_port(struct tegra_xusb_padctl *padctl, const char *type, | ||
464 | unsigned int index) | ||
465 | { | ||
466 | struct tegra_xusb_port *port; | ||
467 | struct device_node *np; | ||
468 | |||
469 | np = tegra_xusb_find_port_node(padctl, type, index); | ||
470 | if (!np) | ||
471 | return NULL; | ||
472 | |||
473 | list_for_each_entry(port, &padctl->ports, list) { | ||
474 | if (np == port->dev.of_node) { | ||
475 | of_node_put(np); | ||
476 | return port; | ||
477 | } | ||
478 | } | ||
479 | |||
480 | of_node_put(np); | ||
481 | |||
482 | return NULL; | ||
483 | } | ||
484 | |||
485 | struct tegra_xusb_usb2_port * | ||
486 | tegra_xusb_find_usb2_port(struct tegra_xusb_padctl *padctl, unsigned int index) | ||
487 | { | ||
488 | struct tegra_xusb_port *port; | ||
489 | |||
490 | port = tegra_xusb_find_port(padctl, "usb2", index); | ||
491 | if (port) | ||
492 | return to_usb2_port(port); | ||
493 | |||
494 | return NULL; | ||
495 | } | ||
496 | |||
497 | struct tegra_xusb_usb3_port * | ||
498 | tegra_xusb_find_usb3_port(struct tegra_xusb_padctl *padctl, unsigned int index) | ||
499 | { | ||
500 | struct tegra_xusb_port *port; | ||
501 | |||
502 | port = tegra_xusb_find_port(padctl, "usb3", index); | ||
503 | if (port) | ||
504 | return to_usb3_port(port); | ||
505 | |||
506 | return NULL; | ||
507 | } | ||
508 | |||
509 | static void tegra_xusb_port_release(struct device *dev) | ||
510 | { | ||
511 | } | ||
512 | |||
513 | static struct device_type tegra_xusb_port_type = { | ||
514 | .release = tegra_xusb_port_release, | ||
515 | }; | ||
516 | |||
517 | static int tegra_xusb_port_init(struct tegra_xusb_port *port, | ||
518 | struct tegra_xusb_padctl *padctl, | ||
519 | struct device_node *np, | ||
520 | const char *name, | ||
521 | unsigned int index) | ||
522 | { | ||
523 | int err; | ||
524 | |||
525 | INIT_LIST_HEAD(&port->list); | ||
526 | port->padctl = padctl; | ||
527 | port->index = index; | ||
528 | |||
529 | device_initialize(&port->dev); | ||
530 | port->dev.type = &tegra_xusb_port_type; | ||
531 | port->dev.of_node = of_node_get(np); | ||
532 | port->dev.parent = padctl->dev; | ||
533 | |||
534 | err = dev_set_name(&port->dev, "%s-%u", name, index); | ||
535 | if (err < 0) | ||
536 | goto unregister; | ||
537 | |||
538 | err = device_add(&port->dev); | ||
539 | if (err < 0) | ||
540 | goto unregister; | ||
541 | |||
542 | return 0; | ||
543 | |||
544 | unregister: | ||
545 | device_unregister(&port->dev); | ||
546 | return err; | ||
547 | } | ||
548 | |||
549 | static void tegra_xusb_port_unregister(struct tegra_xusb_port *port) | ||
550 | { | ||
551 | device_unregister(&port->dev); | ||
552 | } | ||
553 | |||
554 | static int tegra_xusb_usb2_port_parse_dt(struct tegra_xusb_usb2_port *usb2) | ||
555 | { | ||
556 | struct tegra_xusb_port *port = &usb2->base; | ||
557 | struct device_node *np = port->dev.of_node; | ||
558 | |||
559 | usb2->internal = of_property_read_bool(np, "nvidia,internal"); | ||
560 | |||
561 | usb2->supply = devm_regulator_get(&port->dev, "vbus"); | ||
562 | if (IS_ERR(usb2->supply)) | ||
563 | return PTR_ERR(usb2->supply); | ||
564 | |||
565 | return 0; | ||
566 | } | ||
567 | |||
568 | static int tegra_xusb_add_usb2_port(struct tegra_xusb_padctl *padctl, | ||
569 | unsigned int index) | ||
570 | { | ||
571 | struct tegra_xusb_usb2_port *usb2; | ||
572 | struct device_node *np; | ||
573 | int err = 0; | ||
574 | |||
575 | /* | ||
576 | * USB2 ports don't require additional properties, but if the port is | ||
577 | * marked as disabled there is no reason to register it. | ||
578 | */ | ||
579 | np = tegra_xusb_find_port_node(padctl, "usb2", index); | ||
580 | if (!np || !of_device_is_available(np)) | ||
581 | goto out; | ||
582 | |||
583 | usb2 = devm_kzalloc(padctl->dev, sizeof(*usb2), GFP_KERNEL); | ||
584 | if (!usb2) { | ||
585 | err = -ENOMEM; | ||
586 | goto out; | ||
587 | } | ||
588 | |||
589 | err = tegra_xusb_port_init(&usb2->base, padctl, np, "usb2", index); | ||
590 | if (err < 0) | ||
591 | goto out; | ||
592 | |||
593 | usb2->base.ops = padctl->soc->ports.usb2.ops; | ||
594 | |||
595 | usb2->base.lane = usb2->base.ops->map(&usb2->base); | ||
596 | if (IS_ERR(usb2->base.lane)) { | ||
597 | err = PTR_ERR(usb2->base.lane); | ||
598 | goto out; | ||
599 | } | ||
600 | |||
601 | err = tegra_xusb_usb2_port_parse_dt(usb2); | ||
602 | if (err < 0) { | ||
603 | tegra_xusb_port_unregister(&usb2->base); | ||
604 | goto out; | ||
605 | } | ||
606 | |||
607 | list_add_tail(&usb2->base.list, &padctl->ports); | ||
608 | |||
609 | out: | ||
610 | of_node_put(np); | ||
611 | return err; | ||
612 | } | ||
613 | |||
614 | static int tegra_xusb_ulpi_port_parse_dt(struct tegra_xusb_ulpi_port *ulpi) | ||
615 | { | ||
616 | struct tegra_xusb_port *port = &ulpi->base; | ||
617 | struct device_node *np = port->dev.of_node; | ||
618 | |||
619 | ulpi->internal = of_property_read_bool(np, "nvidia,internal"); | ||
620 | |||
621 | return 0; | ||
622 | } | ||
623 | |||
624 | static int tegra_xusb_add_ulpi_port(struct tegra_xusb_padctl *padctl, | ||
625 | unsigned int index) | ||
626 | { | ||
627 | struct tegra_xusb_ulpi_port *ulpi; | ||
628 | struct device_node *np; | ||
629 | int err = 0; | ||
630 | |||
631 | np = tegra_xusb_find_port_node(padctl, "ulpi", index); | ||
632 | if (!np || !of_device_is_available(np)) | ||
633 | goto out; | ||
634 | |||
635 | ulpi = devm_kzalloc(padctl->dev, sizeof(*ulpi), GFP_KERNEL); | ||
636 | if (!ulpi) { | ||
637 | err = -ENOMEM; | ||
638 | goto out; | ||
639 | } | ||
640 | |||
641 | err = tegra_xusb_port_init(&ulpi->base, padctl, np, "ulpi", index); | ||
642 | if (err < 0) | ||
643 | goto out; | ||
644 | |||
645 | ulpi->base.ops = padctl->soc->ports.ulpi.ops; | ||
646 | |||
647 | ulpi->base.lane = ulpi->base.ops->map(&ulpi->base); | ||
648 | if (IS_ERR(ulpi->base.lane)) { | ||
649 | err = PTR_ERR(ulpi->base.lane); | ||
650 | goto out; | ||
651 | } | ||
652 | |||
653 | err = tegra_xusb_ulpi_port_parse_dt(ulpi); | ||
654 | if (err < 0) { | ||
655 | tegra_xusb_port_unregister(&ulpi->base); | ||
656 | goto out; | ||
657 | } | ||
658 | |||
659 | list_add_tail(&ulpi->base.list, &padctl->ports); | ||
660 | |||
661 | out: | ||
662 | of_node_put(np); | ||
663 | return err; | ||
664 | } | ||
665 | |||
666 | static int tegra_xusb_hsic_port_parse_dt(struct tegra_xusb_hsic_port *hsic) | ||
667 | { | ||
668 | /* XXX */ | ||
669 | return 0; | ||
670 | } | ||
671 | |||
672 | static int tegra_xusb_add_hsic_port(struct tegra_xusb_padctl *padctl, | ||
673 | unsigned int index) | ||
674 | { | ||
675 | struct tegra_xusb_hsic_port *hsic; | ||
676 | struct device_node *np; | ||
677 | int err = 0; | ||
678 | |||
679 | np = tegra_xusb_find_port_node(padctl, "hsic", index); | ||
680 | if (!np || !of_device_is_available(np)) | ||
681 | goto out; | ||
682 | |||
683 | hsic = devm_kzalloc(padctl->dev, sizeof(*hsic), GFP_KERNEL); | ||
684 | if (!hsic) { | ||
685 | err = -ENOMEM; | ||
686 | goto out; | ||
687 | } | ||
688 | |||
689 | err = tegra_xusb_port_init(&hsic->base, padctl, np, "hsic", index); | ||
690 | if (err < 0) | ||
691 | goto out; | ||
692 | |||
693 | hsic->base.ops = padctl->soc->ports.hsic.ops; | ||
694 | |||
695 | hsic->base.lane = hsic->base.ops->map(&hsic->base); | ||
696 | if (IS_ERR(hsic->base.lane)) { | ||
697 | err = PTR_ERR(hsic->base.lane); | ||
698 | goto out; | ||
699 | } | ||
700 | |||
701 | err = tegra_xusb_hsic_port_parse_dt(hsic); | ||
702 | if (err < 0) { | ||
703 | tegra_xusb_port_unregister(&hsic->base); | ||
704 | goto out; | ||
705 | } | ||
706 | |||
707 | list_add_tail(&hsic->base.list, &padctl->ports); | ||
708 | |||
709 | out: | ||
710 | of_node_put(np); | ||
711 | return err; | ||
712 | } | ||
713 | |||
714 | static int tegra_xusb_usb3_port_parse_dt(struct tegra_xusb_usb3_port *usb3) | ||
715 | { | ||
716 | struct tegra_xusb_port *port = &usb3->base; | ||
717 | struct device_node *np = port->dev.of_node; | ||
718 | u32 value; | ||
719 | int err; | ||
720 | |||
721 | err = of_property_read_u32(np, "nvidia,usb2-companion", &value); | ||
722 | if (err < 0) { | ||
723 | dev_err(&port->dev, "failed to read port: %d\n", err); | ||
724 | return err; | ||
725 | } | ||
726 | |||
727 | usb3->port = value; | ||
728 | |||
729 | usb3->internal = of_property_read_bool(np, "nvidia,internal"); | ||
730 | |||
731 | usb3->supply = devm_regulator_get(&port->dev, "vbus"); | ||
732 | if (IS_ERR(usb3->supply)) | ||
733 | return PTR_ERR(usb3->supply); | ||
734 | |||
735 | return 0; | ||
736 | } | ||
737 | |||
738 | static int tegra_xusb_add_usb3_port(struct tegra_xusb_padctl *padctl, | ||
739 | unsigned int index) | ||
740 | { | ||
741 | struct tegra_xusb_usb3_port *usb3; | ||
742 | struct device_node *np; | ||
743 | int err = 0; | ||
744 | |||
745 | /* | ||
746 | * If there is no supplemental configuration in the device tree the | ||
747 | * port is unusable. But it is valid to configure only a single port, | ||
748 | * hence return 0 instead of an error to allow ports to be optional. | ||
749 | */ | ||
750 | np = tegra_xusb_find_port_node(padctl, "usb3", index); | ||
751 | if (!np || !of_device_is_available(np)) | ||
752 | goto out; | ||
753 | |||
754 | usb3 = devm_kzalloc(padctl->dev, sizeof(*usb3), GFP_KERNEL); | ||
755 | if (!usb3) { | ||
756 | err = -ENOMEM; | ||
757 | goto out; | ||
758 | } | ||
759 | |||
760 | err = tegra_xusb_port_init(&usb3->base, padctl, np, "usb3", index); | ||
761 | if (err < 0) | ||
762 | goto out; | ||
763 | |||
764 | usb3->base.ops = padctl->soc->ports.usb3.ops; | ||
765 | |||
766 | usb3->base.lane = usb3->base.ops->map(&usb3->base); | ||
767 | if (IS_ERR(usb3->base.lane)) { | ||
768 | err = PTR_ERR(usb3->base.lane); | ||
769 | goto out; | ||
770 | } | ||
771 | |||
772 | err = tegra_xusb_usb3_port_parse_dt(usb3); | ||
773 | if (err < 0) { | ||
774 | tegra_xusb_port_unregister(&usb3->base); | ||
775 | goto out; | ||
776 | } | ||
777 | |||
778 | list_add_tail(&usb3->base.list, &padctl->ports); | ||
779 | |||
780 | out: | ||
781 | of_node_put(np); | ||
782 | return err; | ||
783 | } | ||
784 | |||
785 | static void __tegra_xusb_remove_ports(struct tegra_xusb_padctl *padctl) | ||
786 | { | ||
787 | struct tegra_xusb_port *port, *tmp; | ||
788 | |||
789 | list_for_each_entry_safe_reverse(port, tmp, &padctl->ports, list) { | ||
790 | list_del(&port->list); | ||
791 | tegra_xusb_port_unregister(port); | ||
792 | } | ||
793 | } | ||
794 | |||
795 | static int tegra_xusb_setup_ports(struct tegra_xusb_padctl *padctl) | ||
796 | { | ||
797 | struct tegra_xusb_port *port; | ||
798 | unsigned int i; | ||
799 | int err = 0; | ||
800 | |||
801 | mutex_lock(&padctl->lock); | ||
802 | |||
803 | for (i = 0; i < padctl->soc->ports.usb2.count; i++) { | ||
804 | err = tegra_xusb_add_usb2_port(padctl, i); | ||
805 | if (err < 0) | ||
806 | goto remove_ports; | ||
807 | } | ||
808 | |||
809 | for (i = 0; i < padctl->soc->ports.ulpi.count; i++) { | ||
810 | err = tegra_xusb_add_ulpi_port(padctl, i); | ||
811 | if (err < 0) | ||
812 | goto remove_ports; | ||
813 | } | ||
814 | |||
815 | for (i = 0; i < padctl->soc->ports.hsic.count; i++) { | ||
816 | err = tegra_xusb_add_hsic_port(padctl, i); | ||
817 | if (err < 0) | ||
818 | goto remove_ports; | ||
819 | } | ||
820 | |||
821 | for (i = 0; i < padctl->soc->ports.usb3.count; i++) { | ||
822 | err = tegra_xusb_add_usb3_port(padctl, i); | ||
823 | if (err < 0) | ||
824 | goto remove_ports; | ||
825 | } | ||
826 | |||
827 | list_for_each_entry(port, &padctl->ports, list) { | ||
828 | err = port->ops->enable(port); | ||
829 | if (err < 0) | ||
830 | dev_err(padctl->dev, "failed to enable port %s: %d\n", | ||
831 | dev_name(&port->dev), err); | ||
832 | } | ||
833 | |||
834 | goto unlock; | ||
835 | |||
836 | remove_ports: | ||
837 | __tegra_xusb_remove_ports(padctl); | ||
838 | unlock: | ||
839 | mutex_unlock(&padctl->lock); | ||
840 | return err; | ||
841 | } | ||
842 | |||
843 | static void tegra_xusb_remove_ports(struct tegra_xusb_padctl *padctl) | ||
844 | { | ||
845 | mutex_lock(&padctl->lock); | ||
846 | __tegra_xusb_remove_ports(padctl); | ||
847 | mutex_unlock(&padctl->lock); | ||
848 | } | ||
849 | |||
850 | static int tegra_xusb_padctl_probe(struct platform_device *pdev) | ||
851 | { | ||
852 | struct device_node *np = of_node_get(pdev->dev.of_node); | ||
853 | const struct tegra_xusb_padctl_soc *soc; | ||
854 | struct tegra_xusb_padctl *padctl; | ||
855 | const struct of_device_id *match; | ||
856 | struct resource *res; | ||
857 | int err; | ||
858 | |||
859 | /* for backwards compatibility with old device trees */ | ||
860 | np = of_find_node_by_name(np, "pads"); | ||
861 | if (!np) { | ||
862 | dev_warn(&pdev->dev, "deprecated DT, using legacy driver\n"); | ||
863 | return tegra_xusb_padctl_legacy_probe(pdev); | ||
864 | } | ||
865 | |||
866 | of_node_put(np); | ||
867 | |||
868 | match = of_match_node(tegra_xusb_padctl_of_match, pdev->dev.of_node); | ||
869 | soc = match->data; | ||
870 | |||
871 | padctl = soc->ops->probe(&pdev->dev, soc); | ||
872 | if (IS_ERR(padctl)) | ||
873 | return PTR_ERR(padctl); | ||
874 | |||
875 | platform_set_drvdata(pdev, padctl); | ||
876 | INIT_LIST_HEAD(&padctl->ports); | ||
877 | INIT_LIST_HEAD(&padctl->lanes); | ||
878 | INIT_LIST_HEAD(&padctl->pads); | ||
879 | mutex_init(&padctl->lock); | ||
880 | |||
881 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
882 | padctl->regs = devm_ioremap_resource(&pdev->dev, res); | ||
883 | if (IS_ERR(padctl->regs)) { | ||
884 | err = PTR_ERR(padctl->regs); | ||
885 | goto remove; | ||
886 | } | ||
887 | |||
888 | padctl->rst = devm_reset_control_get(&pdev->dev, NULL); | ||
889 | if (IS_ERR(padctl->rst)) { | ||
890 | err = PTR_ERR(padctl->rst); | ||
891 | goto remove; | ||
892 | } | ||
893 | |||
894 | err = reset_control_deassert(padctl->rst); | ||
895 | if (err < 0) | ||
896 | goto remove; | ||
897 | |||
898 | err = tegra_xusb_setup_pads(padctl); | ||
899 | if (err < 0) { | ||
900 | dev_err(&pdev->dev, "failed to setup pads: %d\n", err); | ||
901 | goto reset; | ||
902 | } | ||
903 | |||
904 | err = tegra_xusb_setup_ports(padctl); | ||
905 | if (err) { | ||
906 | dev_err(&pdev->dev, "failed to setup XUSB ports: %d\n", err); | ||
907 | goto remove_pads; | ||
908 | } | ||
909 | |||
910 | return 0; | ||
911 | |||
912 | remove_pads: | ||
913 | tegra_xusb_remove_pads(padctl); | ||
914 | reset: | ||
915 | reset_control_assert(padctl->rst); | ||
916 | remove: | ||
917 | soc->ops->remove(padctl); | ||
918 | return err; | ||
919 | } | ||
920 | |||
921 | static int tegra_xusb_padctl_remove(struct platform_device *pdev) | ||
922 | { | ||
923 | struct tegra_xusb_padctl *padctl = platform_get_drvdata(pdev); | ||
924 | int err; | ||
925 | |||
926 | tegra_xusb_remove_ports(padctl); | ||
927 | tegra_xusb_remove_pads(padctl); | ||
928 | |||
929 | err = reset_control_assert(padctl->rst); | ||
930 | if (err < 0) | ||
931 | dev_err(&pdev->dev, "failed to assert reset: %d\n", err); | ||
932 | |||
933 | padctl->soc->ops->remove(padctl); | ||
934 | |||
935 | return err; | ||
936 | } | ||
937 | |||
938 | static struct platform_driver tegra_xusb_padctl_driver = { | ||
939 | .driver = { | ||
940 | .name = "tegra-xusb-padctl", | ||
941 | .of_match_table = tegra_xusb_padctl_of_match, | ||
942 | }, | ||
943 | .probe = tegra_xusb_padctl_probe, | ||
944 | .remove = tegra_xusb_padctl_remove, | ||
945 | }; | ||
946 | module_platform_driver(tegra_xusb_padctl_driver); | ||
947 | |||
948 | struct tegra_xusb_padctl *tegra_xusb_padctl_get(struct device *dev) | ||
949 | { | ||
950 | struct tegra_xusb_padctl *padctl; | ||
951 | struct platform_device *pdev; | ||
952 | struct device_node *np; | ||
953 | |||
954 | np = of_parse_phandle(dev->of_node, "nvidia,xusb-padctl", 0); | ||
955 | if (!np) | ||
956 | return ERR_PTR(-EINVAL); | ||
957 | |||
958 | /* | ||
959 | * This is slightly ugly. A better implementation would be to keep a | ||
960 | * registry of pad controllers, but since there will almost certainly | ||
961 | * only ever be one per SoC that would be a little overkill. | ||
962 | */ | ||
963 | pdev = of_find_device_by_node(np); | ||
964 | if (!pdev) { | ||
965 | of_node_put(np); | ||
966 | return ERR_PTR(-ENODEV); | ||
967 | } | ||
968 | |||
969 | of_node_put(np); | ||
970 | |||
971 | padctl = platform_get_drvdata(pdev); | ||
972 | if (!padctl) { | ||
973 | put_device(&pdev->dev); | ||
974 | return ERR_PTR(-EPROBE_DEFER); | ||
975 | } | ||
976 | |||
977 | return padctl; | ||
978 | } | ||
979 | EXPORT_SYMBOL_GPL(tegra_xusb_padctl_get); | ||
980 | |||
981 | void tegra_xusb_padctl_put(struct tegra_xusb_padctl *padctl) | ||
982 | { | ||
983 | if (padctl) | ||
984 | put_device(padctl->dev); | ||
985 | } | ||
986 | EXPORT_SYMBOL_GPL(tegra_xusb_padctl_put); | ||
987 | |||
988 | int tegra_xusb_padctl_usb3_save_context(struct tegra_xusb_padctl *padctl, | ||
989 | unsigned int port) | ||
990 | { | ||
991 | if (padctl->soc->ops->usb3_save_context) | ||
992 | return padctl->soc->ops->usb3_save_context(padctl, port); | ||
993 | |||
994 | return -ENOSYS; | ||
995 | } | ||
996 | EXPORT_SYMBOL_GPL(tegra_xusb_padctl_usb3_save_context); | ||
997 | |||
998 | int tegra_xusb_padctl_hsic_set_idle(struct tegra_xusb_padctl *padctl, | ||
999 | unsigned int port, bool idle) | ||
1000 | { | ||
1001 | if (padctl->soc->ops->hsic_set_idle) | ||
1002 | return padctl->soc->ops->hsic_set_idle(padctl, port, idle); | ||
1003 | |||
1004 | return -ENOSYS; | ||
1005 | } | ||
1006 | EXPORT_SYMBOL_GPL(tegra_xusb_padctl_hsic_set_idle); | ||
1007 | |||
1008 | int tegra_xusb_padctl_usb3_set_lfps_detect(struct tegra_xusb_padctl *padctl, | ||
1009 | unsigned int port, bool enable) | ||
1010 | { | ||
1011 | if (padctl->soc->ops->usb3_set_lfps_detect) | ||
1012 | return padctl->soc->ops->usb3_set_lfps_detect(padctl, port, | ||
1013 | enable); | ||
1014 | |||
1015 | return -ENOSYS; | ||
1016 | } | ||
1017 | EXPORT_SYMBOL_GPL(tegra_xusb_padctl_usb3_set_lfps_detect); | ||
1018 | |||
1019 | MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); | ||
1020 | MODULE_DESCRIPTION("Tegra XUSB Pad Controller driver"); | ||
1021 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h new file mode 100644 index 000000000000..b49dbc36efa3 --- /dev/null +++ b/drivers/phy/tegra/xusb.h | |||
@@ -0,0 +1,421 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved. | ||
3 | * Copyright (c) 2015, Google Inc. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | */ | ||
14 | |||
15 | #ifndef __PHY_TEGRA_XUSB_H | ||
16 | #define __PHY_TEGRA_XUSB_H | ||
17 | |||
18 | #include <linux/io.h> | ||
19 | #include <linux/mutex.h> | ||
20 | #include <linux/workqueue.h> | ||
21 | |||
22 | /* legacy entry points for backwards-compatibility */ | ||
23 | int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev); | ||
24 | int tegra_xusb_padctl_legacy_remove(struct platform_device *pdev); | ||
25 | |||
26 | struct phy; | ||
27 | struct phy_provider; | ||
28 | struct platform_device; | ||
29 | struct regulator; | ||
30 | |||
31 | /* | ||
32 | * lanes | ||
33 | */ | ||
34 | struct tegra_xusb_lane_soc { | ||
35 | const char *name; | ||
36 | |||
37 | unsigned int offset; | ||
38 | unsigned int shift; | ||
39 | unsigned int mask; | ||
40 | |||
41 | const char * const *funcs; | ||
42 | unsigned int num_funcs; | ||
43 | }; | ||
44 | |||
45 | struct tegra_xusb_lane { | ||
46 | const struct tegra_xusb_lane_soc *soc; | ||
47 | struct tegra_xusb_pad *pad; | ||
48 | struct device_node *np; | ||
49 | struct list_head list; | ||
50 | unsigned int function; | ||
51 | unsigned int index; | ||
52 | }; | ||
53 | |||
54 | int tegra_xusb_lane_parse_dt(struct tegra_xusb_lane *lane, | ||
55 | struct device_node *np); | ||
56 | |||
57 | struct tegra_xusb_usb2_lane { | ||
58 | struct tegra_xusb_lane base; | ||
59 | |||
60 | u32 hs_curr_level_offset; | ||
61 | }; | ||
62 | |||
63 | static inline struct tegra_xusb_usb2_lane * | ||
64 | to_usb2_lane(struct tegra_xusb_lane *lane) | ||
65 | { | ||
66 | return container_of(lane, struct tegra_xusb_usb2_lane, base); | ||
67 | } | ||
68 | |||
69 | struct tegra_xusb_ulpi_lane { | ||
70 | struct tegra_xusb_lane base; | ||
71 | }; | ||
72 | |||
73 | static inline struct tegra_xusb_ulpi_lane * | ||
74 | to_ulpi_lane(struct tegra_xusb_lane *lane) | ||
75 | { | ||
76 | return container_of(lane, struct tegra_xusb_ulpi_lane, base); | ||
77 | } | ||
78 | |||
79 | struct tegra_xusb_hsic_lane { | ||
80 | struct tegra_xusb_lane base; | ||
81 | |||
82 | u32 strobe_trim; | ||
83 | u32 rx_strobe_trim; | ||
84 | u32 rx_data_trim; | ||
85 | u32 tx_rtune_n; | ||
86 | u32 tx_rtune_p; | ||
87 | u32 tx_rslew_n; | ||
88 | u32 tx_rslew_p; | ||
89 | bool auto_term; | ||
90 | }; | ||
91 | |||
92 | static inline struct tegra_xusb_hsic_lane * | ||
93 | to_hsic_lane(struct tegra_xusb_lane *lane) | ||
94 | { | ||
95 | return container_of(lane, struct tegra_xusb_hsic_lane, base); | ||
96 | } | ||
97 | |||
98 | struct tegra_xusb_pcie_lane { | ||
99 | struct tegra_xusb_lane base; | ||
100 | }; | ||
101 | |||
102 | static inline struct tegra_xusb_pcie_lane * | ||
103 | to_pcie_lane(struct tegra_xusb_lane *lane) | ||
104 | { | ||
105 | return container_of(lane, struct tegra_xusb_pcie_lane, base); | ||
106 | } | ||
107 | |||
108 | struct tegra_xusb_sata_lane { | ||
109 | struct tegra_xusb_lane base; | ||
110 | }; | ||
111 | |||
112 | static inline struct tegra_xusb_sata_lane * | ||
113 | to_sata_lane(struct tegra_xusb_lane *lane) | ||
114 | { | ||
115 | return container_of(lane, struct tegra_xusb_sata_lane, base); | ||
116 | } | ||
117 | |||
118 | struct tegra_xusb_lane_ops { | ||
119 | struct tegra_xusb_lane *(*probe)(struct tegra_xusb_pad *pad, | ||
120 | struct device_node *np, | ||
121 | unsigned int index); | ||
122 | void (*remove)(struct tegra_xusb_lane *lane); | ||
123 | }; | ||
124 | |||
125 | /* | ||
126 | * pads | ||
127 | */ | ||
128 | struct tegra_xusb_pad_soc; | ||
129 | struct tegra_xusb_padctl; | ||
130 | |||
131 | struct tegra_xusb_pad_ops { | ||
132 | struct tegra_xusb_pad *(*probe)(struct tegra_xusb_padctl *padctl, | ||
133 | const struct tegra_xusb_pad_soc *soc, | ||
134 | struct device_node *np); | ||
135 | void (*remove)(struct tegra_xusb_pad *pad); | ||
136 | }; | ||
137 | |||
138 | struct tegra_xusb_pad_soc { | ||
139 | const char *name; | ||
140 | |||
141 | const struct tegra_xusb_lane_soc *lanes; | ||
142 | unsigned int num_lanes; | ||
143 | |||
144 | const struct tegra_xusb_pad_ops *ops; | ||
145 | }; | ||
146 | |||
147 | struct tegra_xusb_pad { | ||
148 | const struct tegra_xusb_pad_soc *soc; | ||
149 | struct tegra_xusb_padctl *padctl; | ||
150 | struct phy_provider *provider; | ||
151 | struct phy **lanes; | ||
152 | struct device dev; | ||
153 | |||
154 | const struct tegra_xusb_lane_ops *ops; | ||
155 | |||
156 | struct list_head list; | ||
157 | }; | ||
158 | |||
159 | static inline struct tegra_xusb_pad *to_tegra_xusb_pad(struct device *dev) | ||
160 | { | ||
161 | return container_of(dev, struct tegra_xusb_pad, dev); | ||
162 | } | ||
163 | |||
164 | int tegra_xusb_pad_init(struct tegra_xusb_pad *pad, | ||
165 | struct tegra_xusb_padctl *padctl, | ||
166 | struct device_node *np); | ||
167 | int tegra_xusb_pad_register(struct tegra_xusb_pad *pad, | ||
168 | const struct phy_ops *ops); | ||
169 | void tegra_xusb_pad_unregister(struct tegra_xusb_pad *pad); | ||
170 | |||
171 | struct tegra_xusb_usb2_pad { | ||
172 | struct tegra_xusb_pad base; | ||
173 | |||
174 | struct clk *clk; | ||
175 | unsigned int enable; | ||
176 | struct mutex lock; | ||
177 | }; | ||
178 | |||
179 | static inline struct tegra_xusb_usb2_pad * | ||
180 | to_usb2_pad(struct tegra_xusb_pad *pad) | ||
181 | { | ||
182 | return container_of(pad, struct tegra_xusb_usb2_pad, base); | ||
183 | } | ||
184 | |||
185 | struct tegra_xusb_ulpi_pad { | ||
186 | struct tegra_xusb_pad base; | ||
187 | }; | ||
188 | |||
189 | static inline struct tegra_xusb_ulpi_pad * | ||
190 | to_ulpi_pad(struct tegra_xusb_pad *pad) | ||
191 | { | ||
192 | return container_of(pad, struct tegra_xusb_ulpi_pad, base); | ||
193 | } | ||
194 | |||
195 | struct tegra_xusb_hsic_pad { | ||
196 | struct tegra_xusb_pad base; | ||
197 | |||
198 | struct regulator *supply; | ||
199 | struct clk *clk; | ||
200 | }; | ||
201 | |||
202 | static inline struct tegra_xusb_hsic_pad * | ||
203 | to_hsic_pad(struct tegra_xusb_pad *pad) | ||
204 | { | ||
205 | return container_of(pad, struct tegra_xusb_hsic_pad, base); | ||
206 | } | ||
207 | |||
208 | struct tegra_xusb_pcie_pad { | ||
209 | struct tegra_xusb_pad base; | ||
210 | |||
211 | struct reset_control *rst; | ||
212 | struct clk *pll; | ||
213 | |||
214 | unsigned int enable; | ||
215 | }; | ||
216 | |||
217 | static inline struct tegra_xusb_pcie_pad * | ||
218 | to_pcie_pad(struct tegra_xusb_pad *pad) | ||
219 | { | ||
220 | return container_of(pad, struct tegra_xusb_pcie_pad, base); | ||
221 | } | ||
222 | |||
223 | struct tegra_xusb_sata_pad { | ||
224 | struct tegra_xusb_pad base; | ||
225 | |||
226 | struct reset_control *rst; | ||
227 | struct clk *pll; | ||
228 | |||
229 | unsigned int enable; | ||
230 | }; | ||
231 | |||
232 | static inline struct tegra_xusb_sata_pad * | ||
233 | to_sata_pad(struct tegra_xusb_pad *pad) | ||
234 | { | ||
235 | return container_of(pad, struct tegra_xusb_sata_pad, base); | ||
236 | } | ||
237 | |||
238 | /* | ||
239 | * ports | ||
240 | */ | ||
241 | struct tegra_xusb_port_ops; | ||
242 | |||
243 | struct tegra_xusb_port { | ||
244 | struct tegra_xusb_padctl *padctl; | ||
245 | struct tegra_xusb_lane *lane; | ||
246 | unsigned int index; | ||
247 | |||
248 | struct list_head list; | ||
249 | struct device dev; | ||
250 | |||
251 | const struct tegra_xusb_port_ops *ops; | ||
252 | }; | ||
253 | |||
254 | struct tegra_xusb_lane_map { | ||
255 | unsigned int port; | ||
256 | const char *type; | ||
257 | unsigned int index; | ||
258 | const char *func; | ||
259 | }; | ||
260 | |||
261 | struct tegra_xusb_lane * | ||
262 | tegra_xusb_port_find_lane(struct tegra_xusb_port *port, | ||
263 | const struct tegra_xusb_lane_map *map, | ||
264 | const char *function); | ||
265 | |||
266 | struct tegra_xusb_port * | ||
267 | tegra_xusb_find_port(struct tegra_xusb_padctl *padctl, const char *type, | ||
268 | unsigned int index); | ||
269 | |||
270 | struct tegra_xusb_usb2_port { | ||
271 | struct tegra_xusb_port base; | ||
272 | |||
273 | struct regulator *supply; | ||
274 | bool internal; | ||
275 | }; | ||
276 | |||
277 | static inline struct tegra_xusb_usb2_port * | ||
278 | to_usb2_port(struct tegra_xusb_port *port) | ||
279 | { | ||
280 | return container_of(port, struct tegra_xusb_usb2_port, base); | ||
281 | } | ||
282 | |||
283 | struct tegra_xusb_usb2_port * | ||
284 | tegra_xusb_find_usb2_port(struct tegra_xusb_padctl *padctl, | ||
285 | unsigned int index); | ||
286 | |||
287 | struct tegra_xusb_ulpi_port { | ||
288 | struct tegra_xusb_port base; | ||
289 | |||
290 | struct regulator *supply; | ||
291 | bool internal; | ||
292 | }; | ||
293 | |||
294 | static inline struct tegra_xusb_ulpi_port * | ||
295 | to_ulpi_port(struct tegra_xusb_port *port) | ||
296 | { | ||
297 | return container_of(port, struct tegra_xusb_ulpi_port, base); | ||
298 | } | ||
299 | |||
300 | struct tegra_xusb_hsic_port { | ||
301 | struct tegra_xusb_port base; | ||
302 | }; | ||
303 | |||
304 | static inline struct tegra_xusb_hsic_port * | ||
305 | to_hsic_port(struct tegra_xusb_port *port) | ||
306 | { | ||
307 | return container_of(port, struct tegra_xusb_hsic_port, base); | ||
308 | } | ||
309 | |||
310 | struct tegra_xusb_usb3_port { | ||
311 | struct tegra_xusb_port base; | ||
312 | struct regulator *supply; | ||
313 | bool context_saved; | ||
314 | unsigned int port; | ||
315 | bool internal; | ||
316 | |||
317 | u32 tap1; | ||
318 | u32 amp; | ||
319 | u32 ctle_z; | ||
320 | u32 ctle_g; | ||
321 | }; | ||
322 | |||
323 | static inline struct tegra_xusb_usb3_port * | ||
324 | to_usb3_port(struct tegra_xusb_port *port) | ||
325 | { | ||
326 | return container_of(port, struct tegra_xusb_usb3_port, base); | ||
327 | } | ||
328 | |||
329 | struct tegra_xusb_usb3_port * | ||
330 | tegra_xusb_find_usb3_port(struct tegra_xusb_padctl *padctl, | ||
331 | unsigned int index); | ||
332 | |||
333 | struct tegra_xusb_port_ops { | ||
334 | int (*enable)(struct tegra_xusb_port *port); | ||
335 | void (*disable)(struct tegra_xusb_port *port); | ||
336 | struct tegra_xusb_lane *(*map)(struct tegra_xusb_port *port); | ||
337 | }; | ||
338 | |||
339 | /* | ||
340 | * pad controller | ||
341 | */ | ||
342 | struct tegra_xusb_padctl_soc; | ||
343 | |||
344 | struct tegra_xusb_padctl_ops { | ||
345 | struct tegra_xusb_padctl * | ||
346 | (*probe)(struct device *dev, | ||
347 | const struct tegra_xusb_padctl_soc *soc); | ||
348 | void (*remove)(struct tegra_xusb_padctl *padctl); | ||
349 | |||
350 | int (*usb3_save_context)(struct tegra_xusb_padctl *padctl, | ||
351 | unsigned int index); | ||
352 | int (*hsic_set_idle)(struct tegra_xusb_padctl *padctl, | ||
353 | unsigned int index, bool idle); | ||
354 | int (*usb3_set_lfps_detect)(struct tegra_xusb_padctl *padctl, | ||
355 | unsigned int index, bool enable); | ||
356 | }; | ||
357 | |||
358 | struct tegra_xusb_padctl_soc { | ||
359 | const struct tegra_xusb_pad_soc * const *pads; | ||
360 | unsigned int num_pads; | ||
361 | |||
362 | struct { | ||
363 | struct { | ||
364 | const struct tegra_xusb_port_ops *ops; | ||
365 | unsigned int count; | ||
366 | } usb2, ulpi, hsic, usb3; | ||
367 | } ports; | ||
368 | |||
369 | const struct tegra_xusb_padctl_ops *ops; | ||
370 | }; | ||
371 | |||
372 | struct tegra_xusb_padctl { | ||
373 | struct device *dev; | ||
374 | void __iomem *regs; | ||
375 | struct mutex lock; | ||
376 | struct reset_control *rst; | ||
377 | |||
378 | const struct tegra_xusb_padctl_soc *soc; | ||
379 | |||
380 | struct tegra_xusb_pad *pcie; | ||
381 | struct tegra_xusb_pad *sata; | ||
382 | struct tegra_xusb_pad *ulpi; | ||
383 | struct tegra_xusb_pad *usb2; | ||
384 | struct tegra_xusb_pad *hsic; | ||
385 | |||
386 | struct list_head ports; | ||
387 | struct list_head lanes; | ||
388 | struct list_head pads; | ||
389 | |||
390 | unsigned int enable; | ||
391 | |||
392 | struct clk *clk; | ||
393 | }; | ||
394 | |||
395 | static inline void padctl_writel(struct tegra_xusb_padctl *padctl, u32 value, | ||
396 | unsigned long offset) | ||
397 | { | ||
398 | dev_dbg(padctl->dev, "%08lx < %08x\n", offset, value); | ||
399 | writel(value, padctl->regs + offset); | ||
400 | } | ||
401 | |||
402 | static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl, | ||
403 | unsigned long offset) | ||
404 | { | ||
405 | u32 value = readl(padctl->regs + offset); | ||
406 | dev_dbg(padctl->dev, "%08lx > %08x\n", offset, value); | ||
407 | return value; | ||
408 | } | ||
409 | |||
410 | struct tegra_xusb_lane *tegra_xusb_find_lane(struct tegra_xusb_padctl *padctl, | ||
411 | const char *name, | ||
412 | unsigned int index); | ||
413 | |||
414 | #if defined(CONFIG_ARCH_TEGRA_124_SOC) || defined(CONFIG_ARCH_TEGRA_132_SOC) | ||
415 | extern const struct tegra_xusb_padctl_soc tegra124_xusb_padctl_soc; | ||
416 | #endif | ||
417 | #if defined(CONFIG_ARCH_TEGRA_210_SOC) | ||
418 | extern const struct tegra_xusb_padctl_soc tegra210_xusb_padctl_soc; | ||
419 | #endif | ||
420 | |||
421 | #endif /* __PHY_TEGRA_XUSB_H */ | ||
diff --git a/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c b/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c index 2f06029c9405..946cda3fee35 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c | |||
@@ -873,7 +873,7 @@ static const struct of_device_id tegra_xusb_padctl_of_match[] = { | |||
873 | }; | 873 | }; |
874 | MODULE_DEVICE_TABLE(of, tegra_xusb_padctl_of_match); | 874 | MODULE_DEVICE_TABLE(of, tegra_xusb_padctl_of_match); |
875 | 875 | ||
876 | static int tegra_xusb_padctl_probe(struct platform_device *pdev) | 876 | int tegra_xusb_padctl_legacy_probe(struct platform_device *pdev) |
877 | { | 877 | { |
878 | struct tegra_xusb_padctl *padctl; | 878 | struct tegra_xusb_padctl *padctl; |
879 | const struct of_device_id *match; | 879 | const struct of_device_id *match; |
@@ -955,8 +955,9 @@ reset: | |||
955 | reset_control_assert(padctl->rst); | 955 | reset_control_assert(padctl->rst); |
956 | return err; | 956 | return err; |
957 | } | 957 | } |
958 | EXPORT_SYMBOL_GPL(tegra_xusb_padctl_legacy_probe); | ||
958 | 959 | ||
959 | static int tegra_xusb_padctl_remove(struct platform_device *pdev) | 960 | int tegra_xusb_padctl_legacy_remove(struct platform_device *pdev) |
960 | { | 961 | { |
961 | struct tegra_xusb_padctl *padctl = platform_get_drvdata(pdev); | 962 | struct tegra_xusb_padctl *padctl = platform_get_drvdata(pdev); |
962 | int err; | 963 | int err; |
@@ -969,17 +970,4 @@ static int tegra_xusb_padctl_remove(struct platform_device *pdev) | |||
969 | 970 | ||
970 | return err; | 971 | return err; |
971 | } | 972 | } |
972 | 973 | EXPORT_SYMBOL_GPL(tegra_xusb_padctl_legacy_remove); | |
973 | static struct platform_driver tegra_xusb_padctl_driver = { | ||
974 | .driver = { | ||
975 | .name = "tegra-xusb-padctl", | ||
976 | .of_match_table = tegra_xusb_padctl_of_match, | ||
977 | }, | ||
978 | .probe = tegra_xusb_padctl_probe, | ||
979 | .remove = tegra_xusb_padctl_remove, | ||
980 | }; | ||
981 | module_platform_driver(tegra_xusb_padctl_driver); | ||
982 | |||
983 | MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); | ||
984 | MODULE_DESCRIPTION("Tegra 124 XUSB Pad Control driver"); | ||
985 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h index 57bf7aab4516..7007a5f48080 100644 --- a/include/linux/clk/tegra.h +++ b/include/linux/clk/tegra.h | |||
@@ -121,4 +121,9 @@ static inline void tegra_cpu_clock_resume(void) | |||
121 | } | 121 | } |
122 | #endif | 122 | #endif |
123 | 123 | ||
124 | extern void tegra210_xusb_pll_hw_control_enable(void); | ||
125 | extern void tegra210_xusb_pll_hw_sequence_start(void); | ||
126 | extern void tegra210_sata_pll_hw_control_enable(void); | ||
127 | extern void tegra210_sata_pll_hw_sequence_start(void); | ||
128 | |||
124 | #endif /* __LINUX_CLK_TEGRA_H_ */ | 129 | #endif /* __LINUX_CLK_TEGRA_H_ */ |
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index 8cf05e341cff..a810f2a18842 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h | |||
@@ -77,6 +77,7 @@ struct phy { | |||
77 | */ | 77 | */ |
78 | struct phy_provider { | 78 | struct phy_provider { |
79 | struct device *dev; | 79 | struct device *dev; |
80 | struct device_node *children; | ||
80 | struct module *owner; | 81 | struct module *owner; |
81 | struct list_head list; | 82 | struct list_head list; |
82 | struct phy * (*of_xlate)(struct device *dev, | 83 | struct phy * (*of_xlate)(struct device *dev, |
@@ -93,10 +94,16 @@ struct phy_lookup { | |||
93 | #define to_phy(a) (container_of((a), struct phy, dev)) | 94 | #define to_phy(a) (container_of((a), struct phy, dev)) |
94 | 95 | ||
95 | #define of_phy_provider_register(dev, xlate) \ | 96 | #define of_phy_provider_register(dev, xlate) \ |
96 | __of_phy_provider_register((dev), THIS_MODULE, (xlate)) | 97 | __of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate)) |
97 | 98 | ||
98 | #define devm_of_phy_provider_register(dev, xlate) \ | 99 | #define devm_of_phy_provider_register(dev, xlate) \ |
99 | __devm_of_phy_provider_register((dev), THIS_MODULE, (xlate)) | 100 | __devm_of_phy_provider_register((dev), NULL, THIS_MODULE, (xlate)) |
101 | |||
102 | #define of_phy_provider_register_full(dev, children, xlate) \ | ||
103 | __of_phy_provider_register(dev, children, THIS_MODULE, xlate) | ||
104 | |||
105 | #define devm_of_phy_provider_register_full(dev, children, xlate) \ | ||
106 | __devm_of_phy_provider_register(dev, children, THIS_MODULE, xlate) | ||
100 | 107 | ||
101 | static inline void phy_set_drvdata(struct phy *phy, void *data) | 108 | static inline void phy_set_drvdata(struct phy *phy, void *data) |
102 | { | 109 | { |
@@ -147,11 +154,13 @@ struct phy *devm_phy_create(struct device *dev, struct device_node *node, | |||
147 | void phy_destroy(struct phy *phy); | 154 | void phy_destroy(struct phy *phy); |
148 | void devm_phy_destroy(struct device *dev, struct phy *phy); | 155 | void devm_phy_destroy(struct device *dev, struct phy *phy); |
149 | struct phy_provider *__of_phy_provider_register(struct device *dev, | 156 | struct phy_provider *__of_phy_provider_register(struct device *dev, |
150 | struct module *owner, struct phy * (*of_xlate)(struct device *dev, | 157 | struct device_node *children, struct module *owner, |
151 | struct of_phandle_args *args)); | 158 | struct phy * (*of_xlate)(struct device *dev, |
159 | struct of_phandle_args *args)); | ||
152 | struct phy_provider *__devm_of_phy_provider_register(struct device *dev, | 160 | struct phy_provider *__devm_of_phy_provider_register(struct device *dev, |
153 | struct module *owner, struct phy * (*of_xlate)(struct device *dev, | 161 | struct device_node *children, struct module *owner, |
154 | struct of_phandle_args *args)); | 162 | struct phy * (*of_xlate)(struct device *dev, |
163 | struct of_phandle_args *args)); | ||
155 | void of_phy_provider_unregister(struct phy_provider *phy_provider); | 164 | void of_phy_provider_unregister(struct phy_provider *phy_provider); |
156 | void devm_of_phy_provider_unregister(struct device *dev, | 165 | void devm_of_phy_provider_unregister(struct device *dev, |
157 | struct phy_provider *phy_provider); | 166 | struct phy_provider *phy_provider); |
@@ -312,15 +321,17 @@ static inline void devm_phy_destroy(struct device *dev, struct phy *phy) | |||
312 | } | 321 | } |
313 | 322 | ||
314 | static inline struct phy_provider *__of_phy_provider_register( | 323 | static inline struct phy_provider *__of_phy_provider_register( |
315 | struct device *dev, struct module *owner, struct phy * (*of_xlate)( | 324 | struct device *dev, struct device_node *children, struct module *owner, |
316 | struct device *dev, struct of_phandle_args *args)) | 325 | struct phy * (*of_xlate)(struct device *dev, |
326 | struct of_phandle_args *args)) | ||
317 | { | 327 | { |
318 | return ERR_PTR(-ENOSYS); | 328 | return ERR_PTR(-ENOSYS); |
319 | } | 329 | } |
320 | 330 | ||
321 | static inline struct phy_provider *__devm_of_phy_provider_register(struct device | 331 | static inline struct phy_provider *__devm_of_phy_provider_register(struct device |
322 | *dev, struct module *owner, struct phy * (*of_xlate)(struct device *dev, | 332 | *dev, struct device_node *children, struct module *owner, |
323 | struct of_phandle_args *args)) | 333 | struct phy * (*of_xlate)(struct device *dev, |
334 | struct of_phandle_args *args)) | ||
324 | { | 335 | { |
325 | return ERR_PTR(-ENOSYS); | 336 | return ERR_PTR(-ENOSYS); |
326 | } | 337 | } |
diff --git a/include/linux/phy/tegra/xusb.h b/include/linux/phy/tegra/xusb.h new file mode 100644 index 000000000000..8e1a57a78d9f --- /dev/null +++ b/include/linux/phy/tegra/xusb.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #ifndef PHY_TEGRA_XUSB_H | ||
15 | #define PHY_TEGRA_XUSB_H | ||
16 | |||
17 | struct tegra_xusb_padctl; | ||
18 | struct device; | ||
19 | |||
20 | struct tegra_xusb_padctl *tegra_xusb_padctl_get(struct device *dev); | ||
21 | void tegra_xusb_padctl_put(struct tegra_xusb_padctl *padctl); | ||
22 | |||
23 | int tegra_xusb_padctl_usb3_save_context(struct tegra_xusb_padctl *padctl, | ||
24 | unsigned int port); | ||
25 | int tegra_xusb_padctl_hsic_set_idle(struct tegra_xusb_padctl *padctl, | ||
26 | unsigned int port, bool idle); | ||
27 | int tegra_xusb_padctl_usb3_set_lfps_detect(struct tegra_xusb_padctl *padctl, | ||
28 | unsigned int port, bool enable); | ||
29 | |||
30 | #endif /* PHY_TEGRA_XUSB_H */ | ||
diff --git a/include/soc/tegra/fuse.h b/include/soc/tegra/fuse.h index 961b821b6a46..b4c9219e7f95 100644 --- a/include/soc/tegra/fuse.h +++ b/include/soc/tegra/fuse.h | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | #define TEGRA_FUSE_SKU_CALIB_0 0xf0 | 27 | #define TEGRA_FUSE_SKU_CALIB_0 0xf0 |
28 | #define TEGRA30_FUSE_SATA_CALIB 0x124 | 28 | #define TEGRA30_FUSE_SATA_CALIB 0x124 |
29 | #define TEGRA_FUSE_USB_CALIB_EXT_0 0x250 | ||
29 | 30 | ||
30 | #ifndef __ASSEMBLY__ | 31 | #ifndef __ASSEMBLY__ |
31 | 32 | ||