• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2
3#include <intelblocks/tcss.h>
4#include <soc/iomap.h>
5
6/*
7 * Type C Subsystem(TCSS) topology provides Runtime D3 support for USB host controller(xHCI),
8 * USB device controller(xDCI), Thunderbolt DMA devices and Thunderbolt PCIe controllers.
9 * PCIe RP0/RP1 is grouped with DMA0 and PCIe RP2/RP3 is grouped with DMA1.
10 */
11#define TCSS_TBT_PCIE0_RP0			0
12#define TCSS_TBT_PCIE0_RP1			1
13#define TCSS_TBT_PCIE0_RP2			2
14#define TCSS_TBT_PCIE0_RP3			3
15#define TCSS_XHCI				4
16#define TCSS_XDCI				5
17#define TCSS_DMA0				6
18#define TCSS_DMA1				7
19
20/*
21 * MAILBOX_BIOS_CMD_TCSS_DEVEN_INTERFACE
22 * Command code 0x15
23 * Description: Gateway command for handling TCSS DEVEN clear/restore.
24 * Field PARAM1[15:8] of the _INTERFACE register is used in this command to select from
25 * a pre-defined set of subcommands.
26 */
27#define MAILBOX_BIOS_CMD_TCSS_DEVEN_INTERFACE		0x00000015
28#define TCSS_DEVEN_MAILBOX_SUBCMD_GET_STATUS		0  /* Sub-command 0 */
29#define TCSS_DEVEN_MAILBOX_SUBCMD_TCSS_CHANGE_REQ	1  /* Sub-command 1 */
30#define TCSS_IOM_ACK_TIMEOUT_IN_MS			100
31
32#define MCHBAR_TCSS_DEVEN_OFFSET			0x7090
33
34#define REVISION_ID					1
35#define UNRECOGNIZED_UUID				0x4
36#define UNRECOGNIZED_REVISION				0x8
37
38#define USB_TUNNELING					0x1
39#define DISPLAY_PORT_TUNNELING				0x2
40#define PCIE_TUNNELING					0x4
41#define INTER_DOMAIN_USB4_INTERNET_PROTOCOL		0x8
42
43Scope (\_SB)
44{
45	/* Device base address */
46	Method (BASE, 1)
47	{
48		Local0 = Arg0 & 0x7             /* Function number */
49		Local1 = (Arg0 >> 16) & 0x1F    /* Device number */
50		Local2 = (Local0 << 12) + (Local1 << 15)
51		Local3 = \_SB.PCI0.GPCB() + Local2
52		Return (Local3)
53	}
54
55	/*
56	 * Define PCH ACPIBASE IO as an ACPI operating region. The base address can be
57	 * found in Device 31, Function 2, Offset 40h.
58	 */
59	OperationRegion (PMIO, SystemIO, ACPI_BASE_ADDRESS, 0x80)
60	Field (PMIO, ByteAcc, NoLock, Preserve) {
61		Offset(0x6C),   /* 0x6C, General Purpose Event 0 Status [127:96] */
62		    ,  19,
63		CPWS,  1,       /* CPU WAKE STATUS */
64		Offset(0x7C),   /* 0x7C, General Purpose Event 0 Enable [127:96] */
65		    ,  19,
66		CPWE,  1        /* CPU WAKE EN */
67	}
68
69	Name (C2PW, 0)  /* Set default value to 0. */
70
71	/*
72	 * C2PM (CPU to PCH Method)
73	 *
74	 * This object is Enable/Disable GPE_CPU_WAKE_EN.
75	 * Arguments: (4)
76	 * Arg0 - An Integer containing the device wake capability
77	 * Arg1 - An Integer containing the target system state
78	 * Arg2 - An Integer containing the target device state
79	 * Arg3 - An Integer containing the request device type
80	 * Return Value:
81	 * return 0
82	 */
83	Method (C2PM, 4, NotSerialized)
84	{
85		Local0 = 1 << Arg3
86		/* This method is used to enable/disable wake from Tcss Device (WKEN). */
87		If (Arg0 && Arg1)
88		{  /* If entering Sx and enabling wake, need to enable WAKE capability. */
89			If (CPWE == 0) {  /* If CPU WAKE EN is not set, Set it. */
90				If (CPWS) {  /* If CPU WAKE STATUS is set, Clear it. */
91					/* Clear CPU WAKE STATUS by writing 1. */
92					CPWS = 1
93				}
94				CPWE = 1  /* Set CPU WAKE EN by writing 1. */
95			}
96			If ((C2PW & Local0) == 0) {
97				/* Set Corresponding Device En BIT in C2PW. */
98				C2PW |= Local0
99			}
100		} Else {  /* If Staying in S0 or Disabling Wake. */
101			If (Arg0 || Arg2) {  /* Check if Exiting D0 and arming for wake. */
102				/* If CPU WAKE EN is not set, Set it. */
103				If (CPWE == 0) {
104					/* If CPU WAKE STATUS is set, Clear it. */
105					If (CPWS) {
106						/* Clear CPU WAKE STATUS by writing 1. */
107						CPWS = 1
108					}
109					CPWE = 1  /* Set CPU WAKE EN by writing 1. */
110				}
111				If ((C2PW & Local0) == 0) {
112					/* Set Corresponding Device En BIT in C2PW. */
113					C2PW |= Local0
114				}
115			} Else {
116				/*
117				 * Disable runtime PME, either because staying in D0 or
118				 * disabling wake.
119				 */
120				If ((C2PW & Local0) != 0) {
121					/*
122					 * Clear Corresponding Device En BIT in C2PW.
123					 */
124					C2PW &= ~Local0
125				}
126				If ((CPWE != 0) && (C2PW == 0)) {
127					/*
128					 * If CPU WAKE EN is set, Clear it. Clear CPU WAKE EN
129					 * by writing 0.
130					 */
131					CPWE = 0
132				}
133			}
134		}
135		Return (0)
136	}
137
138	Method (_OSC, 4, Serialized)
139	{
140		CreateDWordField (Arg3, 0, CDW1)
141		If (Arg0 == ToUUID("0811B06E-4A27-44F9-8D60-3CBBC22E7B48")) {
142			/* Platform-Wide _OSC Capabilities
143			 * Arg0: UUID = {0811B06E-4A27-44F9-8D60-3CBBC22E7B48}
144			 * Arg1: Revision ID = 1
145			 * Arg2: Count of entries (DWORD) in Arge3 (Integer): 3
146			 * Arg3: DWORD capabilities buffer:
147			 * First DWORD: The standard definition bits are used to return errors.
148			 * Second DWORD: See ACPI specification Platform-Wide _OSC Capabilities
149			 * DWORD2 table for Bits 0-17. Bit 18 is newly defined as native USB4
150			 * support. The OS sets this bit to indicate support for an OSPM-native
151			 * USB4 Connection Manager which handles USB4 connection events and
152			 * link management.
153			 */
154			If (Arg1 != REVISION_ID) {
155				CDW1 |= UNRECOGNIZED_REVISION
156			}
157			Return (Arg3)
158#if CONFIG(SOFTWARE_CONNECTION_MANAGER)
159		/*
160		 * Software Connection Manager doesn't work with Linux 5.13 or later and
161		 * results in TBT ports timing out. Not advertising this results in
162		 * Firmware Connection Manager being used and TBT works correctly.
163		 */
164		} ElseIf (Arg0 == ToUUID("23A0D13A-26AB-486C-9C5F-0FFA525A575A")) {
165			/*
166			 * Operating System Capabilities for USB4
167			 * Arg0: UUID = {23A0D13A-26AB-486C-9C5F-0FFA525A575A}
168			 * Arg1: Revision ID = 1
169			 * Arg2: Count of entries (DWORD) in Arg3 (Integer): 3
170			 * Arg3: DWORD capabilities buffer:
171			 * First DWORD: The standard definition bits are used to return errors.
172			 * Second DWORD: OSPM support field for USB4, bits [31:0] reserved.
173			 * Third DWORD: OSPM control field for USB4.
174			 *       bit 0: USB tunneling
175			 *       bit 1: DisplayPort tunneling
176			 *       bit 2: PCIe tunneling
177			 *       bit 3: Inter-domain USB4 internet protocol
178			 *       bit 31:4: reserved
179			 * Return: The platform acknowledges the capabilities buffer by
180			 * returning a buffer of DWORD of the same length. Masked/Cleared bits
181			 * in the control field indicate that the platform does not permit OSPM
182			 * control of the respectively capabilities or features.
183			 */
184			CreateDWordField (Arg3, 8, CDW3)
185			Local0 = CDW3
186
187			If (Arg1 != REVISION_ID) {
188				CDW1 |= UNRECOGNIZED_REVISION
189				Return (Arg3)
190			}
191			Local0 |= USB_TUNNELING | DISPLAY_PORT_TUNNELING | PCIE_TUNNELING |
192				INTER_DOMAIN_USB4_INTERNET_PROTOCOL
193			CDW3 = Local0
194			Return (Arg3)
195#endif
196		} Else {
197			CDW1 |= UNRECOGNIZED_UUID
198			Return (Arg3)
199		}
200	}
201}
202
203Scope (_GPE)
204{
205	/* PCI Express Hot-Plug wake event */
206	Method (_L61, 0, NotSerialized)
207	{
208		/*
209		 * Delay for 100ms to meet the timing requirements of the PCI Express Base
210		 * Specification, Revision 1.0A, Section 6.6 ("...software must wait at least
211		 * 100ms from the end of reset of one or more device before it is permitted
212		 * to issue Configuration Requests to those devices").
213		 */
214		Sleep (100)
215
216		If (CondRefOf (\_SB.PCI0.TXHC)) {
217			/* Invoke PCIe root ports wake event handler */
218			\_SB.PCI0.TRP0.HPEV()
219			\_SB.PCI0.TRP1.HPEV()
220			\_SB.PCI0.TRP2.HPEV()
221			\_SB.PCI0.TRP3.HPEV()
222		}
223
224		/* Check Root Port 0 for a Hot Plug Event if the port is enabled */
225		If (((\_SB.PCI0.TRP0.VDID != 0xFFFFFFFF) && \_SB.PCI0.TRP0.HPSX)) {
226			If (\_SB.PCI0.TRP0.PDCX) {
227				/* Clear all status bits */
228				\_SB.PCI0.TRP0.PDCX = 1
229				\_SB.PCI0.TRP0.HPSX = 1
230				/*
231				 * Intercept Presence Detect Changed interrupt and make sure
232				 * the L0s is disabled on empty slots.
233				 */
234				If (!\_SB.PCI0.TRP0.PDSX) {
235					/*
236					 * The PCIe slot is empty, so disable L0s on hot unplug.
237					 */
238					\_SB.PCI0.TRP0.L0SE = 0
239				}
240				/* Performs proper notification to the OS. */
241				Notify (\_SB.PCI0.TRP0, 0)
242			} Else {
243				/* False event. Clear Hot-Plug status, then exit. */
244				\_SB.PCI0.TRP0.HPSX = 1
245			}
246		}
247
248		/* Check Root Port 1 for a Hot Plug Event if the port is enabled */
249		If (((\_SB.PCI0.TRP1.VDID != 0xFFFFFFFF) && \_SB.PCI0.TRP1.HPSX)) {
250			If (\_SB.PCI0.TRP1.PDCX) {
251				\_SB.PCI0.TRP1.PDCX = 1
252				\_SB.PCI0.TRP1.HPSX = 1
253				If (!\_SB.PCI0.TRP1.PDSX) {
254					\_SB.PCI0.TRP1.L0SE = 0
255				}
256				Notify (\_SB.PCI0.TRP1, 0)
257			} Else {
258				\_SB.PCI0.TRP1.HPSX = 1
259			}
260		}
261
262		/* Check Root Port 2 for a Hot Plug Event if the port is enabled */
263		If (((\_SB.PCI0.TRP2.VDID != 0xFFFFFFFF) && \_SB.PCI0.TRP2.HPSX)) {
264			If (\_SB.PCI0.TRP2.PDCX) {
265				\_SB.PCI0.TRP2.PDCX = 1
266				\_SB.PCI0.TRP2.HPSX = 1
267				If (!\_SB.PCI0.TRP2.PDSX) {
268					\_SB.PCI0.TRP2.L0SE = 0
269				}
270				Notify (\_SB.PCI0.TRP2, 0)
271			} Else {
272				\_SB.PCI0.TRP2.HPSX = 1
273			}
274		}
275
276		/* Check Root Port 3 for a Hot Plug Event if the port is enabled */
277		If (((\_SB.PCI0.TRP3.VDID != 0xFFFFFFFF) && \_SB.PCI0.TRP3.HPSX)) {
278			If (\_SB.PCI0.TRP3.PDCX) {
279				\_SB.PCI0.TRP3.PDCX = 1
280				\_SB.PCI0.TRP3.HPSX = 1
281				If (!\_SB.PCI0.TRP3.PDSX) {
282					\_SB.PCI0.TRP3.L0SE = 0
283				}
284				Notify (\_SB.PCI0.TRP3, 0)
285			} Else {
286				\_SB.PCI0.TRP3.HPSX = 1
287			}
288		}
289	}
290
291	/* PCI Express power management event */
292	Method (_L69, 0, Serialized)
293	{
294		If (CondRefOf (\_SB.PCI0.TXHC)) {
295			If (\_SB.PCI0.TRP0.HPME() == 1) {
296				Notify (\_SB.PCI0.TDM0, 0x2)
297				Notify (\_SB.PCI0.TRP0, 0x2)
298			}
299
300			If (\_SB.PCI0.TRP1.HPME() == 1) {
301				Notify (\_SB.PCI0.TDM0, 0x2)
302				Notify (\_SB.PCI0.TRP1, 0x2)
303			}
304
305			If (\_SB.PCI0.TRP2.HPME() == 1) {
306				Notify (\_SB.PCI0.TDM1, 0x2)
307				Notify (\_SB.PCI0.TRP2, 0x2)
308			}
309
310			If (\_SB.PCI0.TRP3.HPME() == 1) {
311				Notify (\_SB.PCI0.TDM1, 0x2)
312				Notify (\_SB.PCI0.TRP3, 0x2)
313			}
314		}
315
316		/* Invoke PCIe root ports power management status handler */
317		\_SB.PCI0.TRP0.HPME()
318		\_SB.PCI0.TRP1.HPME()
319		\_SB.PCI0.TRP2.HPME()
320		\_SB.PCI0.TRP3.HPME()
321	}
322}
323
324Scope (\_SB.PCI0)
325{
326	Device (IOM)
327	{
328		Name (_HID, "INTC1079")
329		Name (_DDN, "Intel(R) Alder Lake Input Output Manager(IOM) driver")
330		/* IOM preserved MMIO range from 0xFBC10000 to 0xFBC11600. */
331		Name (_CRS, ResourceTemplate () {
332			Memory32Fixed (ReadWrite, IOM_BASE_ADDRESS, IOM_BASE_SIZE)
333		})
334		Name (_STA, 0xF)
335	}
336
337	/*
338	 * Operation region defined to access the TCSS_DEVEN. Get the MCHBAR in offset
339	 * 0x48 in B0:D0:F0. TCSS device enable base address is in offset 0x7090 of MCHBAR.
340	 */
341	OperationRegion (TDEN, SystemMemory, (GMHB() + MCHBAR_TCSS_DEVEN_OFFSET), 0x4)
342	Field (TDEN, ByteAcc, NoLock, Preserve)
343	{
344		TRE0, 1,  /* PCIE0_EN */
345		TRE1, 1,  /* PCIE1_EN */
346		TRE2, 1,  /* PCIE2_EN */
347		TRE3, 1,  /* PCIE3_EN */
348		,     4,
349		THCE, 1,  /* XHCI_EN */
350		TDCE, 1,  /* XDCI_EN */
351		DME0, 1,  /* TBT_DMA0_EN */
352		DME1, 1,  /* TBT_DMA1_EN */
353		,     20
354	}
355
356	/*
357	 * Operation region defined to access the IOM REGBAR. Get the MCHBAR in offset
358	 * 0x48 in B0:D0:F0. REGBAR Base address is in offset 0x7110 of MCHBAR.
359	 */
360	OperationRegion (MBAR, SystemMemory, (GMHB() + 0x7100), 0x1000)
361	Field (MBAR, ByteAcc, NoLock, Preserve)
362	{
363		Offset(0x10),
364		RBAR, 64        /* RegBar, offset 0x7110 in MCHBAR */
365	}
366
367	/*
368	 * Operation region defined to access the pCode mailbox interface. Get the MCHBAR
369	 * in offset 0x48 in B0:D0:F0. MMIO address is in offset 0x5DA0 of MCHBAR.
370	 */
371	OperationRegion (PBAR, SystemMemory, (GMHB() + 0x5DA0), 0x08)
372	Field (PBAR, DWordAcc, NoLock, Preserve)
373	{
374		PMBD, 32,  /* pCode MailBox Data, offset 0x5DA0 in MCHBAR */
375		PMBC, 8,   /* pCode MailBox Command, [7:0] of offset 0x5DA4 in MCHBAR */
376		PSCM, 8,   /* pCode MailBox Sub-Command, [15:8] of offset 0x5DA4 in MCHBAR */
377		,     15,  /* Reserved */
378		PMBR, 1    /* pCode MailBox RunBit, [31:31] of offset 0x5DA4 in MCHBAR */
379	}
380
381	/*
382	 * Poll pCode MailBox Ready
383	 *
384	 * Return 0xFF - Timeout
385	 *	  0x00 - Ready
386	 */
387	Method (PMBY, 0)
388	{
389		Local0 = 0
390		While (PMBR && (Local0 < 1000)) {
391			Local0++
392			Stall (1)
393		}
394		If (Local0 == 1000) {
395			Printf("Timeout occurred.")
396			Return (0xFF)
397		}
398		Return (0)
399	}
400
401	/*
402	 * IOM REG BAR Base address is in offset 0x7110 in MCHBAR.
403	 */
404	Method (IOMA, 0)
405	{
406		Return (^RBAR & ~0x1)
407	}
408
409	/*
410	 * From RegBar Base, IOM_TypeC_SW_configuration_1 is in offset 0xC10040, where
411	 * 0x40 is the register offset.
412	 */
413	OperationRegion (IOMR, SystemMemory, (IOMA() + 0xC10000), 0x100)
414	Field (IOMR, DWordAcc, NoLock, Preserve)
415	{
416		Offset(0x40),
417		,     15,
418		TD3C, 1,          /* [15:15] Type C D3 cold bit */
419		TACK, 1,          /* [16:16] IOM Acknowledge bit */
420		DPOF, 1,          /* [17:17] Set 1 to indicate IOM, all the */
421				  /* display is OFF, clear otherwise */
422		Offset(0x70),     /* Physical addr is offset 0x70. */
423		IMCD, 32,         /* R_SA_IOM_BIOS_MAIL_BOX_CMD */
424		IMDA, 32          /* R_SA_IOM_BIOS_MAIL_BOX_DATA */
425	}
426
427	/*
428	 * TBT Group0 ON method
429	 */
430	Method (TG0N, 0)
431	{
432		If (\_SB.PCI0.TDM0.VDID == 0xFFFFFFFF) {
433			Printf("TDM0 does not exist.")
434		} Else {
435			If (\_SB.PCI0.TDM0.STAT == 0) {
436				/* DMA0 is in D3Cold early. */
437				\_SB.PCI0.TDM0.D3CX()  /* RTD3 Exit */
438
439				Printf("Bring TBT RPs out of D3Code.")
440				If (\_SB.PCI0.TRP0.VDID != 0xFFFFFFFF) {
441					/* RP0 D3 cold exit. */
442					\_SB.PCI0.TRP0.D3CX()
443				}
444				If (\_SB.PCI0.TRP1.VDID != 0xFFFFFFFF) {
445					/* RP1 D3 cold exit. */
446					\_SB.PCI0.TRP1.D3CX()
447				}
448			} Else {
449				Printf("Drop TG0N due to it is already exit D3 cold.")
450			}
451
452			/* TBT RTD3 exit 10ms delay. */
453			Sleep (10)
454		}
455	}
456
457	/*
458	 * TBT Group0 OFF method
459	 */
460	Method (TG0F, 0)
461	{
462		If (\_SB.PCI0.TDM0.VDID == 0xFFFFFFFF) {
463			Printf("TDM0 does not exist.")
464		} Else {
465			If (\_SB.PCI0.TDM0.STAT == 1) {
466				/* DMA0 is not in D3Cold now. */
467				\_SB.PCI0.TDM0.D3CE()  /* Enable DMA RTD3 */
468
469				If (\_SB.PCI0.TDM0.IF30 != 1) {
470					Return
471				}
472
473				Printf("Push TBT RPs to D3Cold together")
474				If (\_SB.PCI0.TRP0.VDID != 0xFFFFFFFF) {
475					/* Put RP0 to D3 cold. */
476					\_SB.PCI0.TRP0.D3CE()
477				}
478				If (\_SB.PCI0.TRP1.VDID != 0xFFFFFFFF) {
479					/* Put RP1 to D3 cold. */
480					\_SB.PCI0.TRP1.D3CE()
481				}
482			}
483		}
484	}
485
486	/*
487	 * TBT Group1 ON method
488	 */
489	Method (TG1N, 0)
490	{
491		If (\_SB.PCI0.TDM1.VDID == 0xFFFFFFFF) {
492			Printf("TDM1 does not exist.")
493		} Else {
494			If (\_SB.PCI0.TDM1.STAT == 0) {
495				/* DMA1 is in D3Cold early. */
496				\_SB.PCI0.TDM1.D3CX()  /* RTD3 Exit */
497
498				Printf("Bring TBT RPs out of D3Code.")
499				If (\_SB.PCI0.TRP2.VDID != 0xFFFFFFFF) {
500					/* RP2 D3 cold exit. */
501					\_SB.PCI0.TRP2.D3CX()
502				}
503				If (\_SB.PCI0.TRP3.VDID != 0xFFFFFFFF) {
504					/* RP3 D3 cold exit. */
505					\_SB.PCI0.TRP3.D3CX()
506				}
507			} Else {
508				Printf("Drop TG1N due to it is already exit D3 cold.")
509			}
510
511			/* TBT RTD3 exit 10ms delay. */
512			Sleep (10)
513		}
514	}
515
516	/*
517	 * TBT Group1 OFF method
518	 */
519	Method (TG1F, 0)
520	{
521		If (\_SB.PCI0.TDM1.VDID == 0xFFFFFFFF) {
522			 Printf("TDM1 does not exist.")
523		} Else {
524			If (\_SB.PCI0.TDM1.STAT == 1) {
525				/* DMA1 is not in D3Cold now */
526				\_SB.PCI0.TDM1.D3CE()  /* Enable DMA RTD3. */
527
528				If (\_SB.PCI0.TDM1.IF30 != 1) {
529					Return
530				}
531
532				Printf("Push TBT RPs to D3Cold together")
533				If (\_SB.PCI0.TRP2.VDID != 0xFFFFFFFF) {
534					/* Put RP2 to D3 cold. */
535					\_SB.PCI0.TRP2.D3CE()
536				}
537				If (\_SB.PCI0.TRP3.VDID != 0xFFFFFFFF) {
538					/* Put RP3 to D3 cold */
539					\_SB.PCI0.TRP3.D3CE()
540				}
541			}
542		}
543	}
544
545	PowerResource (TBT0, 5, 1)
546	{
547		Method (_STA, 0)
548		{
549			Return (\_SB.PCI0.TDM0.STAT)
550		}
551
552		Method (_ON, 0)
553		{
554			TG0N()
555		}
556
557		Method (_OFF, 0)
558		{
559			If (\_SB.PCI0.TDM0.SD3C == 0) {
560				TG0F()
561			}
562		}
563	}
564
565	PowerResource (TBT1, 5, 1)
566	{
567		Method (_STA, 0)
568		{
569			Return (\_SB.PCI0.TDM1.STAT)
570		}
571
572		Method (_ON, 0)
573		{
574			TG1N()
575		}
576
577		Method (_OFF, 0)
578		{
579			If (\_SB.PCI0.TDM1.SD3C == 0) {
580				TG1F()
581			}
582		}
583	}
584
585#if CONFIG(D3COLD_SUPPORT)
586	Method (TCON, 0)
587	{
588		/* Reset IOM D3 cold bit if it is in D3 cold now. */
589		If (TD3C == 1)  /* It was in D3 cold before. */
590		{
591			/* Reset IOM D3 cold bit. */
592			TD3C = 0    /* Request IOM for D3 cold exit sequence. */
593			Local0 = 0  /* Time check counter variable */
594			/* Wait for ack, the maximum wait time for the ack is 100 msec. */
595			While ((TACK != 0) && (Local0 < TCSS_IOM_ACK_TIMEOUT_IN_MS)) {
596				/*
597				 * Wait in this loop until TACK becomes 0 with timeout
598				 * TCSS_IOM_ACK_TIMEOUT_IN_MS by default.
599				 */
600				Sleep (1)  /* Delay of 1ms. */
601				Local0++
602			}
603
604			If (Local0 == TCSS_IOM_ACK_TIMEOUT_IN_MS) {
605				Printf("Error: Timeout occurred.")
606			}
607			Else
608			{
609				Printf("TCSS D3 exit.");
610			}
611		}
612		Else {
613			Printf("Drop TCON due to it is already exit D3 cold.")
614		}
615	}
616
617	Method (TCOF, 0)
618	{
619		If ((\_SB.PCI0.TXHC.SD3C != 0) || (\_SB.PCI0.TDM0.SD3C != 0)
620					       || (\_SB.PCI0.TDM1.SD3C != 0))
621		{
622			Printf("Skip D3C entry.")
623			Return
624		}
625
626		/* Request IOM for D3 cold entry sequence. */
627		TD3C = 1
628	}
629
630	PowerResource (D3C, 5, 0)
631	{
632		/*
633		 * Variable to save power state
634		 * 1 - TC Cold request cleared.
635		 * 0 - TC Cold request sent.
636		 */
637		Name (STAT, 0x1)
638
639		Method (_STA, 0)
640		{
641			Return (STAT)
642		}
643
644		Method (_ON, 0)
645		{
646			\_SB.PCI0.TCON()
647			STAT = 1
648		}
649
650		Method (_OFF, 0)
651		{
652			\_SB.PCI0.TCOF()
653			STAT = 0
654		}
655	}
656#endif	// D3COLD_SUPPORT
657
658	/*
659	 * TCSS xHCI device
660	 */
661	Device (TXHC)
662	{
663		Name (_ADR, 0x000D0000)
664		Name (_DDN, "North XHCI controller")
665		Name (_STR, Unicode ("North XHCI controller"))
666		Name (DCPM, TCSS_XHCI)
667
668		Method (_STA, 0x0, NotSerialized)
669		{
670			If (THCE == 1) {
671				Return (0x0F)
672			} Else {
673				Return (0x0)
674			}
675		}
676		#include "tcss_xhci.asl"
677	}
678
679	/*
680	 * TCSS DMA0 device
681	 */
682	Device (TDM0)
683	{
684		Name (_ADR, 0x000D0002)
685		Name (_DDN, "TBT DMA0 controller")
686		Name (_STR, Unicode ("TBT DMA0 controller"))
687		Name (DUID, 0)  /* TBT DMA number */
688		Name (DCPM, TCSS_DMA0)
689
690		Method (_STA, 0x0, NotSerialized)
691		{
692			If (DME0 == 1) {
693				Return (0x0F)
694			} Else {
695				Return (0x0)
696			}
697		}
698		#include "tcss_dma.asl"
699	}
700
701	/*
702	 * TCSS DMA1 device
703	 */
704	Device (TDM1)
705	{
706		Name (_ADR, 0x000D0003)
707		Name (_DDN, "TBT DMA1 controller")
708		Name (_STR, Unicode ("TBT DMA1 controller"))
709		Name (DUID, 1)  /* TBT DMA number */
710		Name (DCPM, TCSS_DMA1)
711
712		Method (_STA, 0x0, NotSerialized)
713		{
714			If (DME1 == 1) {
715				Return (0x0F)
716			} Else {
717				Return (0x0)
718			}
719		}
720		#include "tcss_dma.asl"
721	}
722
723	/*
724	 * TCSS PCIE Root Port #00
725	 */
726	Device (TRP0)
727	{
728		Name (_ADR, 0x00070000)
729		Name (TUID, 0)  /* TBT PCIE RP Number 0 for RP00 */
730		Name (LTEN, 0)  /* Latency Tolerance Reporting Mechanism, 0:Disable, 1:Enable */
731		Name (LMSL, 0)  /* PCIE LTR max snoop Latency */
732		Name (LNSL, 0)  /* PCIE LTR max no snoop Latency */
733		Name (DCPM, TCSS_TBT_PCIE0_RP0)
734
735		Method (_STA, 0x0, NotSerialized)
736		{
737			If (TRE0 == 1) {
738				Return (0x0F)
739			} Else {
740				Return (0x0)
741			}
742		}
743
744		Method (_INI)
745		{
746			LTEN = 0
747			LMSL = 0x88C8
748			LNSL = 0x88C8
749		}
750		#include "tcss_pcierp.asl"
751	}
752
753	/*
754	 * TCSS PCIE Root Port #01
755	 */
756	Device (TRP1)
757	{
758		Name (_ADR, 0x00070001)
759		Name (TUID, 1)  /* TBT PCIE RP Number 1 for RP01 */
760		Name (LTEN, 0)  /* Latency Tolerance Reporting Mechanism, 0:Disable, 1:Enable */
761		Name (LMSL, 0)  /* PCIE LTR max snoop Latency */
762		Name (LNSL, 0)  /* PCIE LTR max no snoop Latency */
763		Name (DCPM, TCSS_TBT_PCIE0_RP1)
764
765		Method (_STA, 0x0, NotSerialized)
766		{
767			If (TRE1 == 1) {
768				Return (0x0F)
769			} Else {
770				Return (0x0)
771			}
772		}
773
774		Method (_INI)
775		{
776			LTEN = 0
777			LMSL = 0x88C8
778			LNSL = 0x88C8
779		}
780		#include "tcss_pcierp.asl"
781	}
782
783	/*
784	 * TCSS PCIE Root Port #02
785	 */
786	Device (TRP2)
787	{
788		Name (_ADR, 0x00070002)
789		Name (TUID, 2)  /* TBT PCIE RP Number 2 for RP02 */
790		Name (LTEN, 0)  /* Latency Tolerance Reporting Mechanism, 0:Disable, 1:Enable */
791		Name (LMSL, 0)  /* PCIE LTR max snoop Latency */
792		Name (LNSL, 0)  /* PCIE LTR max no snoop Latency */
793		Name (DCPM, TCSS_TBT_PCIE0_RP2)
794
795		Method (_STA, 0x0, NotSerialized)
796		{
797			If (TRE2 == 1) {
798				Return (0x0F)
799			} Else {
800				Return (0x0)
801			}
802		}
803
804		Method (_INI)
805		{
806			LTEN = 0
807			LMSL = 0x88C8
808			LNSL = 0x88C8
809		}
810		#include "tcss_pcierp.asl"
811	}
812
813	/*
814	 * TCSS PCIE Root Port #03
815	 */
816	Device (TRP3)
817	{
818		Name (_ADR, 0x00070003)
819		Name (TUID, 3)  /* TBT PCIE RP Number 3 for RP03 */
820		Name (LTEN, 0)  /* Latency Tolerance Reporting Mechanism, 0:Disable, 1:Enable */
821		Name (LMSL, 0)  /* PCIE LTR max snoop Latency */
822		Name (LNSL, 0)  /* PCIE LTR max no snoop Latency */
823		Name (DCPM, TCSS_TBT_PCIE0_RP3)
824
825		Method (_STA, 0x0, NotSerialized)
826		{
827			If (TRE3 == 1) {
828				Return (0x0F)
829			} Else {
830				Return (0x0)
831			}
832		}
833
834		Method (_INI)
835		{
836			LTEN = 0
837			LMSL = 0x88C8
838			LNSL = 0x88C8
839		}
840		#include "tcss_pcierp.asl"
841	}
842}
843