summaryrefslogtreecommitdiff
path: root/src/soc/intel/alderlake/acpi/tcss_pcierp.asl
blob: 799c0ce94f1990c678f0207d6b797e6b94f897bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
/* SPDX-License-Identifier: GPL-2.0-or-later */

/*
 * The PCI-SIG engineering change requirement provides the ACPI additions for firmware latency
 * optimization. Both of FW_RESET_TIME and FW_D3HOT_TO_D0_TIME are applicable to the upstream
 * port of the USB4/TBT topology.
 */
/* Number of microseconds to wait after a conventional reset */
#define FW_RESET_TIME			50000

/* Number of microseconds to wait after data link layer active report */
#define FW_DL_UP_TIME			1

/* Number of microseconds to wait after a function level reset */
#define FW_FLR_RESET_TIME		1

/* Number of microseconds to wait from D3 hot to D0 transition */
#define FW_D3HOT_TO_D0_TIME		50000

/* Number of microseconds to wait after setting the VF enable bit  */
#define FW_VF_ENABLE_TIME		1

OperationRegion (PXCS, SystemMemory, BASE(_ADR), 0x800)
Field (PXCS, AnyAcc, NoLock, Preserve)
{
	VDID, 32,
	Offset(0x50),  /* LCTL - Link Control Register */
	L0SE, 1,       /* 0, L0s Entry Enabled */
	, 3,
	LDIS, 1,       /* 1, Link Disable */
	, 3,
	Offset(0x52),  /* LSTS - Link Status Register */
	, 13,
	LASX, 1,       /* 0, Link Active Status */
	Offset(0x5A),  /* SLSTS[7:0] - Slot Status Register */
	ABPX, 1,       /* 0, Attention Button Pressed */
	, 2,
	PDCX, 1,       /* 3, Presence Detect Changed */
	, 2,
	PDSX, 1,       /* 6, Presence Detect State */
	, 1,
	DLSC, 1,       /* 8, Data Link Layer State Changed */
	Offset(0x60),  /* RSTS - Root Status Register */
	, 16,
	PSPX, 1,       /* 16,  PME Status */
	Offset(0xA4),
	D3HT, 2,       /* Power State */
	Offset(0xD8),  /* 0xD8, MPC - Miscellaneous Port Configuration Register */
	, 30,
	HPEX, 1,       /* 30,  Hot Plug SCI Enable */
	PMEX, 1,       /* 31,  Power Management SCI Enable */
	Offset(0xE2),  /* 0xE2, RPPGEN - Root Port Power Gating Enable */
	, 2,
	L23E, 1,       /* 2,   L23_Rdy Entry Request (L23ER) */
	L23R, 1,       /* 3,   L23_Rdy to Detect Transition (L23R2DT) */
	Offset(0x420), /* 0x420, PCIEPMECTL (PCIe PM Extension Control) */
	, 30,
	DPGE, 1,       /* PCIEPMECTL[30]: Disabled, Detect and L23_Rdy State PHY Lane */
		       /* Power Gating Enable (DLSULPPGE) */
	Offset(0x5BC), /* 0x5BC, PCIE ADVMCTRL */
	, 3,
	RPER, 1,       /*  RTD3PERST[3] */
	RPFE, 1,       /*  RTD3PFETDIS[4] */
}

Field (PXCS, AnyAcc, NoLock, WriteAsZeros)
{
	Offset(0xDC),  /* 0xDC, SMSCS - SMI/SCI Status Register */
	, 30,
	HPSX, 1,       /* 30,  Hot Plug SCI Status */
	PMSX, 1        /* 31,  Power Management SCI Status */
}

/*
 * _DSM Device Specific Method
 *
 * Arg0: UUID Unique function identifier
 * Arg1: Integer Revision Level
 * Arg2: Integer Function Index (0 = Return Supported Functions)
 * Arg3: Package Parameters
 */
Method (_DSM, 4, Serialized)
{
	Return (Buffer() { 0x00 })
}

/*
 * A bitmask of functions support
 */
Name(OPTS, Buffer(2) {0, 0})

Device (PXSX)
{
	Name (_ADR, 0x00000000)

	/*
	 * _DSM Device Specific Method
	 *
	 * Arg0: UUID: E5C937D0-3553-4d7a-9117-EA4D19C3434D
	 * Arg1: Revision ID: 3
	 * Arg2: Function index: 0, 9
	 * Arg3: Empty package
	 */
	Method (_DSM, 4, Serialized)
	{
		If (Arg0 == ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D")) {
			If (Arg1 >= 3) {
				If (Arg2 == 0) {
					/*
					 * Function index: 0
					 * Standard query - A bitmask of functions supported
					 */
					CreateBitField(OPTS, 9, FUN9)
					FUN9 = 1
					Return (OPTS)
				} ElseIf (Arg2 == 9) {
					/*
					 * Function index: 9
					 * Specifying device readiness durations
					 */
					Return (Package() { FW_RESET_TIME, FW_DL_UP_TIME,
							FW_FLR_RESET_TIME, FW_D3HOT_TO_D0_TIME,
							FW_VF_ENABLE_TIME })
				}
			}
		}
		Return (Buffer() { 0x0 })
	}

	Method (_PRW, 0)
	{
		Return (Package() { 0x69, 4 })
	}
}

