blob: 608b46450d9b12e40700bd5a079aa63e71eea875 [file] [log] [blame]
Elyes HAOUASf50b6622020-07-19 14:00:43 +02001/* SPDX-License-Identifier: GPL-2.0-or-later */
John Zhaoca584082020-03-16 15:33:06 -07002
Subrata Banikff433b72022-12-08 16:05:40 +05303#include <intelblocks/tcss.h>
John Zhaoca584082020-03-16 15:33:06 -07004#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 */
John Zhaoca584082020-03-16 15:33:06 -070030#define TCSS_IOM_ACK_TIMEOUT_IN_MS 100
31
John Zhaob8febf42020-06-11 18:05:23 -070032#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
John Zhaoca584082020-03-16 15:33:06 -070043Scope (\_SB)
44{
45 /* Device base address */
46 Method (BASE, 1)
47 {
48 Local0 = Arg0 & 0x7 /* Function number */
John Zhaof74aa6492020-06-07 09:20:01 -070049 Local1 = (Arg0 >> 16) & 0x1F /* Device number */
John Zhaoca584082020-03-16 15:33:06 -070050 Local2 = (Local0 << 12) + (Local1 << 15)
51 Local3 = \_SB.PCI0.GPCB() + Local2
52 Return (Local3)
53 }
54
55 /*
John Zhao7d054bd2020-05-19 11:10:21 -070056 * Define PCH ACPIBASE IO as an ACPI operating region. The base address can be
John Zhaoca584082020-03-16 15:33:06 -070057 * found in Device 31, Function 2, Offset 40h.
58 */
John Zhao7d054bd2020-05-19 11:10:21 -070059 OperationRegion (PMIO, SystemIO, ACPI_BASE_ADDRESS, 0x80)
John Zhaoca584082020-03-16 15:33:06 -070060 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 {
John Zhao9e9f3012020-05-13 09:53:24 -070085 Local0 = 1 << Arg3
John Zhaoca584082020-03-16 15:33:06 -070086 /* 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 }
John Zhaob8febf42020-06-11 18:05:23 -0700137
138 Method (_OSC, 4, Serialized)
139 {
John Zhao85288672020-06-22 09:30:47 -0700140 CreateDWordField (Arg3, 0, CDW1)
John Zhaoc47e3142020-06-24 23:08:01 -0700141 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)
Sean Rhodes060df172022-05-21 10:39:27 +0100158#if CONFIG(SOFTWARE_CONNECTION_MANAGER)
Sean Rhodese72e8572021-11-01 21:33:37 +0000159 /*
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 */
John Zhaoc47e3142020-06-24 23:08:01 -0700164 } 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
John Zhaob8febf42020-06-11 18:05:23 -0700186
187 If (Arg1 != REVISION_ID) {
188 CDW1 |= UNRECOGNIZED_REVISION
John Zhao85288672020-06-22 09:30:47 -0700189 Return (Arg3)
John Zhaob8febf42020-06-11 18:05:23 -0700190 }
John Zhaoc47e3142020-06-24 23:08:01 -0700191 Local0 |= USB_TUNNELING | DISPLAY_PORT_TUNNELING | PCIE_TUNNELING |
John Zhaob8febf42020-06-11 18:05:23 -0700192 INTER_DOMAIN_USB4_INTERNET_PROTOCOL
John Zhaoc47e3142020-06-24 23:08:01 -0700193 CDW3 = Local0
John Zhaob8febf42020-06-11 18:05:23 -0700194 Return (Arg3)
Sean Rhodese72e8572021-11-01 21:33:37 +0000195#endif
John Zhaob8febf42020-06-11 18:05:23 -0700196 } Else {
197 CDW1 |= UNRECOGNIZED_UUID
198 Return (Arg3)
199 }
200 }
John Zhaoca584082020-03-16 15:33:06 -0700201}
202
John Zhaof74aa6492020-06-07 09:20:01 -0700203Scope (_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
John Zhaoca584082020-03-16 15:33:06 -0700324Scope (\_SB.PCI0)
325{
John Zhao6aedba22020-05-26 21:19:19 -0700326 Device (IOM)
327 {
328 Name (_HID, "INTC1072")
329 Name (_DDN, "Intel(R) Tiger 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 })
Matt DeVillier3d85d6b2022-11-29 13:00:31 -0600334 Name (_STA, 0xF)
John Zhao6aedba22020-05-26 21:19:19 -0700335 }
336
John Zhaoca584082020-03-16 15:33:06 -0700337 /*
John Zhaob8febf42020-06-11 18:05:23 -0700338 * 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 /*
John Zhaoca584082020-03-16 15:33:06 -0700357 * 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 Field (MBAR, DWordAcc, NoLock, Preserve)
367 {
368 Offset(0x304), /* PRIMDN_MASK1_0_0_0_MCHBAR_IMPH, offset 0x7404 */
369 , 31,
370 TCD3, 1 /* [31:31] TCSS IN D3 bit */
371 }
372
373 /*
374 * Operation region defined to access the pCode mailbox interface. Get the MCHBAR
375 * in offset 0x48 in B0:D0:F0. MMIO address is in offset 0x5DA0 of MCHBAR.
376 */
377 OperationRegion (PBAR, SystemMemory, (GMHB() + 0x5DA0), 0x08)
378 Field (PBAR, DWordAcc, NoLock, Preserve)
379 {
380 PMBD, 32, /* pCode MailBox Data, offset 0x5DA0 in MCHBAR */
381 PMBC, 8, /* pCode MailBox Command, [7:0] of offset 0x5DA4 in MCHBAR */
382 PSCM, 8, /* pCode MailBox Sub-Command, [15:8] of offset 0x5DA4 in MCHBAR */
383 , 15, /* Reserved */
384 PMBR, 1 /* pCode MailBox RunBit, [31:31] of offset 0x5DA4 in MCHBAR */
385 }
386
387 /*
388 * Poll pCode MailBox Ready
389 *
390 * Return 0xFF - Timeout
Elyes HAOUASe912e3e2020-08-13 14:54:21 +0200391 * 0x00 - Ready
John Zhaoca584082020-03-16 15:33:06 -0700392 */
393 Method (PMBY, 0)
394 {
395 Local0 = 0
396 While (PMBR && (Local0 < 1000)) {
397 Local0++
398 Stall (1)
399 }
400 If (Local0 == 1000) {
401 Printf("Timeout occurred.")
402 Return (0xFF)
403 }
404 Return (0)
405 }
406
407 /*
408 * Method to send pCode MailBox command TCSS_DEVEN_MAILBOX_SUBCMD_GET_STATUS
409 *
410 * Result will be updated in DATA[1:0]
411 * DATA[0:0] TCSS_DEVEN_CURRENT_STATE:
412 * 0 - TCSS Deven in normal state.
413 * 1 - TCSS Deven is cleared by BIOS Mailbox request.
414 * DATA[1:1] TCSS_DEVEN_REQUEST_STATUS:
415 * 0 - IDLE. TCSS DEVEN has reached its final requested state.
416 * 1 - In Progress. TCSS DEVEN is currently in progress of switching state
Elyes HAOUASe912e3e2020-08-13 14:54:21 +0200417 * according to given request (bit 0 reflects source state).
John Zhaoca584082020-03-16 15:33:06 -0700418 *
419 * Return 0x00 - TCSS Deven in normal state
Elyes HAOUASe912e3e2020-08-13 14:54:21 +0200420 * 0x01 - TCSS Deven is cleared by BIOS Mailbox request
421 * 0x1x - TCSS Deven is in progress of switching state according to given request
422 * 0xFE - Command timeout
423 * 0xFF - Command corrupt
John Zhaoca584082020-03-16 15:33:06 -0700424 */
425 Method (DSGS, 0)
426 {
427 If ((PMBY () == 0)) {
428 PMBC = MAILBOX_BIOS_CMD_TCSS_DEVEN_INTERFACE
429 PSCM = TCSS_DEVEN_MAILBOX_SUBCMD_GET_STATUS
430 PMBR = 1
431 If (PMBY () == 0) {
432 Local0 = PMBD
433 Local1 = PMBC
434 Stall (10)
435 If ((Local0 != PMBD) || (Local1 != PMBC)) {
436 Printf("pCode MailBox is corrupt.")
437 Return (0xFF)
438 }
439 Return (Local0)
440 } Else {
441 Printf("pCode MailBox is not ready.")
442 Return (0xFE)
443 }
444 } Else {
445 Printf("pCode MailBox is not ready.")
446 Return (0xFE)
447 }
448 }
449
450 /*
451 * Method to send pCode MailBox command TCSS_DEVEN_MAILBOX_SUBCMD_TCSS_CHANGE_REQ
452 *
453 * Arg0 : 0 - Restore to previously saved value of TCSS DEVEN
454 * 1 - Save current TCSS DEVEN value and clear it
455 *
456 * Return 0x00 - MAILBOX_BIOS_CMD_CLEAR_TCSS_DEVEN command completed
457 * 0xFD - Input argument is invalid
458 * 0xFE - Command timeout
459 * 0xFF - Command corrupt
460 */
461 Method (DSCR, 1)
462 {
463 If (Arg0 > 1) {
464 Printf("pCode MailBox is corrupt.")
465 Return (0xFD)
466 }
467 If ((PMBY () == 0)) {
468 PMBC = MAILBOX_BIOS_CMD_TCSS_DEVEN_INTERFACE
469 PSCM = TCSS_DEVEN_MAILBOX_SUBCMD_TCSS_CHANGE_REQ
470 PMBD = Arg0
471 PMBR = 1
472 If ((PMBY () == 0)) {
473 Local0 = PMBD
474 Local1 = PMBC
475 Stall (10)
476 If ((Local0 != PMBD) || (Local1 != PMBC)) {
477 Printf("pCode MailBox is corrupt.")
478 Return (0xFF)
479 }
480 /* Poll TCSS_DEVEN_REQUEST_STATUS, timeout value is 10ms. */
481 Local0 = 0
482 While ((DSGS () & 0x10) && (Local0 < 100)) {
483 Stall (100)
484 Local0++
485 }
486 If (Local0 == 100) {
487 Printf("pCode MailBox is not ready.")
488 Return (0xFE)
489 } Else {
490 Return (0x00)
491 }
492 } Else {
493 Printf("pCode MailBox is not ready.")
494 Return (0xFE)
495 }
496 } Else {
497 Printf("pCode MailBox is not ready.")
498 Return (0xFE)
499 }
500 }
501
502 /*
503 * IOM REG BAR Base address is in offset 0x7110 in MCHBAR.
504 */
505 Method (IOMA, 0)
506 {
507 Return (^RBAR & ~0x1)
508 }
509
510 /*
511 * From RegBar Base, IOM_TypeC_SW_configuration_1 is in offset 0xC10040, where
512 * 0x40 is the register offset.
513 */
514 OperationRegion (IOMR, SystemMemory, (IOMA() + 0xC10000), 0x100)
515 Field (IOMR, DWordAcc, NoLock, Preserve)
516 {
517 Offset(0x40),
518 , 15,
519 TD3C, 1, /* [15:15] Type C D3 cold bit */
520 TACK, 1, /* [16:16] IOM Acknowledge bit */
521 DPOF, 1, /* [17:17] Set 1 to indicate IOM, all the */
522 /* display is OFF, clear otherwise */
Martin Roth26f97f92021-10-01 14:53:22 -0600523 Offset(0x70), /* Physical addr is offset 0x70. */
John Zhaoca584082020-03-16 15:33:06 -0700524 IMCD, 32, /* R_SA_IOM_BIOS_MAIL_BOX_CMD */
525 IMDA, 32 /* R_SA_IOM_BIOS_MAIL_BOX_DATA */
526 }
527
528 /*
John Zhaoca584082020-03-16 15:33:06 -0700529 * TBT Group0 ON method
530 */
531 Method (TG0N, 0)
532 {
533 If (\_SB.PCI0.TDM0.VDID == 0xFFFFFFFF) {
534 Printf("TDM0 does not exist.")
John Zhaoca584082020-03-16 15:33:06 -0700535 } Else {
John Zhaof74aa6492020-06-07 09:20:01 -0700536 If (\_SB.PCI0.TDM0.STAT == 0) {
537 /* DMA0 is in D3Cold early. */
538 \_SB.PCI0.TDM0.D3CX() /* RTD3 Exit */
539
540 Printf("Bring TBT RPs out of D3Code.")
541 If (\_SB.PCI0.TRP0.VDID != 0xFFFFFFFF) {
542 /* RP0 D3 cold exit. */
543 \_SB.PCI0.TRP0.D3CX()
544 }
545 If (\_SB.PCI0.TRP1.VDID != 0xFFFFFFFF) {
546 /* RP1 D3 cold exit. */
547 \_SB.PCI0.TRP1.D3CX()
548 }
John Zhaof74aa6492020-06-07 09:20:01 -0700549 } Else {
550 Printf("Drop TG0N due to it is already exit D3 cold.")
551 }
552
553 /* TBT RTD3 exit 10ms delay. */
554 Sleep (10)
John Zhaoca584082020-03-16 15:33:06 -0700555 }
John Zhaoca584082020-03-16 15:33:06 -0700556 }
557
558 /*
559 * TBT Group0 OFF method
560 */
561 Method (TG0F, 0)
562 {
563 If (\_SB.PCI0.TDM0.VDID == 0xFFFFFFFF) {
564 Printf("TDM0 does not exist.")
John Zhaof74aa6492020-06-07 09:20:01 -0700565 } Else {
566 If (\_SB.PCI0.TDM0.STAT == 1) {
567 /* DMA0 is not in D3Cold now. */
568 \_SB.PCI0.TDM0.D3CE() /* Enable DMA RTD3 */
John Zhaoca584082020-03-16 15:33:06 -0700569
CoolStar377845a2024-02-23 12:09:22 -0800570 If (\_SB.PCI0.TDM0.IF30 != 1) {
571 Return
572 }
573
John Zhaof74aa6492020-06-07 09:20:01 -0700574 Printf("Push TBT RPs to D3Cold together")
575 If (\_SB.PCI0.TRP0.VDID != 0xFFFFFFFF) {
John Zhaof74aa6492020-06-07 09:20:01 -0700576 /* Put RP0 to D3 cold. */
577 \_SB.PCI0.TRP0.D3CE()
John Zhaoca584082020-03-16 15:33:06 -0700578 }
John Zhaof74aa6492020-06-07 09:20:01 -0700579 If (\_SB.PCI0.TRP1.VDID != 0xFFFFFFFF) {
John Zhaof74aa6492020-06-07 09:20:01 -0700580 /* Put RP1 to D3 cold. */
581 \_SB.PCI0.TRP1.D3CE()
John Zhaoca584082020-03-16 15:33:06 -0700582 }
John Zhaoca584082020-03-16 15:33:06 -0700583 }
584 }
585 }
586
587 /*
588 * TBT Group1 ON method
589 */
590 Method (TG1N, 0)
591 {
592 If (\_SB.PCI0.TDM1.VDID == 0xFFFFFFFF) {
593 Printf("TDM1 does not exist.")
John Zhaoca584082020-03-16 15:33:06 -0700594 } Else {
John Zhaof74aa6492020-06-07 09:20:01 -0700595 If (\_SB.PCI0.TDM1.STAT == 0) {
596 /* DMA1 is in D3Cold early. */
597 \_SB.PCI0.TDM1.D3CX() /* RTD3 Exit */
598
599 Printf("Bring TBT RPs out of D3Code.")
600 If (\_SB.PCI0.TRP2.VDID != 0xFFFFFFFF) {
601 /* RP2 D3 cold exit. */
602 \_SB.PCI0.TRP2.D3CX()
603 }
604 If (\_SB.PCI0.TRP3.VDID != 0xFFFFFFFF) {
605 /* RP3 D3 cold exit. */
606 \_SB.PCI0.TRP3.D3CX()
607 }
John Zhaof74aa6492020-06-07 09:20:01 -0700608 } Else {
609 Printf("Drop TG1N due to it is already exit D3 cold.")
610 }
611
612 /* TBT RTD3 exit 10ms delay. */
613 Sleep (10)
John Zhaoca584082020-03-16 15:33:06 -0700614 }
John Zhaoca584082020-03-16 15:33:06 -0700615 }
616
617 /*
618 * TBT Group1 OFF method
619 */
620 Method (TG1F, 0)
621 {
622 If (\_SB.PCI0.TDM1.VDID == 0xFFFFFFFF) {
623 Printf("TDM1 does not exist.")
John Zhaof74aa6492020-06-07 09:20:01 -0700624 } Else {
625 If (\_SB.PCI0.TDM1.STAT == 1) {
626 /* DMA1 is not in D3Cold now */
627 \_SB.PCI0.TDM1.D3CE() /* Enable DMA RTD3. */
John Zhaoca584082020-03-16 15:33:06 -0700628
CoolStar377845a2024-02-23 12:09:22 -0800629 If (\_SB.PCI0.TDM0.IF30 != 1) {
630 Return
631 }
632
John Zhaof74aa6492020-06-07 09:20:01 -0700633 Printf("Push TBT RPs to D3Cold together")
634 If (\_SB.PCI0.TRP2.VDID != 0xFFFFFFFF) {
John Zhaof74aa6492020-06-07 09:20:01 -0700635 /* Put RP2 to D3 cold. */
636 \_SB.PCI0.TRP2.D3CE()
John Zhaoca584082020-03-16 15:33:06 -0700637 }
John Zhaof74aa6492020-06-07 09:20:01 -0700638 If (\_SB.PCI0.TRP3.VDID != 0xFFFFFFFF) {
John Zhaof74aa6492020-06-07 09:20:01 -0700639 /* Put RP3 to D3 cold */
640 \_SB.PCI0.TRP3.D3CE()
John Zhaoca584082020-03-16 15:33:06 -0700641 }
John Zhaoca584082020-03-16 15:33:06 -0700642 }
643 }
644 }
645
646 PowerResource (TBT0, 5, 1)
647 {
648 Method (_STA, 0)
649 {
650 Return (\_SB.PCI0.TDM0.STAT)
651 }
652
653 Method (_ON, 0)
654 {
655 TG0N()
656 }
657
658 Method (_OFF, 0)
659 {
660 If (\_SB.PCI0.TDM0.SD3C == 0) {
661 TG0F()
662 }
663 }
664 }
665
666 PowerResource (TBT1, 5, 1)
667 {
668 Method (_STA, 0)
669 {
670 Return (\_SB.PCI0.TDM1.STAT)
671 }
672
673 Method (_ON, 0)
674 {
675 TG1N()
676 }
677
678 Method (_OFF, 0)
679 {
680 If (\_SB.PCI0.TDM1.SD3C == 0) {
681 TG1F()
682 }
683 }
684 }
685
Sean Rhodes5f0cda72023-04-13 12:17:38 +0100686#if CONFIG(D3COLD_SUPPORT)
Sean Rhodes6b5b7e02023-02-06 09:09:16 +0000687 Method (TCON, 0)
688 {
689 /* Reset IOM D3 cold bit if it is in D3 cold now. */
690 If (TD3C == 1) /* It was in D3 cold before. */
John Zhaoca584082020-03-16 15:33:06 -0700691 {
Sean Rhodes6b5b7e02023-02-06 09:09:16 +0000692 /* Reset IOM D3 cold bit. */
693 TD3C = 0 /* Request IOM for D3 cold exit sequence. */
694 Local0 = 0 /* Time check counter variable */
695 /* Wait for ack, the maximum wait time for the ack is 100 msec. */
696 While ((TACK != 0) && (Local0 < TCSS_IOM_ACK_TIMEOUT_IN_MS)) {
697 /*
698 * Wait in this loop until TACK becomes 0 with timeout
699 * TCSS_IOM_ACK_TIMEOUT_IN_MS by default.
700 */
701 Sleep (1) /* Delay of 1ms. */
702 Local0++
703 }
Sean Rhodes56226662021-11-08 21:34:34 +0000704
Sean Rhodes6b5b7e02023-02-06 09:09:16 +0000705 If (Local0 == TCSS_IOM_ACK_TIMEOUT_IN_MS) {
706 Printf("Error: Timeout occurred.")
707 }
708 Else
709 {
710 /*
711 * Program IOP MCTP Drop (TCSS_IN_D3) after D3 cold exit and
712 * acknowledgement by IOM.
713 */
714 TCD3 = 0
715 /*
716 * If the TCSS Deven is cleared by BIOS Mailbox request, then
717 * restore to previously saved value of TCSS DEVNE.
718 */
719 Local0 = 0
720 While (\_SB.PCI0.TXHC.VDID == 0xFFFFFFFF) {
721 If (DSGS () == 1) {
722 DSCR (0)
723 }
724 Local0++
725 If (Local0 == 5) {
726 Printf("pCode mailbox command failed.")
727 Break
John Zhaoca584082020-03-16 15:33:06 -0700728 }
729 }
730 }
John Zhaoca584082020-03-16 15:33:06 -0700731 }
Sean Rhodes6b5b7e02023-02-06 09:09:16 +0000732 Else {
733 Printf("Drop TCON due to it is already exit D3 cold.")
734 }
735 }
John Zhaoca584082020-03-16 15:33:06 -0700736
Sean Rhodes6b5b7e02023-02-06 09:09:16 +0000737 Method (TCOF, 0)
738 {
739 If ((\_SB.PCI0.TXHC.SD3C != 0) || (\_SB.PCI0.TDM0.SD3C != 0)
740 || (\_SB.PCI0.TDM1.SD3C != 0))
John Zhaoca584082020-03-16 15:33:06 -0700741 {
Sean Rhodes6b5b7e02023-02-06 09:09:16 +0000742 Printf("Skip D3C entry.")
743 Return
John Zhaoca584082020-03-16 15:33:06 -0700744 }
745
Sean Rhodes6b5b7e02023-02-06 09:09:16 +0000746 /*
747 * If the TCSS Deven in normal state, then Save current TCSS DEVEN value and
748 * clear it.
749 */
750 Local0 = 0
751 While (\_SB.PCI0.TXHC.VDID != 0xFFFFFFFF) {
752 If (DSGS () == 0) {
753 DSCR (1)
754 }
755 Local0++
756 If (Local0 == 5) {
757 Printf("pCode mailbox command failed.")
758 Break
759 }
760 }
761
762 /*
763 * Program IOM MCTP Drop (TCSS_IN_D3) in D3Cold entry before entering D3 cold.
764 */
765 TCD3 = 1
766
767 /* Request IOM for D3 cold entry sequence. */
768 TD3C = 1
769 }
770
771 PowerResource (D3C, 5, 0)
772 {
773 /*
774 * Variable to save power state
775 * 1 - TC Cold request cleared.
776 * 0 - TC Cold request sent.
777 */
778 Name (STAT, 0x1)
779
780 Method (_STA, 0)
John Zhaoca584082020-03-16 15:33:06 -0700781 {
Sean Rhodes6b5b7e02023-02-06 09:09:16 +0000782 Return (STAT)
John Zhaoca584082020-03-16 15:33:06 -0700783 }
Sean Rhodes6b5b7e02023-02-06 09:09:16 +0000784
785 Method (_ON, 0)
786 {
787 \_SB.PCI0.TCON()
788 STAT = 1
789 }
790
791 Method (_OFF, 0)
792 {
793 \_SB.PCI0.TCOF()
794 STAT = 0
795 }
796 }
Sean Rhodes5f0cda72023-04-13 12:17:38 +0100797#endif // D3COLD_SUPPORT
John Zhaoca584082020-03-16 15:33:06 -0700798
799 /*
800 * TCSS xHCI device
801 */
802 Device (TXHC)
803 {
804 Name (_ADR, 0x000D0000)
805 Name (_DDN, "North XHCI controller")
806 Name (_STR, Unicode ("North XHCI controller"))
807 Name (DCPM, TCSS_XHCI)
808
809 Method (_STA, 0x0, NotSerialized)
810 {
John Zhaob8febf42020-06-11 18:05:23 -0700811 If (THCE == 1) {
812 Return (0x0F)
813 } Else {
814 Return (0x0)
815 }
John Zhaoca584082020-03-16 15:33:06 -0700816 }
817 #include "tcss_xhci.asl"
818 }
819
820 /*
821 * TCSS DMA0 device
822 */
823 Device (TDM0)
824 {
825 Name (_ADR, 0x000D0002)
826 Name (_DDN, "TBT DMA0 controller")
827 Name (_STR, Unicode ("TBT DMA0 controller"))
828 Name (DUID, 0) /* TBT DMA number */
829 Name (DCPM, TCSS_DMA0)
830
831 Method (_STA, 0x0, NotSerialized)
832 {
John Zhaob8febf42020-06-11 18:05:23 -0700833 If (DME0 == 1) {
834 Return (0x0F)
835 } Else {
836 Return (0x0)
837 }
John Zhaoca584082020-03-16 15:33:06 -0700838 }
839 #include "tcss_dma.asl"
840 }
841
842 /*
843 * TCSS DMA1 device
844 */
845 Device (TDM1)
846 {
847 Name (_ADR, 0x000D0003)
848 Name (_DDN, "TBT DMA1 controller")
849 Name (_STR, Unicode ("TBT DMA1 controller"))
850 Name (DUID, 1) /* TBT DMA number */
851 Name (DCPM, TCSS_DMA1)
852
853 Method (_STA, 0x0, NotSerialized)
854 {
John Zhaob8febf42020-06-11 18:05:23 -0700855 If (DME1 == 1) {
856 Return (0x0F)
857 } Else {
858 Return (0x0)
859 }
John Zhaoca584082020-03-16 15:33:06 -0700860 }
861 #include "tcss_dma.asl"
862 }
863
864 /*
865 * TCSS PCIE Root Port #00
866 */
867 Device (TRP0)
868 {
869 Name (_ADR, 0x00070000)
870 Name (TUID, 0) /* TBT PCIE RP Number 0 for RP00 */
871 Name (LTEN, 0) /* Latency Tolerance Reporting Mechanism, 0:Disable, 1:Enable */
872 Name (LMSL, 0) /* PCIE LTR max snoop Latency */
873 Name (LNSL, 0) /* PCIE LTR max no snoop Latency */
874 Name (DCPM, TCSS_TBT_PCIE0_RP0)
875
876 Method (_STA, 0x0, NotSerialized)
877 {
John Zhaob8febf42020-06-11 18:05:23 -0700878 If (TRE0 == 1) {
879 Return (0x0F)
880 } Else {
881 Return (0x0)
882 }
John Zhaoca584082020-03-16 15:33:06 -0700883 }
John Zhaob8febf42020-06-11 18:05:23 -0700884
John Zhaoca584082020-03-16 15:33:06 -0700885 Method (_INI)
886 {
887 LTEN = 0
888 LMSL = 0x88C8
889 LNSL = 0x88C8
890 }
891 #include "tcss_pcierp.asl"
892 }
893
894 /*
895 * TCSS PCIE Root Port #01
896 */
897 Device (TRP1)
898 {
899 Name (_ADR, 0x00070001)
900 Name (TUID, 1) /* TBT PCIE RP Number 1 for RP01 */
901 Name (LTEN, 0) /* Latency Tolerance Reporting Mechanism, 0:Disable, 1:Enable */
902 Name (LMSL, 0) /* PCIE LTR max snoop Latency */
903 Name (LNSL, 0) /* PCIE LTR max no snoop Latency */
904 Name (DCPM, TCSS_TBT_PCIE0_RP1)
905
906 Method (_STA, 0x0, NotSerialized)
907 {
John Zhaob8febf42020-06-11 18:05:23 -0700908 If (TRE1 == 1) {
909 Return (0x0F)
910 } Else {
911 Return (0x0)
912 }
John Zhaoca584082020-03-16 15:33:06 -0700913 }
John Zhaob8febf42020-06-11 18:05:23 -0700914
John Zhaoca584082020-03-16 15:33:06 -0700915 Method (_INI)
916 {
917 LTEN = 0
918 LMSL = 0x88C8
919 LNSL = 0x88C8
920 }
921 #include "tcss_pcierp.asl"
922 }
923
924 /*
925 * TCSS PCIE Root Port #02
926 */
927 Device (TRP2)
928 {
929 Name (_ADR, 0x00070002)
930 Name (TUID, 2) /* TBT PCIE RP Number 2 for RP02 */
931 Name (LTEN, 0) /* Latency Tolerance Reporting Mechanism, 0:Disable, 1:Enable */
932 Name (LMSL, 0) /* PCIE LTR max snoop Latency */
933 Name (LNSL, 0) /* PCIE LTR max no snoop Latency */
934 Name (DCPM, TCSS_TBT_PCIE0_RP2)
935
936 Method (_STA, 0x0, NotSerialized)
937 {
John Zhaob8febf42020-06-11 18:05:23 -0700938 If (TRE2 == 1) {
939 Return (0x0F)
940 } Else {
941 Return (0x0)
942 }
John Zhaoca584082020-03-16 15:33:06 -0700943 }
John Zhaob8febf42020-06-11 18:05:23 -0700944
John Zhaoca584082020-03-16 15:33:06 -0700945 Method (_INI)
946 {
947 LTEN = 0
948 LMSL = 0x88C8
949 LNSL = 0x88C8
950 }
951 #include "tcss_pcierp.asl"
952 }
953
954 /*
955 * TCSS PCIE Root Port #03
956 */
957 Device (TRP3)
958 {
959 Name (_ADR, 0x00070003)
960 Name (TUID, 3) /* TBT PCIE RP Number 3 for RP03 */
961 Name (LTEN, 0) /* Latency Tolerance Reporting Mechanism, 0:Disable, 1:Enable */
962 Name (LMSL, 0) /* PCIE LTR max snoop Latency */
963 Name (LNSL, 0) /* PCIE LTR max no snoop Latency */
964 Name (DCPM, TCSS_TBT_PCIE0_RP3)
965
966 Method (_STA, 0x0, NotSerialized)
967 {
John Zhaob8febf42020-06-11 18:05:23 -0700968 If (TRE3 == 1) {
969 Return (0x0F)
970 } Else {
971 Return (0x0)
972 }
John Zhaoca584082020-03-16 15:33:06 -0700973 }
John Zhaob8febf42020-06-11 18:05:23 -0700974
John Zhaoca584082020-03-16 15:33:06 -0700975 Method (_INI)
976 {
977 LTEN = 0
978 LMSL = 0x88C8
979 LNSL = 0x88C8
980 }
981 #include "tcss_pcierp.asl"
982 }
983}