blob: 817afdded4922721e16ca468c36fa39327225734 [file] [log] [blame]
Ravi Sarawadie02fd832022-05-08 00:27:31 -07001/* SPDX-License-Identifier: GPL-2.0-or-later */
2
3#include <soc/iomap.h>
4#include <soc/tcss.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 } ElseIf (Arg0 == ToUUID("23A0D13A-26AB-486C-9C5F-0FFA525A575A")) {
159 /*
160 * Operating System Capabilities for USB4
161 * Arg0: UUID = {23A0D13A-26AB-486C-9C5F-0FFA525A575A}
162 * Arg1: Revision ID = 1
163 * Arg2: Count of entries (DWORD) in Arg3 (Integer): 3
164 * Arg3: DWORD capabilities buffer:
165 * First DWORD: The standard definition bits are used to return errors.
166 * Second DWORD: OSPM support field for USB4, bits [31:0] reserved.
167 * Third DWORD: OSPM control field for USB4.
168 * bit 0: USB tunneling
169 * bit 1: DisplayPort tunneling
170 * bit 2: PCIe tunneling
171 * bit 3: Inter-domain USB4 internet protocol
172 * bit 31:4: reserved
173 * Return: The platform acknowledges the capabilities buffer by
174 * returning a buffer of DWORD of the same length. Masked/Cleared bits
175 * in the control field indicate that the platform does not permit OSPM
176 * control of the respectively capabilities or features.
177 */
178 CreateDWordField (Arg3, 8, CDW3)
179 Local0 = CDW3
180
181 If (Arg1 != REVISION_ID) {
182 CDW1 |= UNRECOGNIZED_REVISION
183 Return (Arg3)
184 }
185 Local0 |= USB_TUNNELING | DISPLAY_PORT_TUNNELING | PCIE_TUNNELING |
186 INTER_DOMAIN_USB4_INTERNET_PROTOCOL
187 CDW3 = Local0
188 Return (Arg3)
189 } Else {
190 CDW1 |= UNRECOGNIZED_UUID
191 Return (Arg3)
192 }
193 }
194}
195
196Scope (_GPE)
197{
198 /* PCI Express Hot-Plug wake event */
199 Method (_L61, 0, NotSerialized)
200 {
201 /*
202 * Delay for 100ms to meet the timing requirements of the PCI Express Base
203 * Specification, Revision 1.0A, Section 6.6 ("...software must wait at least
204 * 100ms from the end of reset of one or more device before it is permitted
205 * to issue Configuration Requests to those devices").
206 */
207 Sleep (100)
208
209 If (CondRefOf (\_SB.PCI0.TXHC)) {
210 /* Invoke PCIe root ports wake event handler */
211 \_SB.PCI0.TRP0.HPEV()
212 \_SB.PCI0.TRP1.HPEV()
213 \_SB.PCI0.TRP2.HPEV()
214 \_SB.PCI0.TRP3.HPEV()
215 }
216
217 /* Check Root Port 0 for a Hot Plug Event if the port is enabled */
218 If (((\_SB.PCI0.TRP0.VDID != 0xFFFFFFFF) && \_SB.PCI0.TRP0.HPSX)) {
219 If (\_SB.PCI0.TRP0.PDCX) {
220 /* Clear all status bits */
221 \_SB.PCI0.TRP0.PDCX = 1
222 \_SB.PCI0.TRP0.HPSX = 1
223 /*
224 * Intercept Presence Detect Changed interrupt and make sure
225 * the L0s is disabled on empty slots.
226 */
227 If (!\_SB.PCI0.TRP0.PDSX) {
228 /*
229 * The PCIe slot is empty, so disable L0s on hot unplug.
230 */
231 \_SB.PCI0.TRP0.L0SE = 0
232 }
233 /* Performs proper notification to the OS. */
234 Notify (\_SB.PCI0.TRP0, 0)
235 } Else {
236 /* False event. Clear Hot-Plug status, then exit. */
237 \_SB.PCI0.TRP0.HPSX = 1
238 }
239 }
240
241 /* Check Root Port 1 for a Hot Plug Event if the port is enabled */
242 If (((\_SB.PCI0.TRP1.VDID != 0xFFFFFFFF) && \_SB.PCI0.TRP1.HPSX)) {
243 If (\_SB.PCI0.TRP1.PDCX) {
244 \_SB.PCI0.TRP1.PDCX = 1
245 \_SB.PCI0.TRP1.HPSX = 1
246 If (!\_SB.PCI0.TRP1.PDSX) {
247 \_SB.PCI0.TRP1.L0SE = 0
248 }
249 Notify (\_SB.PCI0.TRP1, 0)
250 } Else {
251 \_SB.PCI0.TRP1.HPSX = 1
252 }
253 }
254
255 /* Check Root Port 2 for a Hot Plug Event if the port is enabled */
256 If (((\_SB.PCI0.TRP2.VDID != 0xFFFFFFFF) && \_SB.PCI0.TRP2.HPSX)) {
257 If (\_SB.PCI0.TRP2.PDCX) {
258 \_SB.PCI0.TRP2.PDCX = 1
259 \_SB.PCI0.TRP2.HPSX = 1
260 If (!\_SB.PCI0.TRP2.PDSX) {
261 \_SB.PCI0.TRP2.L0SE = 0
262 }
263 Notify (\_SB.PCI0.TRP2, 0)
264 } Else {
265 \_SB.PCI0.TRP2.HPSX = 1
266 }
267 }
268
269 /* Check Root Port 3 for a Hot Plug Event if the port is enabled */
270 If (((\_SB.PCI0.TRP3.VDID != 0xFFFFFFFF) && \_SB.PCI0.TRP3.HPSX)) {
271 If (\_SB.PCI0.TRP3.PDCX) {
272 \_SB.PCI0.TRP3.PDCX = 1
273 \_SB.PCI0.TRP3.HPSX = 1
274 If (!\_SB.PCI0.TRP3.PDSX) {
275 \_SB.PCI0.TRP3.L0SE = 0
276 }
277 Notify (\_SB.PCI0.TRP3, 0)
278 } Else {
279 \_SB.PCI0.TRP3.HPSX = 1
280 }
281 }
282 }
283
284 /* PCI Express power management event */
285 Method (_L69, 0, Serialized)
286 {
287 If (CondRefOf (\_SB.PCI0.TXHC)) {
288 If (\_SB.PCI0.TRP0.HPME() == 1) {
289 Notify (\_SB.PCI0.TDM0, 0x2)
290 Notify (\_SB.PCI0.TRP0, 0x2)
291 }
292
293 If (\_SB.PCI0.TRP1.HPME() == 1) {
294 Notify (\_SB.PCI0.TDM0, 0x2)
295 Notify (\_SB.PCI0.TRP1, 0x2)
296 }
297
298 If (\_SB.PCI0.TRP2.HPME() == 1) {
299 Notify (\_SB.PCI0.TDM1, 0x2)
300 Notify (\_SB.PCI0.TRP2, 0x2)
301 }
302
303 If (\_SB.PCI0.TRP3.HPME() == 1) {
304 Notify (\_SB.PCI0.TDM1, 0x2)
305 Notify (\_SB.PCI0.TRP3, 0x2)
306 }
307 }
308
309 /* Invoke PCIe root ports power management status handler */
310 \_SB.PCI0.TRP0.HPME()
311 \_SB.PCI0.TRP1.HPME()
312 \_SB.PCI0.TRP2.HPME()
313 \_SB.PCI0.TRP3.HPME()
314 }
315}
316
317Scope (\_SB.PCI0)
318{
319 Device (IOM)
320 {
321 Name (_HID, "INTC107A")
322 Name (_DDN, "Intel(R) Meteor Lake Input Output Manager(IOM) driver")
323 /* IOM preserved MMIO range from 0x3fff0aa0000 to 0x3fff0aa15ff. */
324 Name (_CRS, ResourceTemplate () {
325 QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed,
326 NonCacheable, ReadWrite, 0x0,
327 IOM_BASE_ADDR, IOM_BASE_ADDR_MAX, 0x0,
328 IOM_BASE_SIZE,,,)
329 })
Kapil Porwalc89de222022-11-14 18:39:21 +0530330 /* Hide the device so that Windows does not complain on missing driver */
331 Name (_STA, 0xB)
Ravi Sarawadie02fd832022-05-08 00:27:31 -0700332 }
333
334 /*
335 * Operation region defined to access the TCSS_DEVEN. Get the MCHBAR in offset
336 * 0x48 in B0:D0:F0. TCSS device enable base address is in offset 0x7090 of MCHBAR.
337 */
338 OperationRegion (TDEN, SystemMemory, (GMHB() + MCHBAR_TCSS_DEVEN_OFFSET), 0x4)
339 Field (TDEN, ByteAcc, NoLock, Preserve)
340 {
341 TRE0, 1, /* PCIE0_EN */
342 TRE1, 1, /* PCIE1_EN */
343 TRE2, 1, /* PCIE2_EN */
344 TRE3, 1, /* PCIE3_EN */
345 , 4,
346 THCE, 1, /* XHCI_EN */
347 TDCE, 1, /* XDCI_EN */
348 DME0, 1, /* TBT_DMA0_EN */
349 DME1, 1, /* TBT_DMA1_EN */
350 , 20
351 }
352
353 /*
354 * Operation region defined to access the pCode mailbox interface. Get the MCHBAR
355 * in offset 0x48 in B0:D0:F0. MMIO address is in offset 0x5DA0 of MCHBAR.
356 */
357 OperationRegion (PBAR, SystemMemory, (GMHB() + 0x5DA0), 0x08)
358 Field (PBAR, DWordAcc, NoLock, Preserve)
359 {
360 PMBD, 32, /* pCode MailBox Data, offset 0x5DA0 in MCHBAR */
361 PMBC, 8, /* pCode MailBox Command, [7:0] of offset 0x5DA4 in MCHBAR */
362 PSCM, 8, /* pCode MailBox Sub-Command, [15:8] of offset 0x5DA4 in MCHBAR */
363 , 15, /* Reserved */
364 PMBR, 1 /* pCode MailBox RunBit, [31:31] of offset 0x5DA4 in MCHBAR */
365 }
366
367 /*
368 * Poll pCode MailBox Ready
369 *
370 * Return 0xFF - Timeout
371 * 0x00 - Ready
372 */
373 Method (PMBY, 0)
374 {
375 Local0 = 0
376 While (PMBR && (Local0 < 1000)) {
377 Local0++
378 Stall (1)
379 }
380 If (Local0 == 1000) {
381 Printf("Timeout occurred.")
382 Return (0xFF)
383 }
384 Return (0)
385 }
386
387 /*
388 * Method to send pCode MailBox command TCSS_DEVEN_MAILBOX_SUBCMD_GET_STATUS
389 *
390 * Result will be updated in DATA[1:0]
391 * DATA[0:0] TCSS_DEVEN_CURRENT_STATE:
392 * 0 - TCSS Deven in normal state.
393 * 1 - TCSS Deven is cleared by BIOS Mailbox request.
394 * DATA[1:1] TCSS_DEVEN_REQUEST_STATUS:
395 * 0 - IDLE. TCSS DEVEN has reached its final requested state.
396 * 1 - In Progress. TCSS DEVEN is currently in progress of switching state
397 * according to given request (bit 0 reflects source state).
398 *
399 * Return 0x00 - TCSS Deven in normal state
400 * 0x01 - TCSS Deven is cleared by BIOS Mailbox request
401 * 0x1x - TCSS Deven is in progress of switching state according to given request
402 * 0xFE - Command timeout
403 * 0xFF - Command corrupt
404 */
405 Method (DSGS, 0)
406 {
407 If ((PMBY () == 0)) {
408 PMBC = MAILBOX_BIOS_CMD_TCSS_DEVEN_INTERFACE
409 PSCM = TCSS_DEVEN_MAILBOX_SUBCMD_GET_STATUS
410 PMBR = 1
411 If (PMBY () == 0) {
412 Local0 = PMBD
413 Local1 = PMBC
414 Stall (10)
415 If ((Local0 != PMBD) || (Local1 != PMBC)) {
416 Printf("pCode MailBox is corrupt.")
417 Return (0xFF)
418 }
419 Return (Local0)
420 } Else {
421 Printf("pCode MailBox is not ready.")
422 Return (0xFE)
423 }
424 } Else {
425 Printf("pCode MailBox is not ready.")
426 Return (0xFE)
427 }
428 }
429
430 /*
431 * Method to send pCode MailBox command TCSS_DEVEN_MAILBOX_SUBCMD_TCSS_CHANGE_REQ
432 *
433 * Arg0 : 0 - Restore to previously saved value of TCSS DEVEN
434 * 1 - Save current TCSS DEVEN value and clear it
435 *
436 * Return 0x00 - MAILBOX_BIOS_CMD_CLEAR_TCSS_DEVEN command completed
437 * 0xFD - Input argument is invalid
438 * 0xFE - Command timeout
439 * 0xFF - Command corrupt
440 */
441 Method (DSCR, 1)
442 {
443 If (Arg0 > 1) {
444 Printf("pCode MailBox is corrupt.")
445 Return (0xFD)
446 }
447 If ((PMBY () == 0)) {
448 PMBC = MAILBOX_BIOS_CMD_TCSS_DEVEN_INTERFACE
449 PSCM = TCSS_DEVEN_MAILBOX_SUBCMD_TCSS_CHANGE_REQ
450 PMBD = Arg0
451 PMBR = 1
452 If ((PMBY () == 0)) {
453 Local0 = PMBD
454 Local1 = PMBC
455 Stall (10)
456 If ((Local0 != PMBD) || (Local1 != PMBC)) {
457 Printf("pCode MailBox is corrupt.")
458 Return (0xFF)
459 }
460 /* Poll TCSS_DEVEN_REQUEST_STATUS, timeout value is 10ms. */
461 Local0 = 0
462 While ((DSGS () & 0x10) && (Local0 < 100)) {
463 Stall (100)
464 Local0++
465 }
466 If (Local0 == 100) {
467 Printf("pCode MailBox is not ready.")
468 Return (0xFE)
469 } Else {
470 Return (0x00)
471 }
472 } Else {
473 Printf("pCode MailBox is not ready.")
474 Return (0xFE)
475 }
476 } Else {
477 Printf("pCode MailBox is not ready.")
478 Return (0xFE)
479 }
480 }
481
482 /* From RegBar Base, IOM_TypeC_SW_configuration_1 is at offset 0x40 */
483 OperationRegion (IOMR, SystemMemory, IOM_BASE_ADDR, 0x100)
484 Field (IOMR, DWordAcc, NoLock, Preserve)
485 {
486 Offset(0x40),
487 , 15,
488 TD3C, 1, /* [15:15] Type C D3 cold bit */
489 TACK, 1, /* [16:16] IOM Acknowledge bit */
490 DPOF, 1, /* [17:17] Set 1 to indicate IOM, all the */
491 /* display is OFF, clear otherwise */
492 Offset(0x70), /* Pyhsical addr is offset 0x70. */
493 IMCD, 32, /* R_SA_IOM_BIOS_MAIL_BOX_CMD */
494 IMDA, 32 /* R_SA_IOM_BIOS_MAIL_BOX_DATA */
495 }
496
497 /*
498 * TBT Group0 ON method
499 */
500 Method (TG0N, 0)
501 {
502 If (\_SB.PCI0.TDM0.VDID == 0xFFFFFFFF) {
503 Printf("TDM0 does not exist.")
504 } Else {
505 If (\_SB.PCI0.TDM0.STAT == 0) {
506 /* DMA0 is in D3Cold early. */
507 \_SB.PCI0.TDM0.D3CX() /* RTD3 Exit */
508
509 Printf("Bring TBT RPs out of D3Code.")
510 If (\_SB.PCI0.TRP0.VDID != 0xFFFFFFFF) {
511 /* RP0 D3 cold exit. */
512 \_SB.PCI0.TRP0.D3CX()
513 }
514 If (\_SB.PCI0.TRP1.VDID != 0xFFFFFFFF) {
515 /* RP1 D3 cold exit. */
516 \_SB.PCI0.TRP1.D3CX()
517 }
518 } Else {
519 Printf("Drop TG0N due to it is already exit D3 cold.")
520 }
521
522 /* TBT RTD3 exit 10ms delay. */
523 Sleep (10)
524 }
525 }
526
527 /*
528 * TBT Group0 OFF method
529 */
530 Method (TG0F, 0)
531 {
532 If (\_SB.PCI0.TDM0.VDID == 0xFFFFFFFF) {
533 Printf("TDM0 does not exist.")
534 } Else {
535 If (\_SB.PCI0.TDM0.STAT == 1) {
536 If (\_SB.PCI0.TDM0.INFR != 1) {
537 Return
538 }
539 /* DMA0 is not in D3Cold now. */
540 \_SB.PCI0.TDM0.D3CE() /* Enable DMA RTD3 */
541
542 Printf("Push TBT RPs to D3Cold together")
543 If (\_SB.PCI0.TRP0.VDID != 0xFFFFFFFF) {
544 /* Put RP0 to D3 cold. */
545 \_SB.PCI0.TRP0.D3CE()
546 }
547 If (\_SB.PCI0.TRP1.VDID != 0xFFFFFFFF) {
548 /* Put RP1 to D3 cold. */
549 \_SB.PCI0.TRP1.D3CE()
550 }
551 }
552 }
553 }
554
555 /*
556 * TBT Group1 ON method
557 */
558 Method (TG1N, 0)
559 {
560 If (\_SB.PCI0.TDM1.VDID == 0xFFFFFFFF) {
561 Printf("TDM1 does not exist.")
562 } Else {
563 If (\_SB.PCI0.TDM1.STAT == 0) {
564 /* DMA1 is in D3Cold early. */
565 \_SB.PCI0.TDM1.D3CX() /* RTD3 Exit */
566
567 Printf("Bring TBT RPs out of D3Code.")
568 If (\_SB.PCI0.TRP2.VDID != 0xFFFFFFFF) {
569 /* RP2 D3 cold exit. */
570 \_SB.PCI0.TRP2.D3CX()
571 }
572 If (\_SB.PCI0.TRP3.VDID != 0xFFFFFFFF) {
573 /* RP3 D3 cold exit. */
574 \_SB.PCI0.TRP3.D3CX()
575 }
576 } Else {
577 Printf("Drop TG1N due to it is already exit D3 cold.")
578 }
579
580 /* TBT RTD3 exit 10ms delay. */
581 Sleep (10)
582 }
583 }
584
585 /*
586 * TBT Group1 OFF method
587 */
588 Method (TG1F, 0)
589 {
590 If (\_SB.PCI0.TDM1.VDID == 0xFFFFFFFF) {
591 Printf("TDM1 does not exist.")
592 } Else {
593 If (\_SB.PCI0.TDM1.STAT == 1) {
594 If (\_SB.PCI0.TDM1.INFR != 1) {
595 Return
596 }
597 /* DMA1 is not in D3Cold now */
598 \_SB.PCI0.TDM1.D3CE() /* Enable DMA RTD3. */
599
600 Printf("Push TBT RPs to D3Cold together")
601 If (\_SB.PCI0.TRP2.VDID != 0xFFFFFFFF) {
602 /* Put RP2 to D3 cold. */
603 \_SB.PCI0.TRP2.D3CE()
604 }
605 If (\_SB.PCI0.TRP3.VDID != 0xFFFFFFFF) {
606 /* Put RP3 to D3 cold */
607 \_SB.PCI0.TRP3.D3CE()
608 }
609 }
610 }
611 }
612
613 PowerResource (TBT0, 5, 1)
614 {
615 Method (_STA, 0)
616 {
617 Return (\_SB.PCI0.TDM0.STAT)
618 }
619
620 Method (_ON, 0)
621 {
622 TG0N()
623 }
624
625 Method (_OFF, 0)
626 {
627 If (\_SB.PCI0.TDM0.SD3C == 0) {
628 TG0F()
629 }
630 }
631 }
632
633 PowerResource (TBT1, 5, 1)
634 {
635 Method (_STA, 0)
636 {
637 Return (\_SB.PCI0.TDM1.STAT)
638 }
639
640 Method (_ON, 0)
641 {
642 TG1N()
643 }
644
645 Method (_OFF, 0)
646 {
647 If (\_SB.PCI0.TDM1.SD3C == 0) {
648 TG1F()
649 }
650 }
651 }
652
653 Method (TCON, 0)
654 {
655 /* Reset IOM D3 cold bit if it is in D3 cold now. */
656 If (TD3C == 1) /* It was in D3 cold before. */
657 {
658 /* Reset IOM D3 cold bit. */
659 TD3C = 0 /* Request IOM for D3 cold exit sequence. */
660 Local0 = 0 /* Time check counter variable */
661 /* Wait for ack, the maximum wait time for the ack is 100 msec. */
662 While ((TACK != 0) && (Local0 < TCSS_IOM_ACK_TIMEOUT_IN_MS)) {
663 /*
664 * Wait in this loop until TACK becomes 0 with timeout
665 * TCSS_IOM_ACK_TIMEOUT_IN_MS by default.
666 */
667 Sleep (1) /* Delay of 1ms. */
668 Local0++
669 }
670
671 If (Local0 == TCSS_IOM_ACK_TIMEOUT_IN_MS) {
672 Printf("Error: Timeout occurred.")
673 }
674 Else
675 {
676 /*
677 * If the TCSS Deven is cleared by BIOS Mailbox request, then
678 * restore to previously saved value of TCSS DEVNE.
679 */
680 Local0 = 0
681 While (\_SB.PCI0.TXHC.VDID == 0xFFFFFFFF) {
682 If (DSGS () == 1) {
683 DSCR (0)
684 }
685 Local0++
686 If (Local0 == 5) {
687 Printf("pCode mailbox command failed.")
688 Break
689 }
690 }
691 }
692 }
693 Else {
694 Printf("Drop TCON due to it is already exit D3 cold.")
695 }
696 }
697
698 Method (TCOF, 0)
699 {
700 If ((\_SB.PCI0.TXHC.SD3C != 0) || (\_SB.PCI0.TDM0.SD3C != 0)
701 || (\_SB.PCI0.TDM1.SD3C != 0))
702 {
703 Printf("Skip D3C entry.")
704 Return
705 }
706
707 /*
708 * If the TCSS Deven in normal state, then Save current TCSS DEVEN value and
709 * clear it.
710 */
711 Local0 = 0
712 While (\_SB.PCI0.TXHC.VDID != 0xFFFFFFFF) {
713 If (DSGS () == 0) {
714 DSCR (1)
715 }
716 Local0++
717 If (Local0 == 5) {
718 Printf("pCode mailbox command failed.")
719 Break
720 }
721 }
722
723 /* Request IOM for D3 cold entry sequence. */
zhaojohn88a496a2022-09-12 14:24:59 -0700724 /*
725 * FIXME: Remove this workaround after resolving b/244082753
726 *
727 * Document #742990: TCCold exit flow may not complete when processor at package
728 * C0. The implication is that the system may hang.
729 */
730 // TD3C = 1
Ravi Sarawadie02fd832022-05-08 00:27:31 -0700731 }
732
733 PowerResource (D3C, 5, 0)
734 {
735 /*
736 * Variable to save power state
737 * 1 - TC Cold request cleared.
738 * 0 - TC Cold request sent.
739 */
740 Name (STAT, 0x1)
741
742 Method (_STA, 0)
743 {
744 Return (STAT)
745 }
746
747 Method (_ON, 0)
748 {
749 \_SB.PCI0.TCON()
750 STAT = 1
751 }
752
753 Method (_OFF, 0)
754 {
755 \_SB.PCI0.TCOF()
756 STAT = 0
757 }
758 }
759
760 /*
761 * TCSS xHCI device
762 */
763 Device (TXHC)
764 {
765 Name (_ADR, 0x000D0000)
766 Name (_DDN, "North XHCI controller")
767 Name (_STR, Unicode ("North XHCI controller"))
768 Name (DCPM, TCSS_XHCI)
769
770 Method (_STA, 0x0, NotSerialized)
771 {
772 If (THCE == 1) {
773 Return (0x0F)
774 } Else {
775 Return (0x0)
776 }
777 }
778 #include "tcss_xhci.asl"
779 }
780
781 /*
782 * TCSS DMA0 device
783 */
784 Device (TDM0)
785 {
786 Name (_ADR, 0x000D0002)
787 Name (_DDN, "TBT DMA0 controller")
788 Name (_STR, Unicode ("TBT DMA0 controller"))
789 Name (DUID, 0) /* TBT DMA number */
790 Name (DCPM, TCSS_DMA0)
791
792 Method (_STA, 0x0, NotSerialized)
793 {
794 If (DME0 == 1) {
795 Return (0x0F)
796 } Else {
797 Return (0x0)
798 }
799 }
800 #include "tcss_dma.asl"
801 }
802
803 /*
804 * TCSS DMA1 device
805 */
806 Device (TDM1)
807 {
808 Name (_ADR, 0x000D0003)
809 Name (_DDN, "TBT DMA1 controller")
810 Name (_STR, Unicode ("TBT DMA1 controller"))
811 Name (DUID, 1) /* TBT DMA number */
812 Name (DCPM, TCSS_DMA1)
813
814 Method (_STA, 0x0, NotSerialized)
815 {
816 If (DME1 == 1) {
817 Return (0x0F)
818 } Else {
819 Return (0x0)
820 }
821 }
822 #include "tcss_dma.asl"
823 }
824
825 /*
826 * TCSS PCIE Root Port #00
827 */
828 Device (TRP0)
829 {
830 Name (_ADR, 0x00070000)
831 Name (TUID, 0) /* TBT PCIE RP Number 0 for RP00 */
832 Name (LTEN, 0) /* Latency Tolerance Reporting Mechanism, 0:Disable, 1:Enable */
833 Name (LMSL, 0) /* PCIE LTR max snoop Latency */
834 Name (LNSL, 0) /* PCIE LTR max no snoop Latency */
835 Name (DCPM, TCSS_TBT_PCIE0_RP0)
836
837 Method (_STA, 0x0, NotSerialized)
838 {
839 If (TRE0 == 1) {
840 Return (0x0F)
841 } Else {
842 Return (0x0)
843 }
844 }
845
846 Method (_INI)
847 {
848 LTEN = 0
849 LMSL = 0x88C8
850 LNSL = 0x88C8
851 }
852 #include "tcss_pcierp.asl"
853 }
854
855 /*
856 * TCSS PCIE Root Port #01
857 */
858 Device (TRP1)
859 {
860 Name (_ADR, 0x00070001)
861 Name (TUID, 1) /* TBT PCIE RP Number 1 for RP01 */
862 Name (LTEN, 0) /* Latency Tolerance Reporting Mechanism, 0:Disable, 1:Enable */
863 Name (LMSL, 0) /* PCIE LTR max snoop Latency */
864 Name (LNSL, 0) /* PCIE LTR max no snoop Latency */
865 Name (DCPM, TCSS_TBT_PCIE0_RP1)
866
867 Method (_STA, 0x0, NotSerialized)
868 {
869 If (TRE1 == 1) {
870 Return (0x0F)
871 } Else {
872 Return (0x0)
873 }
874 }
875
876 Method (_INI)
877 {
878 LTEN = 0
879 LMSL = 0x88C8
880 LNSL = 0x88C8
881 }
882 #include "tcss_pcierp.asl"
883 }
884
885 /*
886 * TCSS PCIE Root Port #02
887 */
888 Device (TRP2)
889 {
890 Name (_ADR, 0x00070002)
891 Name (TUID, 2) /* TBT PCIE RP Number 2 for RP02 */
892 Name (LTEN, 0) /* Latency Tolerance Reporting Mechanism, 0:Disable, 1:Enable */
893 Name (LMSL, 0) /* PCIE LTR max snoop Latency */
894 Name (LNSL, 0) /* PCIE LTR max no snoop Latency */
895 Name (DCPM, TCSS_TBT_PCIE0_RP2)
896
897 Method (_STA, 0x0, NotSerialized)
898 {
899 If (TRE2 == 1) {
900 Return (0x0F)
901 } Else {
902 Return (0x0)
903 }
904 }
905
906 Method (_INI)
907 {
908 LTEN = 0
909 LMSL = 0x88C8
910 LNSL = 0x88C8
911 }
912 #include "tcss_pcierp.asl"
913 }
914
915 /*
916 * TCSS PCIE Root Port #03
917 */
918 Device (TRP3)
919 {
920 Name (_ADR, 0x00070003)
921 Name (TUID, 3) /* TBT PCIE RP Number 3 for RP03 */
922 Name (LTEN, 0) /* Latency Tolerance Reporting Mechanism, 0:Disable, 1:Enable */
923 Name (LMSL, 0) /* PCIE LTR max snoop Latency */
924 Name (LNSL, 0) /* PCIE LTR max no snoop Latency */
925 Name (DCPM, TCSS_TBT_PCIE0_RP3)
926
927 Method (_STA, 0x0, NotSerialized)
928 {
929 If (TRE3 == 1) {
930 Return (0x0F)
931 } Else {
932 Return (0x0)
933 }
934 }
935
936 Method (_INI)
937 {
938 LTEN = 0
939 LMSL = 0x88C8
940 LNSL = 0x88C8
941 }
942 #include "tcss_pcierp.asl"
943 }
944}