• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* SPDX-License-Identifier: GPL-2.0-only */
2
3// XHCI Controller 0:14.0
4
5Device (XHCI)
6{
7	Name (_ADR, 0x00140000)
8
9	Name (PLSD, 5) // Port Link State - RxDetect
10	Name (PLSP, 7) // Port Link State - Polling
11
12	OperationRegion (XPRT, PCI_Config, 0, 0x100)
13	Field (XPRT, AnyAcc, NoLock, Preserve)
14	{
15		DVID, 16,
16		Offset (0x10),
17		, 16,
18		XMEM, 16, // MEM_BASE
19		Offset (0x40),
20		, 11,
21		SWAI, 1,
22		, 20,
23		Offset (0x44),
24		, 12,
25		SAIP, 2,
26		, 18,
27		Offset (0x74),
28		D0D3, 2,
29		, 6,
30		PMEE, 1,  // PME_EN
31		, 6,
32		PMES, 1,  // PME_STS
33		Offset (0xb0),
34		, 13,
35		MB13, 1,
36		MB14, 1,
37		Offset (0xd0),
38		PR2R, 32,  // USB2PR
39		PR2M, 32,  // USB2PRM
40		PR3R, 32,  // USB3PR
41		PR3M, 32,  // USB3PRM
42	}
43
44	// Clear status bits
45	Method (LPCL, 0, Serialized)
46	{
47		OperationRegion (XREG, SystemMemory, ^XMEM << 16, 0x600)
48		Field (XREG, DWordAcc, Lock, Preserve)
49		{
50			Offset (0x510), // PORTSCNUSB3[0]
51			PSC0, 32,
52			Offset (0x520), // PORTSCNUSB3[1]
53			PSC1, 32,
54			Offset (0x530), // PORTSCNUSB3[2]
55			PSC2, 32,
56			Offset (0x540), // PORTSCNUSB3[3]
57			PSC3, 32,
58		}
59
60		// Port Enabled/Disabled (Bit 1)
61		Name (PEDB, 1 << 1)
62
63		// Change Status (Bits 23:17)
64		Name (CHST, 0x7f << 17)
65
66		// Port 0
67		Local0 = PSC0 & ~PEDB
68		PSC0 = Local0 | CHST
69
70		// Port 1
71		Local0 = PSC1 & ~PEDB
72		PSC1 = Local0 | CHST
73
74		// Port 2
75		Local0 = PSC2 & ~PEDB
76		PSC2 = Local0 | CHST
77
78		// Port 3
79		Local0 = PSC3 & ~PEDB
80		PSC3 = Local0 | CHST
81	}
82
83	Method (LPS0, 0, Serialized)
84	{
85		OperationRegion (XREG, SystemMemory, ^XMEM << 16, 0x600)
86		Field (XREG, DWordAcc, Lock, Preserve)
87		{
88			Offset (0x510), // PORTSCNUSB3
89			, 5,
90			PLS1, 4,	// [8:5] Port Link State
91			PPR1, 1,	// [9] Port Power
92			, 7,
93			CSC1, 1,	// [17] Connect Status Change
94			, 1,
95			WRC1, 1,	// [19] Warm Port Reset Change
96			, 11,
97			WPR1, 1,	// [31] Warm Port Reset
98			Offset (0x520), // PORTSCNUSB3
99			, 5,
100			PLS2, 4,	// [8:5] Port Link State
101			PPR2, 1,	// [9] Port Power
102			, 7,
103			CSC2, 1,	// [17] Connect Status Change
104			, 1,
105			WRC2, 1,	// [19] Warm Port Reset Change
106			, 11,
107			WPR2, 1,	// [31] Warm Port Reset
108			Offset (0x530), // PORTSCNUSB3
109			, 5,
110			PLS3, 4,	// [8:5] Port Link State
111			PPR3, 1,	// [9] Port Power
112			, 7,
113			CSC3, 1,	// [17] Connect Status Change
114			, 1,
115			WRC3, 1,	// [19] Warm Port Reset Change
116			, 11,
117			WPR3, 1,	// [31] Warm Port Reset
118			Offset (0x540), // PORTSCNUSB3
119			, 5,
120			PLS4, 4,	// [8:5] Port Link State
121			PPR4, 1,	// [9] Port Power
122			, 7,
123			CSC4, 1,	// [17] Connect Status Change
124			, 1,
125			WRC4, 1,	// [19] Warm Port Reset Change
126			, 11,
127			WPR4, 1,	// [31] Warm Port Reset
128		}
129
130		// Wait for all powered ports to finish polling
131		Local0 = 10
132		While ((PPR1 == 1 && PLS1 == PLSP || PPR2 == 1 && PLS2 == PLSP) ||
133		       (PPR3 == 1 && PLS3 == PLSP || PPR4 == 1 && PLS4 == PLSP))
134		{
135			If (Local0 == 0) {
136				Break
137			}
138			Local0--
139			Stall (10)
140		}
141
142		// For each USB3 Port:
143		//   If port is disconnected (PLS=5 PP=1 CSC=0)
144		//     1) Issue warm reset (WPR=1)
145		//     2) Poll for warm reset complete (WRC=0)
146		//     3) Write 1 to port status to clear
147
148		// Local# indicate if port is reset
149		Local1 = 0
150		Local2 = 0
151		Local3 = 0
152		Local4 = 0
153
154		If (PLS1 == PLSD && (CSC1 == 0 && PPR1 == 1)) {
155			WPR1 = 1	// Issue warm reset
156			Local1 = 1
157		}
158		If (PLS2 == PLSD && (CSC2 == 0 && PPR2 == 1)) {
159			WPR2 = 1	// Issue warm reset
160			Local2 = 1
161		}
162		If (PLS3 == PLSD && (CSC3 == 0 && PPR3 == 1)) {
163			WPR3 = 1	// Issue warm reset
164			Local3 = 1
165		}
166		If (PLS4 == PLSD && (CSC4 == 0 && PPR4 == 1)) {
167			WPR4 = 1	// Issue warm reset
168			Local4 = 1
169		}
170
171		// Poll for warm reset complete on all ports that were reset
172		Local0 = 10
173		While ((Local1 == 1 && WRC1 == 0 || Local2 == 1 && WRC2 == 0) ||
174		       (Local3 == 1 && WRC3 == 0 || Local4 == 1 && WRC4 == 0))
175		{
176			If (Local0 == 0) {
177				Break
178			}
179			Local0--
180			Stall (10)
181		}
182
183		// Clear status bits in all ports
184		LPCL ()
185	}
186
187	Method (_PSC, 0, NotSerialized)
188	{
189		Return (^D0D3)
190	}
191
192	Method (_PS0, 0, Serialized)
193	{
194		If (^DVID == 0xFFFF) {
195			Return ()
196		}
197		If (^XMEM == 0xFFFF || ^XMEM == 0) {
198			Return ()
199		}
200
201		OperationRegion (XREG, SystemMemory, (^XMEM << 16) + 0x8000, 0x200)
202		Field (XREG, DWordAcc, Lock, Preserve)
203		{
204			Offset (0x0e0), // AUX Reset Control 1
205			, 15,
206			AX15, 1,
207			Offset (0x154), // AUX Domain PM Control Register 2
208			, 31,
209			CLK2, 1,
210			Offset (0x16c), // AUX Clock Control
211			, 2,
212			CLK0, 1,
213			, 11,
214			CLK1, 1, // USB3 Port Aux/Core Clock Gating Enable
215		}
216
217		// If device is in D3, set back to D0
218		Local0 = ^D0D3
219		if (Local0 == 3) {
220			^D0D3 = 0
221		}
222
223#if CONFIG(INTEL_LYNXPOINT_LP)
224		If (!\ISWP()) {
225			// Clear PCI 0xB0[14:13]
226			^MB13 = 0
227			^MB14 = 0
228
229			// Clear MMIO 0x816C[14,2]
230			CLK0 = 0
231			CLK1 = 0
232
233			// Set MMIO 0x8154[31]
234			CLK2 = 1
235
236			// Handle per-port reset if needed
237			LPS0 ()
238
239			// Set MMIO 0x80e0[15]
240			AX15 = 1
241
242			// Clear PCI CFG offset 0x40[11]
243			^SWAI = 0
244
245			// Clear PCI CFG offset 0x44[13:12]
246			^SAIP = 0
247		}
248#else
249		// Set MMIO 0x8154[31]
250		CLK2 = 1
251
252		// Clear PCI CFG offset 0x40[11]
253		^SWAI = 0
254
255		// Clear PCI CFG offset 0x44[13:12]
256		^SAIP = 0
257#endif
258
259		// Clear PCI CFG offset 0x40[11]
260		^SWAI = 0
261
262		// Clear PCI CFG offset 0x44[13:12]
263		^SAIP = 0
264
265		Return ()
266	}
267
268	Method (_PS3, 0, Serialized)
269	{
270		If (^DVID == 0xFFFF) {
271			Return ()
272		}
273		If (^XMEM == 0xFFFF || ^XMEM == 0) {
274			Return ()
275		}
276
277		OperationRegion (XREG, SystemMemory, (^XMEM << 16) + 0x8000, 0x200)
278		Field (XREG, DWordAcc, Lock, Preserve)
279		{
280			Offset (0x0e0), // AUX Reset Control 1
281			, 15,
282			AX15, 1,
283			Offset (0x154), // AUX Domain PM Control Register 2
284			, 31,
285			CLK2, 1,
286			Offset (0x16c), // AUX Clock Control
287			, 2,
288			CLK0, 1,
289			, 11,
290			CLK1, 1, // USB3 Port Aux/Core Clock Gating Enable
291		}
292
293		^PMES = 1 // Clear PME Status
294		^PMEE = 1 // Enable PME
295
296		// If device is in D3, set back to D0
297		Local0 = ^D0D3
298		if (Local0 == 3) {
299			^D0D3 = 0
300		}
301
302#if CONFIG(INTEL_LYNXPOINT_LP)
303		If (!\ISWP()) {
304			// Set PCI 0xB0[14:13]
305			^MB13 = 1
306			^MB14 = 1
307
308			// Set MMIO 0x816C[14,2]
309			CLK0 = 1
310			CLK1 = 1
311
312			// Clear MMIO 0x8154[31]
313			CLK2 = 0
314
315			// Clear MMIO 0x80e0[15]
316			AX15 = 0
317
318			// Set PCI CFG offset 0x40[11]
319			^SWAI = 1
320
321			// Set PCI CFG offset 0x44[13:12]
322			^SAIP = 1
323		}
324#else
325		// Clear MMIO 0x8154[31]
326		CLK2 = 0
327
328		// Set PCI CFG offset 0x40[11]
329		^SWAI = 1
330
331		// Set PCI CFG offset 0x44[13:12]
332		^SAIP = 1
333#endif
334
335		// Set PCI CFG offset 0x40[11]
336		^SWAI = 1
337
338		// Set PCI CFG offset 0x44[13:12]
339		^SAIP = 1
340
341		// Put device in D3
342		^D0D3 = 3
343
344		Return ()
345	}
346
347	Name (_PRW, Package () { DEFAULT_PRW_VALUE, 3 })
348
349	// Leave USB ports on for to allow Wake from USB
350
351	Method (_S3D, 0)	// Highest D State in S3 State
352	{
353		Return (3)
354	}
355
356	Method (_S4D, 0)	// Highest D State in S4 State
357	{
358		Return (3)
359	}
360
361	Device (HUB7)
362	{
363		Name (_ADR, 0)
364
365		// GPLD: Generate Port Location Data (PLD)
366		Method (GPLD, 1, Serialized) {
367			Name (PCKG, Package () {
368				Buffer (0x10) {}
369			})
370
371			// REV: Revision 2 for ACPI 5.0
372			CreateField (DerefOf (PCKG [0]), 0, 7, REV)
373			REV = 2
374
375			// VISI: Port visibility to user per port
376			CreateField (DerefOf (PCKG [0]), 0x40, 1, VISI)
377			VISI = Arg0
378			Return (PCKG)
379		}
380
381		Device (PRT1) { Name (_ADR, 1) } // USB Port 0
382		Device (PRT2) { Name (_ADR, 2) } // USB Port 1
383		Device (PRT3) { Name (_ADR, 3) } // USB Port 2
384		Device (PRT4) { Name (_ADR, 4) } // USB Port 3
385		Device (PRT5) { Name (_ADR, 5) } // USB Port 4
386		Device (PRT6) { Name (_ADR, 6) } // USB Port 5
387		Device (PRT7) { Name (_ADR, 7) } // USB Port 6
388		Device (PRT8) { Name (_ADR, 8) } // USB Port 7
389		Device (SSP1) { Name (_ADR, 10) } // USB Port 10
390		Device (SSP2) { Name (_ADR, 11) } // USB Port 11
391		Device (SSP3) { Name (_ADR, 12) } // USB Port 12
392		Device (SSP4) { Name (_ADR, 13) } // USB Port 13
393		Device (SSP5) { Name (_ADR, 14) } // USB Port 14
394		Device (SSP6) { Name (_ADR, 15) } // USB Port 15
395	}
396}
397