Method (_DSW, 3)
{
	/* If entering Sx (Arg1 > 1), need to skip TCSS D3Cold & TBT RTD3/D3Cold. */
	If ((TUID == 0) || (TUID == 1)) {
		\_SB.PCI0.TDM0.SD3C = Arg1
	} Else {
		\_SB.PCI0.TDM1.SD3C = Arg1
	}

	C2PM (Arg0, Arg1, Arg2, DCPM)
}

Method (_PRW, 0)
{
	Return (Package() { 0x69, 4 })
}

/*
 * Sub-Method of _L61 Hot-Plug event
 * _L61 event handler should invoke this method to support HotPlug wake event from TBT RP.
 */
Method (HPEV, 0, Serialized)
{
	If ((VDID != 0xFFFFFFFF) && HPSX) {
		If ((PDCX == 1) && (DLSC == 1)) {
			/* Clear all status bits first. */
			PDCX = 1
			HPSX = 1

			/* Perform proper notification to the OS. */
			Notify (^, 0)
		} Else {
			/* False event. Clear Hot-Plug Status, then exit. */
			HPSX = 1
		}
	}
}

/*
 * Power Management routine for D3
 */
Name (STAT, 0x1)  /* Variable to save power state 1 - D0, 0 - D3C */

/*
 * RTD3 Exit Method to bring TBT controller out of RTD3 mode.
 */
Method (D3CX, 0, Serialized)
{
	If (STAT == 0x1) {
		Return
	}

	RPFE = 0  /* Set RTD3PFETDIS = 0 */
	RPER = 0  /* Set RTD3PERST = 0 */
	L23R = 1  /* Set L23r2dt = 1 */

	/*
	 * Poll for L23r2dt == 0. Wait for transition to Detect.
	 */
	Local0 = 0
	Local1 = L23R
	While (Local1) {
		If (Local0 > 20) {
			Break
		}
		Sleep(5)
		Local0++
		Local1 = L23R
	}
	STAT = 0x1
}

/*
 * RTD3 Entry method to enable TBT controller RTD3 mode.
 */
Method (D3CE, 0, Serialized)
{
	If (STAT == 0x0) {
		Return
	}

	L23E = 1  /* Set L23er = 1 */

	/* Poll until L23er == 0 */
	Local0 = 0
	Local1 = L23E
	While (Local1) {
		If (Local0 > 20) {
			Break
		}
		Sleep(5)
		Local0++
		Local1 = L23E
	}

	STAT = 0  /* D3Cold */
	RPFE = 1  /* Set RTD3PFETDIS = 1 */
	RPER = 1  /* Set RTD3PERST = 1 */
}

Method (_PS0, 0, Serialized)
{
	HPEV ()  /* Check and handle Hot Plug SCI status. */
	If (HPEX == 1) {
		HPEX = 0  /* Disable Hot Plug SCI */
	}
	HPME ()  /* Check and handle PME SCI status */
	If (PMEX == 1) {
		PMEX = 0  /* Disable Power Management SCI */
	}
}

Method (_PS3, 0, Serialized)
{
	/* Check it is hotplug SCI or not, then clear PDC accordingly */
	If (PDCX == 1) {
		If (DLSC == 0) {
			/* Clear PDC since it is not a hotplug. */
			PDCX = 1
		}
	}

	If (HPEX == 0) {
		HPEX = 1  /* Enable Hot Plug SCI. */
		HPEV ()   /* Check and handle Hot Plug SCI status. */
	}
	If (PMEX == 0) {
		PMEX = 1  /* Enable Power Management SCI. */
		HPME ()   /* Check and handle PME SCI status. */
	}
}

Method (_S0W, 0x0, NotSerialized)
{
	Return (0x4)
}

Method (_PR0)
{
	If ((TUID == 0) || (TUID == 1)) {
		Return (Package() { \_SB.PCI0.D3C, \_SB.PCI0.TBT0 })
	} Else {
		Return (Package() { \_SB.PCI0.D3C, \_SB.PCI0.TBT1 })
	}
}

Method (_PR3)
{
	If ((TUID == 0) || (TUID == 1)) {
		Return (Package() { \_SB.PCI0.D3C, \_SB.PCI0.TBT0 })
	} Else {
		Return (Package() { \_SB.PCI0.D3C, \_SB.PCI0.TBT1 })
	}
}

/*
 * PCI_EXP_STS Handler for PCIE Root Port
 */
Method (HPME, 0, Serialized)
{
	If ((VDID != 0xFFFFFFFF) && (PMSX == 1)) {  /* if port exists and PME SCI Status set */
		/*
		 * Notify child device; this will cause its driver to clear PME_Status from
		 * device.
		 */
		Notify (PXSX, 0x2)
		PMSX = 1  /* clear rootport's PME SCI status */
		/*
		 * Consume one pending PME notification to prevent it from blocking the queue.
		 */
		PSPX = 1
		Return (0x01)
	}
	Return (0x00)
}