1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2004-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 /**************** Resource Manager Defines and Structures ******************\
25 *                                                                           *
26 *       Chipset and Root Port information                                   *
27 *                                                                           *
28 \***************************************************************************/
29 
30 #include "platform/chipset/chipset_info.h"
31 #include "platform/chipset/chipset.h"
32 #include "core/system.h"
33 #include "os/os.h"
34 #include "nvpcie.h"
35 #include "nvdevid.h"
36 
37 #include "nvcst.h"
38 
39 //
40 // X48 & X38 share the same chipset ID, differentiate between two, we need to look at the
41 // capability Identifier register bit 89
42 //
43 #define PCIE_CHIPSET_CAPABILITY_ID_OFFSET_X48   0xE0     // PCIE chipset capability ID offset
44 #define PCIE_CHIPSET_DETECT_OFFSET              0x8      // PCIE chipset identifier
45 #define PCIE_CHIPSET_DETECT_BIT                 0x19     // Chipset detect bit
46 
47 // Used to check if chipset is X38 or X48
48 #define IS_CHIPSET_X38(n)  (!((n) & NVBIT(PCIE_CHIPSET_DETECT_BIT)))
49 
50 static NV_STATUS Intel_Core_Nehalem_Processor_setupFunc(OBJCL *pCl);
51 static NV_STATUS Intel_Huron_River_setupFunc(OBJCL *pCl);
52 void _Set_ASPM_L0S_L1(OBJCL *pCl, NvBool bDisableL0S, NvBool bDisableL1);
53 
54 RPINFO rootPortInfo[] =
55 {
56     {PCI_VENDOR_ID_BROADCOM, 0x0140, RP_BROADCOM_HT2100, Broadcom_HT2100_setupFunc},
57     {PCI_VENDOR_ID_BROADCOM, 0x0142, RP_BROADCOM_HT2100, Broadcom_HT2100_setupFunc},
58     {PCI_VENDOR_ID_BROADCOM, 0x0144, RP_BROADCOM_HT2100, Broadcom_HT2100_setupFunc},
59     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_2581_ROOT_PORT, RP_INTEL_2581, Intel_RP25XX_setupFunc},
60     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_2585_ROOT_PORT, RP_INTEL_2585, Intel_RP25XX_setupFunc},
61     {PCI_VENDOR_ID_INTEL, 0x2589                        , RP_INTEL_2589, Intel_RP25XX_setupFunc},
62     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_2591_ROOT_PORT, RP_INTEL_2591, Intel_RP25XX_setupFunc},
63     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_3597_ROOT_PORT, RP_INTEL_3597, NULL},
64     {PCI_VENDOR_ID_INTEL, 0x2775,                         RP_INTEL_2775, Intel_RP25XX_setupFunc},
65     {PCI_VENDOR_ID_INTEL, 0x2771,                         RP_INTEL_2771, Intel_RP25XX_setupFunc},
66     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_8110_ROOT_PORT, RP_INTEL_8110, Intel_RP81XX_setupFunc},
67     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_8112_ROOT_PORT, RP_INTEL_8112, Intel_RP81XX_setupFunc},
68     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_8180_ROOT_PORT, RP_INTEL_8180, Intel_RP81XX_setupFunc},
69     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_8181_ROOT_PORT, RP_INTEL_8181, Intel_RP81XX_setupFunc},
70     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_8184_ROOT_PORT, RP_INTEL_8184, Intel_RP81XX_setupFunc},
71     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_8185_ROOT_PORT, RP_INTEL_8185, Intel_RP81XX_setupFunc},
72     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_3C02_ROOT_PORT, RP_INTEL_3C02, Intel_RP3C0X_setupFunc},
73     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_3C03_ROOT_PORT, RP_INTEL_3C03, Intel_RP3C0X_setupFunc},
74     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_3C04_ROOT_PORT, RP_INTEL_3C04, Intel_RP3C0X_setupFunc},
75     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_3C05_ROOT_PORT, RP_INTEL_3C05, Intel_RP3C0X_setupFunc},
76     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_3C06_ROOT_PORT, RP_INTEL_3C06, Intel_RP3C0X_setupFunc},
77     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_3C07_ROOT_PORT, RP_INTEL_3C07, Intel_RP3C0X_setupFunc},
78     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_3C08_ROOT_PORT, RP_INTEL_3C08, Intel_RP3C0X_setupFunc},
79     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_3C09_ROOT_PORT, RP_INTEL_3C09, Intel_RP3C0X_setupFunc},
80     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_3C0A_ROOT_PORT, RP_INTEL_3C0A, Intel_RP3C0X_setupFunc},
81     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_3C0B_ROOT_PORT, RP_INTEL_3C0B, Intel_RP3C0X_setupFunc},
82     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_2F04_ROOT_PORT, RP_INTEL_2F04, Intel_RP2F0X_setupFunc},
83     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_2F08_ROOT_PORT, RP_INTEL_2F08, Intel_RP2F0X_setupFunc},
84     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_0C01_ROOT_PORT, RP_INTEL_0C01, Intel_RP0C0X_setupFunc},
85 
86 // last element must have zero vendor id and device id
87     {0,                   0,                              RP_UNKNOWN,    NULL}
88 };
89 
90 BRINFO upstreamPortInfo[] =
91 {
92     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_1901_ROOT_PORT,  Intel_Skylake_setupFunc},
93     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_9D18_PCH_BRIDGE, Intel_Skylake_U_Pch_setupFunc},
94     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_A117_PCH_BRIDGE, Intel_Skylake_H_Pch_setupFunc},
95     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_A118_PCH_BRIDGE, Intel_Skylake_H_Pch_setupFunc},
96     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_9C98_PCH_BRIDGE, Intel_Broadwell_setupFunc},
97     {PCI_VENDOR_ID_INTEL, DEVICE_ID_INTEL_9D10_PCH_BRIDGE, Intel_Kabylake_Y_setupFunc},
98     {PCI_VENDOR_ID_AMD,   DEVICE_ID_AMD_1483_ROOT_PORT,    AMD_RP1483_setupFunc},
99     {PCI_VENDOR_ID_AMD,   DEVICE_ID_AMD_1480_ROOT_PORT,    AMD_RP1480_setupFunc},
100     {PCI_VENDOR_ID_AMD,   DEVICE_ID_AMD_1630_ROOT_PORT,    AMD_RP1630_setupFunc},
101 
102     // last element must have zero vendor id and device id
103     {0, 0, NULL}
104 };
105 
106 static NV_STATUS
107 Intel_25XX_setupFunc
108 (
109     OBJCL *pCl
110 )
111 {
112     RmPhysAddr baseAddress;
113 
114     if (!pCl->FHBAddr.valid)
115         return NV_ERR_GENERIC;
116     baseAddress = (RmPhysAddr)(osPciReadDword(pCl->FHBAddr.handle,
117                                               INTEL_25XX_CONFIG_SPACE_BASE));
118 
119     // PCI-E enhanced config space is 256M aligned
120     baseAddress &= ( ~ 0x0fffffff);
121 
122     if (baseAddress)
123     {
124         if (clInsertPcieConfigSpaceBase(pCl, baseAddress, 0, 0, (NvU8)(PCI_MAX_BUSES - 1)) == NV_OK)
125             pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE, NV_TRUE);
126     }
127 
128     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_SKIP_MCFG_READ, NV_TRUE);
129 
130     return NV_OK;
131 }
132 
133 // Montevina
134 static NV_STATUS
135 Intel_2A40_setupFunc
136 (
137     OBJCL *pCl
138 )
139 {
140     RmPhysAddr baseAddress;
141 
142     if (!pCl->FHBAddr.valid)
143         return NV_ERR_GENERIC;
144     baseAddress = (RmPhysAddr)(osPciReadDword(pCl->FHBAddr.handle,
145                                               INTEL_2A40_CONFIG_SPACE_BASE));
146 
147     //
148     // PCI-E v1.1 enhanced config space is aligned between 1M and 256M,
149     // depending on # of buses (see PCIE v1.1, section 7.2.2).
150     //
151     baseAddress &= ( ~ 0x000fffff);
152 
153     if (baseAddress)
154     {
155         if (clInsertPcieConfigSpaceBase(pCl, baseAddress, 0, 0, (NvU8)(PCI_MAX_BUSES - 1)) == NV_OK)
156         {
157             pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE, NV_TRUE);
158             //
159             // Get the specific Montevina revision to see if its safe to enable
160             // ALSM.  Note that the initial Montevina boards do not support ASLM.
161             //
162             if (pCl->FHBBusInfo.revisionID >= INTEL_2A40_ASLM_CAPABLE_REVID)
163             {
164                 // Supports ASLM
165                 pCl->setProperty(pCl, PDB_PROP_CL_ASLM_SUPPORTS_NV_LINK_UPGRADE, NV_TRUE);
166             }
167         }
168     }
169 
170     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_SKIP_MCFG_READ, NV_TRUE);
171 
172     return NV_OK;
173 }
174 
175 // Calpella - Arrandale
176 static NV_STATUS
177 Intel_0040_setupFunc
178 (
179     OBJCL *pCl
180 )
181 {
182     pCl->setProperty(pCl, PDB_PROP_CL_ASLM_SUPPORTS_GEN2_LINK_UPGRADE, NV_TRUE);
183 
184     return Intel_Core_Nehalem_Processor_setupFunc(pCl);
185 }
186 
187 // Eaglelake
188 static NV_STATUS
189 Intel_2E00_setupFunc
190 (
191     OBJCL *pCl
192 )
193 {
194     RmPhysAddr baseAddress;
195 
196     if (!pCl->FHBAddr.valid)
197     {
198         return NV_ERR_GENERIC;
199     }
200 
201     baseAddress = (RmPhysAddr)(osPciReadDword(pCl->FHBAddr.handle,
202                                               INTEL_2E00_CONFIG_SPACE_BASE));
203 
204     //
205     // PCI-E v1.1 enhanced config space is aligned between 1M and 256M,
206     // depending on # of buses (see PCIE v1.1, section 7.2.2)
207     //
208     baseAddress &= ( ~ 0x000fffff);
209 
210     if (baseAddress)
211     {
212         if (clInsertPcieConfigSpaceBase(pCl, baseAddress, 0, 0, (NvU8)(PCI_MAX_BUSES - 1)) == NV_OK)
213             pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE, NV_TRUE);
214     }
215 
216     // Set ASPM L0S\L1 properties
217     _Set_ASPM_L0S_L1(pCl, NV_TRUE, NV_FALSE);
218 
219     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_SKIP_MCFG_READ, NV_TRUE);
220 
221     return NV_OK;
222 }
223 
224 
225 // Q35/BearlakeB/IntelQ33
226 static NV_STATUS
227 Intel_29X0_setupFunc
228 (
229     OBJCL *pCl
230 )
231 {
232     NV_STATUS  rmStatus;
233 
234     rmStatus = Intel_29XX_setupFunc(pCl);
235 
236     // Set ASPM L0S\L1 properties
237     _Set_ASPM_L0S_L1(pCl, NV_TRUE, NV_TRUE);
238 
239     return rmStatus;
240 }
241 
242 static NV_STATUS
243 Intel_29E0_setupFunc
244 (
245     OBJCL *pCl
246 )
247 {
248     NV_STATUS  rmStatus;
249     NvU32      capId;
250 
251     rmStatus = Intel_29XX_setupFunc(pCl);
252     //
253     // Both X48 & X38 chipset share the same device ID and bit 89
254     // of pci capability register is used to differentiate between two
255     // (Bug 549707)
256     //
257     capId = clPcieReadDword(
258              pCl,
259              pCl->FHBAddr.domain,
260              pCl->FHBAddr.bus,
261              pCl->FHBAddr.device,
262              pCl->FHBAddr.func,
263              (PCIE_CHIPSET_CAPABILITY_ID_OFFSET_X48 + PCIE_CHIPSET_DETECT_OFFSET));
264 
265     if (IS_CHIPSET_X38(capId))
266     {
267         // Not capable of Gen1/Gen2 switch
268         pCl->setProperty(pCl,
269             PDB_PROP_CL_PCIE_GEN1_GEN2_SWITCH_CHIPSET_DISABLED_GEFORCE,
270             NV_TRUE);
271     }
272 
273     // Set ASPM L0S\L1 properties
274     _Set_ASPM_L0S_L1(pCl, NV_TRUE, NV_FALSE);
275 
276     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_GEN2_AT_LESS_THAN_X16_DISABLED, NV_TRUE);
277 
278     return rmStatus;
279 }
280 
281 static NV_STATUS
282 Intel_29XX_setupFunc
283 (
284     OBJCL *pCl
285 )
286 {
287     RmPhysAddr baseAddress;
288 
289     if (!pCl->FHBAddr.valid)
290         return NV_ERR_GENERIC;
291 
292     baseAddress = (RmPhysAddr)(osPciReadDword(pCl->FHBAddr.handle,
293                                               INTEL_29XX_CONFIG_SPACE_BASE));
294 
295     //
296     // PCI-E v1.1 enhanced config space is aligned between 1M and 256M,
297     // depending on # of buses (see PCIE v1.1, section 7.2.2).
298     //
299     baseAddress &= ( ~ 0x000fffff);
300 
301     if (baseAddress)
302     {
303         if (clInsertPcieConfigSpaceBase(pCl, baseAddress, 0, 0, (NvU8)(PCI_MAX_BUSES - 1)) == NV_OK)
304             pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE, NV_TRUE);
305     }
306 
307     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_SKIP_MCFG_READ, NV_TRUE);
308 
309     return NV_OK;
310 }
311 
312 static NV_STATUS
313 Intel_25E0_setupFunc
314 (
315     OBJCL *pCl
316 )
317 {
318     RmPhysAddr baseAddress;
319 
320     if (!pCl->FHBAddr.valid)
321         return NV_ERR_GENERIC;
322     baseAddress = (RmPhysAddr)INTEL_25E0_CONFIG_SPACE_BASE_ADDRESS;
323 
324     if (clInsertPcieConfigSpaceBase(pCl, baseAddress, 0, 0, (NvU8)(PCI_MAX_BUSES - 1)) == NV_OK)
325         pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE, NV_TRUE);
326 
327     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_SKIP_MCFG_READ, NV_TRUE);
328 
329     return NV_OK;
330 }
331 
332 static NV_STATUS
333 Intel_27XX_setupFunc
334 (
335     OBJCL *pCl
336 )
337 {
338     RmPhysAddr baseAddress;
339 
340     if (!pCl->FHBAddr.valid)
341         return NV_ERR_GENERIC;
342     baseAddress = (RmPhysAddr)(osPciReadDword(pCl->FHBAddr.handle,
343                                               INTEL_25XX_CONFIG_SPACE_BASE));
344 
345     // PCI-E enhanced config space is 256M aligned
346     baseAddress &= ( ~ 0x0fffffff);
347 
348     if (baseAddress)
349     {
350         if (clInsertPcieConfigSpaceBase(pCl, baseAddress, 0, 0, (NvU8)(PCI_MAX_BUSES - 1)) == NV_OK)
351             pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE, NV_TRUE);
352     }
353 
354     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_SKIP_MCFG_READ, NV_TRUE);
355 
356     return NV_OK;
357 }
358 
359 static NV_STATUS
360 Intel_359E_setupFunc
361 (
362     OBJCL *pCl
363 )
364 {
365     RmPhysAddr baseAddress;
366 
367     if (!pCl->FHBAddr.valid)
368         return NV_ERR_GENERIC;
369     baseAddress = (RmPhysAddr)(osPciReadDword(pCl->FHBAddr.handle,
370                                               INTEL_359E_CONFIG_SPACE_BASE));
371 
372     // PCI-E enhanced config space is 256M aligned
373     baseAddress &= ( ~ 0x0fffffff);
374 
375     if (baseAddress)
376     {
377         if (clInsertPcieConfigSpaceBase(pCl, baseAddress, 0, 0, (NvU8)(PCI_MAX_BUSES - 1)) == NV_OK)
378             pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE, NV_TRUE);
379     }
380 
381     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_SKIP_MCFG_READ, NV_TRUE);
382 
383     return NV_OK;
384 }
385 
386 static NV_STATUS
387 Intel_4000_setupFunc
388 (
389     OBJCL *pCl
390 )
391 {
392     RmPhysAddr baseAddress;
393 
394     if (!pCl->FHBAddr.valid)
395         return NV_ERR_GENERIC;
396 
397     baseAddress = (RmPhysAddr)INTEL_4000_CONFIG_SPACE_BASE_ADDRESS;
398 
399     if (clInsertPcieConfigSpaceBase(pCl, baseAddress, 0, 0, (NvU8)(PCI_MAX_BUSES - 1)) == NV_OK)
400         pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE, NV_TRUE);
401 
402     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_SKIP_MCFG_READ, NV_TRUE);
403 
404     return NV_OK;
405 }
406 
407 static NV_STATUS
408 Intel_4003_setupFunc
409 (
410     OBJCL *pCl
411 )
412 {
413     void *pHandle;
414     NvU32 hecbase;
415     RmPhysAddr baseAddress;
416 
417     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE, NV_FALSE);
418 
419     // The Intel "SkullTrail" (aka 5400) motherboard chipset does not
420     // have a fixed PCIe enhanced config space base address. We can find
421     // it by reading bus 0, device 16, function 0, register 0x64 (HECBASE),
422     // per Intel 5400 Chipset Memory Controller Hub Datasheet.
423 
424     pHandle = osPciInitHandle(0, 0, 16, 0, NULL, NULL);
425     if (pHandle == NULL)
426         return NV_ERR_GENERIC;
427 
428     // Note: This read is on device 16, not on FHB (first host bridge).
429 
430     hecbase = osPciReadDword(pHandle, INTEL_4003_CONFIG_SPACE_BASE);
431     if (hecbase != 0xFFFFFFFF)
432     {
433         // The part we are interested in are the 12 bits [23:12],
434         // which make up bits [39:28] of the base address. So we
435         // isolate the 12 bits we need and shift into place. The
436         // high byte of the 40-bit address is shifted away.
437 
438         baseAddress = (RmPhysAddr) (hecbase & 0x00FFF000) << 16;
439 
440         if (clInsertPcieConfigSpaceBase(pCl, baseAddress, 0, 0, (NvU8)(PCI_MAX_BUSES - 1)) == NV_OK)
441             pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE, NV_TRUE);
442     }
443     else
444     {
445         NV_PRINTF(LEVEL_ERROR,
446                   "Can't read HECBASE register on Intel SkullTrail!\n");
447     }
448 
449     if (clPcieReadDword(pCl, pCl->FHBAddr.domain, pCl->FHBAddr.bus, pCl->FHBAddr.device, pCl->FHBAddr.func, 0)
450             != (NvU32)(pCl->FHBBusInfo.vendorID | pCl->FHBBusInfo.deviceID << 16))
451     {
452         pCl->pPcieConfigSpaceBase->baseAddress = INTEL_4003_CONFIG_SPACE_BASE_ADDRESS_E;
453         if (clPcieReadDword(pCl, pCl->FHBAddr.domain, pCl->FHBAddr.bus, pCl->FHBAddr.device, pCl->FHBAddr.func, 0)
454                 != (NvU32)(pCl->FHBBusInfo.vendorID | pCl->FHBBusInfo.deviceID << 16))
455         {
456             return NV_ERR_GENERIC;
457         }
458     }
459 
460     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_SKIP_MCFG_READ, NV_TRUE);
461 
462     return NV_OK;
463 }
464 
465 //
466 // the PCI extended config space BAR is a property of the CPU, not the
467 // actual chipset because Intel integrated that part of the
468 // Northbridge in the CPU.
469 // This function currently applies to processors:
470 // - i7: INTEL_QUICKPATH_SYSTEM_ADDRESS_DECODER_I7,
471 // - i5 Auburndale: INTEL_QUICKPATH_SYSTEM_ADDRESS_DECODER_I5_A,
472 // - i5 Lynnfield :INTEL_QUICKPATH_SYSTEM_ADDRESS_DECODER_I5_L.
473 //
474 
475 static NV_STATUS
476 Intel_Core_Nehalem_Processor_setupFunc
477 (
478     OBJCL *pCl
479 )
480 {
481     NvS32 bus;
482     RmPhysAddr baseAddress;
483 
484     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE, NV_FALSE);
485 
486     //
487     // Intel data sheet 320835 describes how to find the PCI extended
488     // config space BAR in a Core i7 CPU.
489     //
490     // Current link for i7:
491     // https://download.intel.com/design/processor/datashts/320835.pdf
492     // Link for i5 not found. It has been reverse engineered.
493 
494     // We need to find the pci functions, "Intel QuickPath
495     // Architecture System Address Decoder" device 0, function 1 on
496     // the CPU's PCI bus, Device ID =
497     // INTEL_QUICKPATH_SYSTEM_ADDRESS_DECODER* [section
498     // 2.3]. The bus number is the highest bus number in the PCI
499     // fabric.
500 
501     for (bus = 0xff; bus >= 0; --bus)
502     {
503         NvU16 vendorId, deviceId;
504         void *pHandle = osPciInitHandle(0, bus, 0, 1, &vendorId, &deviceId);
505         if (pHandle
506             && (vendorId == PCI_VENDOR_ID_INTEL)
507             && ((deviceId == INTEL_QUICKPATH_SYSTEM_ADDRESS_DECODER_I7) ||
508                 (deviceId == INTEL_QUICKPATH_SYSTEM_ADDRESS_DECODER_I5_A) ||
509                 (deviceId == INTEL_QUICKPATH_SYSTEM_ADDRESS_DECODER_I5_L) ||
510                 (deviceId == INTEL_QUICKPATH_SYSTEM_ADDRESS_DECODER_I5_6)))
511         {
512             // [section 2.6.5] describes how to decode the config
513             // space bar
514             const NvU32 sad_pciexbar_low  = osPciReadDword(pHandle, 0x50);
515             const NvU64 sad_pciexbar_high = osPciReadDword(pHandle, 0x54);
516 
517             const NvU64 sad_pciexbar = (sad_pciexbar_high << 32) | sad_pciexbar_low;
518             const NvU64 address      = sad_pciexbar & 0xfffff00000ULL;
519             const NvU32 size         = (sad_pciexbar_low >> 1) & 0x7;
520             const NvU32 enabled      = (sad_pciexbar_low & 1);
521 
522             // if it's disabled, then skip.
523             if (enabled == 0)
524                 continue;
525 
526             // if it's not a size we know, then skip. 0 = 256MB, 6 = 64MB, 7 =
527             // 128MB BAR size
528             if ((size != 0) && (size != 7) && (size != 6))
529                 continue;
530 
531             baseAddress = (RmPhysAddr)address;
532 
533             if (clInsertPcieConfigSpaceBase(pCl, baseAddress, 0, 0, (NvU8)(PCI_MAX_BUSES - 1)) == NV_OK)
534                 pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE, NV_TRUE);
535             break;
536         }
537     }
538 
539     return NV_OK;
540 }
541 
542 static NV_STATUS
543 Intel_3400_setupFunc
544 (
545     OBJCL *pCl
546 )
547 {
548     // Set ASPM L0S\L1 properties
549     _Set_ASPM_L0S_L1(pCl, NV_TRUE, NV_FALSE);
550 
551     return Intel_Core_Nehalem_Processor_setupFunc(pCl);
552 }
553 
554 //
555 // 3B42 is the device Id of the IBEX south bridge. It is not the device id of the host bridge.
556 // On such core i5 platforms the host bridge is in the CPU, so we cannot rely on it
557 // to detect the P55 platform.
558 //
559 static NV_STATUS
560 Intel_3B42_setupFunc
561 (
562     OBJCL *pCl
563 )
564 {
565     void *pHandle;
566     NvU16 deviceId;
567     NvU16 cpuDeviceId;
568     NvU16 cpuVId;
569 
570     // We need to find out if it is Intel H57 Chipset (based on LPC D31 F0
571     // PCI DevID 3B08h )and remove it from ASPM POR. Refer Bug 706926 for more details
572     pHandle = osPciInitHandle(0, 0, 31 , 0, NULL, &deviceId);
573 
574     if ((pHandle != NULL) && (deviceId == 0x3B08))
575     {
576        // Set PDB_PROP_CL_INTEL_CPU_ROOTPORT1_NEEDS_H57_WAR to disable L1 in CPU Root Port for H57.
577        pCl->setProperty(pCl, PDB_PROP_CL_INTEL_CPU_ROOTPORT1_NEEDS_H57_WAR, NV_TRUE);
578     }
579 
580      //
581     // Bug 782125 : [PEX ASPM] Enable GPU L0s and L1 on H55 LPC (@ D31 F0) (deviceId == 0x3B06) and
582     // H57 (deviceId == 0x3B08) with Clarkdale CPUs dev 0 func 0 (deviceId == 0x0042) for All
583     // Fermi and Later GPUs
584     //
585     if ((pHandle != NULL) && ((deviceId == 0x3B06) || (deviceId == 0x3B08)))
586     {
587         // We need to find out if CPU is Clarkdale by reading 'Register 0 of Dev 0 Func 0
588         // VID: 0x8086 and DEVID: 0x0040
589         pHandle = osPciInitHandle(0, 0, 0 , 0, &cpuVId, &cpuDeviceId);
590 
591         if ((pHandle != NULL) && (cpuVId == PCI_VENDOR_ID_INTEL) && (cpuDeviceId == 0x0040))
592         {
593             // Enable L1P and L0
594             _Set_ASPM_L0S_L1(pCl, NV_FALSE, NV_FALSE);
595         }
596     }
597 
598     return Intel_Core_Nehalem_Processor_setupFunc(pCl);
599 }
600 
601 // Intel Huron River Chipset Common Function
602 static NV_STATUS
603 Intel_Huron_River_setupFunc
604 (
605     OBJCL *pCl
606 )
607 {
608     // Enable Gen2 ASLM
609     pCl->setProperty(pCl, PDB_PROP_CL_ASLM_SUPPORTS_GEN2_LINK_UPGRADE, NV_TRUE);
610 
611     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IN_ASPM_POR_LIST, NV_TRUE);
612 
613     // Set ASPM L0S\L1 properties
614     _Set_ASPM_L0S_L1(pCl, NV_TRUE, NV_TRUE);
615 
616     // Enable L0s and L1 on mobile only
617     pCl->setProperty(pCl, PDB_PROP_CL_ASPM_L0S_CHIPSET_ENABLED_MOBILE_ONLY, NV_TRUE);
618     pCl->setProperty(pCl, PDB_PROP_CL_ASPM_L1_CHIPSET_ENABLED_MOBILE_ONLY, NV_TRUE);
619 
620     return NV_OK;
621 }
622 
623 // Intel Huron River Chipset HM67/QM67 Function - supports SLI
624 static NV_STATUS
625 Intel_1C4B_setupFunc
626 (
627     OBJCL *pCl
628 )
629 {
630     return Intel_Huron_River_setupFunc(pCl);
631 }
632 
633 // Intel Huron River Chipset HM65 Function - does not support SLI
634 static NV_STATUS
635 Intel_1C49_setupFunc
636 (
637     OBJCL *pCl
638 )
639 {
640     return Intel_Huron_River_setupFunc(pCl);
641 }
642 
643 // Intel P67 Chipset Setup Function
644 static NV_STATUS
645 Intel_1C10_setupFunc
646 (
647     OBJCL *pCl
648 )
649 {
650     return NV_OK;
651 }
652 
653 // Intel P67 Chipset Cougar-PointSetup Function - supports SLI
654 static NV_STATUS
655 Intel_1C46_setupFunc
656 (
657     OBJCL *pCl
658 )
659 {
660     return NV_OK;
661 }
662 
663 // Intel X79 Patsburg Chipset - supports SLI
664 static NV_STATUS
665 Intel_1D40_setupFunc
666 (
667     OBJCL *pCl
668 )
669 {
670     pCl->setProperty(pCl, PDB_PROP_CL_ON_PCIE_GEN3_PATSBURG, NV_TRUE);
671 
672     if (DEVICE_ID_INTEL_0E00_HOST_BRIDGE == pCl->FHBBusInfo.deviceID)
673     {
674         pCl->setProperty(pCl, PDB_PROP_CL_ALLOW_PCIE_GEN3_ON_PATSBURG_WITH_IVBE_CPU, NV_TRUE);
675     }
676 
677     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IN_ASPM_POR_LIST, NV_TRUE);
678 
679     // Set ASPM L0S\L1 properties
680     _Set_ASPM_L0S_L1(pCl, NV_TRUE, NV_TRUE);
681 
682     // Enable L0s on mobile parts only
683     pCl->setProperty(pCl, PDB_PROP_CL_ASPM_L0S_CHIPSET_ENABLED_MOBILE_ONLY, NV_TRUE);
684 
685     return NV_OK;
686 }
687 
688 // Intel X99 platform
689 static NV_STATUS
690 Intel_8D47_setupFunc
691 (
692     OBJCL *pCl
693 )
694 {
695     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IN_ASPM_POR_LIST, NV_TRUE);
696 
697     // Set ASPM L0S\L1 properties
698     _Set_ASPM_L0S_L1(pCl, NV_TRUE, NV_TRUE);
699 
700     // Enable L0s on mobile parts only
701     pCl->setProperty(pCl, PDB_PROP_CL_ASPM_L0S_CHIPSET_ENABLED_MOBILE_ONLY, NV_TRUE);
702 
703     // Disable MSCG on X99 chipset
704     pCl->setProperty(pCl, PDB_PROP_CL_BUG_1681803_WAR_DISABLE_MSCG, NV_TRUE);
705 
706     return NV_OK;
707 }
708 
709 // Intel C612 platform (X99 based)
710 static NV_STATUS
711 Intel_8D44_setupFunc
712 (
713     OBJCL *pCl
714 )
715 {
716     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IN_ASPM_POR_LIST, NV_TRUE);
717 
718     // Set ASPM L0S\L1 properties
719     _Set_ASPM_L0S_L1(pCl, NV_TRUE, NV_TRUE);
720 
721     // Enable L0s on mobile parts only
722     pCl->setProperty(pCl, PDB_PROP_CL_ASPM_L0S_CHIPSET_ENABLED_MOBILE_ONLY, NV_TRUE);
723 
724     return NV_OK;
725 }
726 
727 // Intel Z75 Ivy Bridge CPU - supports SLI
728 static NV_STATUS
729 Intel_1E10_setupFunc
730 (
731     OBJCL *pCl
732 )
733 {
734     // Set ASPM L0S\L1 properties
735     _Set_ASPM_L0S_L1(pCl, NV_FALSE, NV_FALSE);
736 
737     // Set PDB to disable Gen3 on GIGABYTE Sniper 3 motherboard. Bug 1340801.
738     if (pCl->chipsetIDInfo.subvendorID == NV_PCI_SUBID_VENDOR_GIGABYTE)
739     {
740         switch(pCl->chipsetIDInfo.subdeviceID)
741         {
742             case GIGABYTE_SNIPER_3_SSDEVID_1:
743             case GIGABYTE_SNIPER_3_SSDEVID_2:
744                 pCl->setProperty(pCl, PDB_PROP_CL_BUG_1340801_DISABLE_GEN3_ON_GIGABYTE_SNIPER_3, NV_TRUE);
745                 break;
746             default:
747                 break;
748         }
749     }
750 
751     return NV_OK;
752 }
753 
754 // Intel SharkBay (Haswell) - Lynx Point platform
755 static NV_STATUS
756 Intel_8C4B_setupFunc
757 (
758     OBJCL *pCl
759 )
760 {
761 
762     // Set ASPM L0S\L1 properties
763     _Set_ASPM_L0S_L1(pCl, NV_TRUE, NV_FALSE);
764 
765     // Enable L0s on mobile only
766     pCl->setProperty(pCl, PDB_PROP_CL_ASPM_L0S_CHIPSET_ENABLED_MOBILE_ONLY, NV_TRUE);
767 
768     return NV_OK;
769 }
770 
771 // Intel Z97 platform
772 static NV_STATUS
773 Intel_8CC4_setupFunc
774 (
775     OBJCL *pCl
776 )
777 {
778     return NV_OK;
779 }
780 
781 // Intel Z170 platform
782 static NV_STATUS
783 Intel_A145_setupFunc
784 (
785     OBJCL *pCl
786 )
787 {
788     return NV_OK;
789 }
790 
791 // Intel Z270 platform
792 static NV_STATUS
793 Intel_A2C5_setupFunc
794 (
795     OBJCL *pCl
796 )
797 {
798     return NV_OK;
799 }
800 
801 // Intel C62x/C422 platform
802 static NV_STATUS
803 Intel_A242_setupFunc
804 (
805     OBJCL *pCl
806 )
807 {
808     return NV_OK;
809 }
810 
811 // IntelX299 platform
812 static NV_STATUS
813 Intel_A2D2_setupFunc
814 (
815     OBJCL *pCl
816 )
817 {
818     return NV_OK;
819 }
820 
821 // Intel Z370 platform
822 static NV_STATUS
823 Intel_A2C9_setupFunc
824 (
825     OBJCL *pCl
826 )
827 {
828     return NV_OK;
829 }
830 
831 // Intel CannonLake platform
832 static NV_STATUS
833 Intel_A301_setupFunc
834 (
835     OBJCL *pCl
836 )
837 {
838     return NV_OK;
839 }
840 
841 // Intel Comet Lake platform
842 static NV_STATUS
843 Intel_0685_setupFunc
844 (
845     OBJCL *pCl
846 )
847 {
848     return NV_OK;
849 }
850 
851 // Intel Z590 platform (Rocket Lake)
852 static NV_STATUS
853 Intel_4381_setupFunc
854 (
855     OBJCL *pCl
856 )
857 {
858     pCl->setProperty(pCl, PDB_PROP_CL_HAS_RESIZABLE_BAR_ISSUE, NV_TRUE);
859 
860     //
861     // Apply the WAR to restrict the max target gen speed capable to previous gen
862     // on ASUS Z590 (Intel RKL-S) platform only
863     // Bug 3751839
864     //
865     if (pCl->chipsetIDInfo.subvendorID == PCI_VENDOR_ID_ASUS)
866     {
867         pCl->setProperty(pCl, PDB_PROP_CL_BUG_3751839_GEN_SPEED_WAR, NV_TRUE);
868     }
869 
870     return NV_OK;
871 }
872 
873 // Intel Z690 platform (Alder Lake)
874 static NV_STATUS
875 Intel_7A82_setupFunc
876 (
877     OBJCL *pCl
878 )
879 {
880     pCl->setProperty(pCl, PDB_PROP_CL_HAS_RESIZABLE_BAR_ISSUE, NV_TRUE);
881 
882     return NV_OK;
883 }
884 
885 // Intel Z790 platform (Raptor Lake)
886 static NV_STATUS
887 Intel_7A04_setupFunc
888 (
889     OBJCL *pCl
890 )
891 {
892     pCl->setProperty(pCl, PDB_PROP_CL_HAS_RESIZABLE_BAR_ISSUE, NV_TRUE);
893 
894     return NV_OK;
895 }
896 
897 static NV_STATUS
898 Nvidia_T210_setupFunc
899 (
900     OBJCL *pCl
901 )
902 {
903     if (!pCl->FHBAddr.valid)
904         return NV_ERR_GENERIC;
905 
906     if (clInsertPcieConfigSpaceBase(pCl, 0, 0, 0, (NvU8)(PCI_MAX_BUSES - 1)) == NV_OK)
907             pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE, NV_TRUE);
908 
909     //
910     // setting this prevents trying to access the PCI MCFG table to get config information;
911     // this is part of the ACPI spec, which doesn't apply to Tegra
912     //
913     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_SKIP_MCFG_READ, NV_TRUE);
914 
915     // Enable Gen2 ASLM
916     pCl->setProperty(pCl, PDB_PROP_CL_ASLM_SUPPORTS_GEN2_LINK_UPGRADE, NV_TRUE);
917 
918     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_FALSE);
919 
920     _Set_ASPM_L0S_L1(pCl, NV_FALSE, NV_FALSE);
921     return NV_OK;
922 }
923 
924 static NV_STATUS
925 Nvidia_T194_setupFunc
926 (
927     OBJCL *pCl
928 )
929 {
930     NV_STATUS status;
931 
932     status = Nvidia_T210_setupFunc(pCl);
933     if (status != NV_OK)
934         return status;
935 
936     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
937 
938     return NV_OK;
939 }
940 
941 static NV_STATUS
942 Nvidia_TH500_setupFunc
943 (
944     OBJCL *pCl
945 )
946 {
947     if (!pCl->FHBAddr.valid)
948         return NV_ERR_GENERIC;
949 
950     if (clInsertPcieConfigSpaceBase(pCl, 0, 0, 0, (NvU8)(PCI_MAX_BUSES - 1)) == NV_OK)
951         pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE, NV_TRUE);
952 
953     // Enable Gen2 ASLM
954     pCl->setProperty(pCl, PDB_PROP_CL_ASLM_SUPPORTS_GEN2_LINK_UPGRADE, NV_TRUE);
955 
956     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
957 
958     pCl->setProperty(pCl, PDB_PROP_CL_BUG_3562968_WAR_ALLOW_PCIE_ATOMICS, NV_TRUE);
959 
960     _Set_ASPM_L0S_L1(pCl, NV_FALSE, NV_FALSE);
961 
962     return NV_OK;
963 }
964 
965 static NV_STATUS
966 SiS_656_setupFunc
967 (
968     OBJCL *pCl
969 )
970 {
971     NvU32 PcieConfigBaseReg;
972     RmPhysAddr baseAddress;
973 
974     if (!pCl->FHBAddr.valid)
975         return NV_ERR_GENERIC;
976 
977     PcieConfigBaseReg = osPciReadDword(pCl->FHBAddr.handle,
978             SIS_656_CONFIG_SPACE_BASE);
979 
980     baseAddress = (RmPhysAddr)(REF_VAL(SIS_656_CONFIG_SPACE_BASE_ADDRESS, PcieConfigBaseReg ));
981 
982     if (baseAddress)
983     {
984         baseAddress <<= 28;
985         if (clInsertPcieConfigSpaceBase(pCl, baseAddress, 0, 0, (NvU8)(PCI_MAX_BUSES - 1)) == NV_OK)
986             pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE, NV_TRUE);
987     }
988 
989     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_SKIP_MCFG_READ, NV_TRUE);
990 
991     return NV_OK;
992 }
993 
994 static NV_STATUS
995 ATI_RS400_setupFunc
996 (
997     OBJCL *pCl
998 )
999 {
1000     NvU32 nbcfg;
1001 
1002     if (!pCl->FHBAddr.valid)
1003         return NV_ERR_GENERIC;
1004 
1005     // Distinguish chipset revisions. A21 and earlier have PCI-E issues
1006     // that require special treatment.
1007     nbcfg = osPciReadDword(pCl->FHBAddr.handle, 0x9c);
1008     if (nbcfg & 1)
1009         pCl->Chipset = CS_ATI_RS400;
1010     else
1011         pCl->Chipset = CS_ATI_RS400_A21;
1012 
1013     return NV_OK;
1014 }
1015 
1016 static NV_STATUS
1017 ATI_RS480_setupFunc
1018 (
1019     OBJCL *pCl
1020 )
1021 {
1022     NvU32 rev;
1023 
1024     if (!pCl->FHBAddr.valid)
1025         return NV_ERR_GENERIC;
1026 
1027     // Distinguish chipset revisions. A21 and earlier have PCI-E issues
1028     // that require special treatment.
1029     rev = osPciReadDword(pCl->FHBAddr.handle, 0x08);
1030     if (rev & 0xff)
1031         pCl->Chipset = CS_ATI_RS480;
1032     else
1033         pCl->Chipset = CS_ATI_RS480_A21;
1034 
1035     return NV_OK;
1036 }
1037 
1038 //
1039 // AMD RS 780 and GX790
1040 //
1041 NV_STATUS
1042 AMD_RS780_setupFunc(OBJCL *pCl)
1043 {
1044     if (!pCl->FHBAddr.valid)
1045         return NV_ERR_GENERIC;
1046 
1047     _Set_ASPM_L0S_L1(pCl, NV_FALSE, NV_TRUE);
1048     return NV_OK;
1049 }
1050 
1051 //
1052 // AMD FX 790
1053 //
1054 NV_STATUS
1055 AMD_FX790_setupFunc(OBJCL *pCl)
1056 {
1057     if (!pCl->FHBAddr.valid)
1058         return NV_ERR_GENERIC;
1059 
1060     _Set_ASPM_L0S_L1(pCl, NV_TRUE, NV_FALSE);
1061     return NV_OK;
1062 }
1063 
1064 NV_STATUS ATI_RD870_setupFunc(OBJCL *pCl)
1065 {
1066     return NV_OK;
1067 }
1068 
1069 NV_STATUS ATI_RD890_setupFunc(OBJCL *pCl)
1070 {
1071     pCl->setProperty(pCl, PDB_PROP_CL_RELAXED_ORDERING_NOT_CAPABLE, NV_TRUE);
1072     return NV_OK;
1073 }
1074 
1075 NV_STATUS ATI_RX780_setupFunc(OBJCL *pCl)
1076 {
1077     pCl->setProperty(pCl, PDB_PROP_CL_RELAXED_ORDERING_NOT_CAPABLE, NV_TRUE);
1078     return NV_OK;
1079 }
1080 
1081 // AMD FX890 and AMD GX890 Chipset Setup Function
1082 static NV_STATUS
1083 AMD_FX890_setupFunc
1084 (
1085     OBJCL *pCl
1086 )
1087 {
1088    // Set ASPM L0S\L1 properties
1089     _Set_ASPM_L0S_L1(pCl, NV_FALSE, NV_FALSE);
1090 
1091    return NV_OK;
1092 }
1093 
1094 // AMD FX990 and AMD X990 Chipset Setup Function
1095 static NV_STATUS
1096 ATI_FX990_setupFunc
1097 (
1098     OBJCL *pCl
1099 )
1100 {
1101     pCl->setProperty(pCl, PDB_PROP_CL_BUG_999673_P2P_ARBITRARY_SPLIT_WAR, NV_TRUE);
1102 
1103    // Set ASPM L0S\L1 properties
1104     _Set_ASPM_L0S_L1(pCl, NV_FALSE, NV_FALSE);
1105 
1106     return NV_OK;
1107 }
1108 
1109 
1110 // AMD X370 Chipset Setup Function
1111 static NV_STATUS
1112 AMD_X370_setupFunc
1113 (
1114     OBJCL *pCl
1115 )
1116 {
1117 
1118     // Set ASPM L0S\L1 properties
1119     _Set_ASPM_L0S_L1(pCl, NV_FALSE, NV_FALSE);
1120 
1121     return NV_OK;
1122 }
1123 
1124 // VIA VX900 Chipset Setup Function
1125 static NV_STATUS
1126 VIA_VX900_setupFunc
1127 (
1128     OBJCL *pCl
1129 )
1130 {
1131     // This chipset is not capable of Gen1/Gen2 switch.
1132     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_GEN1_GEN2_SWITCH_CHIPSET_DISABLED, NV_TRUE);
1133 
1134    return NV_OK;
1135 }
1136 
1137 // AppliedMicro XGene Storm Setup Function
1138 static NV_STATUS
1139 APM_Storm_setupFunc
1140 (
1141     OBJCL *pCl
1142 )
1143 {
1144     // This chipset has trouble with multiple traffic classes
1145     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_NON_COHERENT_USE_TC0_ONLY, NV_TRUE);
1146 
1147     return NV_OK;
1148 }
1149 
1150 // Generic ARMV8 setup function
1151 static NV_STATUS
1152 ARMV8_generic_setupFunc
1153 (
1154     OBJCL *pCl
1155 )
1156 {
1157     return NV_OK;
1158 }
1159 
1160 // Marvell ThunderX2 Setup Function
1161 static NV_STATUS
1162 Marvell_ThunderX2_setupFunc
1163 (
1164     OBJCL *pCl
1165 )
1166 {
1167     // TODO Need to check if any more PDB properties should be set
1168     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
1169     return NV_OK;
1170 }
1171 
1172 // QEMU Setup Function
1173 static NV_STATUS
1174 QEMU_setupFunc
1175 (
1176     OBJCL *pCl
1177 )
1178 {
1179     //
1180     // TODO Need to check if any more PDB properties should be set and
1181     // use ACPI tables to determine whether system is I/O coherent,
1182     // instead of hard coding.
1183     //
1184     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
1185     return NV_OK;
1186 }
1187 
1188 // Ampere eMag Setup Function
1189 static NV_STATUS
1190 Ampere_eMag_setupFunc
1191 (
1192     OBJCL *pCl
1193 )
1194 {
1195     // TODO Need to check if any more PDB properties should be set
1196     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
1197     return NV_OK;
1198 }
1199 
1200 // Huawei Kunpeng Setup Function
1201 static NV_STATUS
1202 Huawei_Kunpeng920_setupFunc
1203 (
1204     OBJCL *pCl
1205 )
1206 {
1207     //
1208     // TODO Need to check if any more PDB properties should be set and
1209     // use ACPI tables to determine whether system is I/O coherent,
1210     // instead of hard coding.
1211     //
1212     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
1213     return NV_OK;
1214 }
1215 
1216 // Mellanox BlueField Setup Function
1217 static NV_STATUS
1218 Mellanox_BlueField_setupFunc
1219 (
1220     OBJCL *pCl
1221 )
1222 {
1223     // TODO Need to check if any more PDB properties should be set
1224     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
1225     return NV_OK;
1226 }
1227 
1228 // Mellanox BlueField3 Setup Function
1229 static NV_STATUS
1230 Mellanox_BlueField3_setupFunc
1231 (
1232     OBJCL *pCl
1233 )
1234 {
1235     // Bug 4151565: BlueField 3 does not support WC mapping
1236     pCl->setProperty(pCl, PDB_PROP_CL_DISABLE_IOMAP_WC, NV_TRUE);
1237     return NV_OK;
1238 }
1239 
1240 
1241 // Amazon Gravitron2 Setup Function
1242 static NV_STATUS
1243 Amazon_Gravitron2_setupFunc
1244 (
1245     OBJCL *pCl
1246 )
1247 {
1248     // TODO Need to check if any more PDB properties should be set
1249     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
1250     return NV_OK;
1251 }
1252 
1253 // Fujitsu A64FX Setup Function
1254 static NV_STATUS
1255 Fujitsu_A64FX_setupFunc
1256 (
1257     OBJCL *pCl
1258 )
1259 {
1260     // TODO Need to check if any more PDB properties should be set
1261     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
1262     return NV_OK;
1263 }
1264 
1265 // Ampere Quicksilver Setup Function
1266 static NV_STATUS
1267 Ampere_Altra_setupFunc
1268 (
1269     OBJCL *pCl
1270 )
1271 {
1272     // TODO Need to check if any more PDB properties should be set
1273     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
1274 
1275     // WAR bug 2915474: Ampere Altra rev0 does not correctly handle UC/WC iomaps.
1276     if (pCl->pBusTopologyInfo->busInfo.revisionID == 0x0)
1277     {
1278         pCl->setProperty(pCl, PDB_PROP_CL_DISABLE_IOMAP_WC, NV_TRUE);
1279     }
1280 
1281     return NV_OK;
1282 }
1283 
1284 static NV_STATUS
1285 Arm_NeoverseN1_setupFunc
1286 (
1287     OBJCL *pCl
1288 )
1289 {
1290     // TODO Need to check if any more PDB properties should be set
1291     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
1292     return NV_OK;
1293 }
1294 
1295 void
1296 csGetInfoStrings
1297 (
1298     OBJCL *pCl,
1299     NvU8 *pChipsetNameStr,
1300     NvU8 *pVendorNameStr,
1301     NvU8 *pSliBondNameStr,
1302     NvU8 *pSubSysVendorNameStr,
1303     NvU32 nameStrLen
1304 )
1305 {
1306     NvU32 i;
1307     const char* pszUnknown = "Unknown";
1308     NvU32 szUnknownLen = portStringLength(pszUnknown) + 1;
1309 
1310     if (!pCl->chipsetIDBusAddr.valid)
1311     {
1312         portStringCopy((char *) pChipsetNameStr, szUnknownLen,
1313                        pszUnknown, szUnknownLen);
1314         portStringCopy((char *) pVendorNameStr, szUnknownLen,
1315                        pszUnknown, szUnknownLen);
1316         portStringCopy((char *) pSliBondNameStr, szUnknownLen,
1317                        pszUnknown, szUnknownLen);
1318         portStringCopy((char *) pSubSysVendorNameStr, szUnknownLen,
1319                        pszUnknown, szUnknownLen);
1320         return ;
1321     }
1322 
1323     for (i = 0; chipsetInfo[i].chipset; i++)
1324     {
1325         if ((pCl->chipsetIDInfo.vendorID == chipsetInfo[i].vendorID) &&
1326              (pCl->chipsetIDInfo.deviceID == chipsetInfo[i].deviceID))
1327         {
1328             portStringCopy((char*)pChipsetNameStr,
1329                             nameStrLen,
1330                             chipsetInfo[i].name,
1331                             nameStrLen);
1332             break;
1333         }
1334     }
1335     if (!chipsetInfo[i].chipset)
1336     {
1337         portStringCopy((char *) pChipsetNameStr, szUnknownLen,
1338                        pszUnknown, szUnknownLen);
1339     }
1340 
1341     for (i = 0; vendorName[i].vendorID; i++)
1342     {
1343         if (pCl->chipsetIDInfo.vendorID == vendorName[i].vendorID)
1344         {
1345             portStringCopy((char*)pVendorNameStr,
1346                             nameStrLen,
1347                             vendorName[i].name,
1348                             nameStrLen);
1349             break;
1350         }
1351     }
1352     if (!vendorName[i].vendorID)
1353     {
1354         portStringCopy((char *) pVendorNameStr, szUnknownLen,
1355                        pszUnknown, szUnknownLen);
1356     }
1357 
1358     for (i = 0; vendorName[i].vendorID; i++)
1359     {
1360         if (pCl->chipsetIDInfo.subvendorID == vendorName[i].vendorID)
1361         {
1362             portStringCopy((char*)pSubSysVendorNameStr,
1363                             nameStrLen,
1364                             vendorName[i].name,
1365                             nameStrLen);
1366             break;
1367         }
1368     }
1369     if (!vendorName[i].vendorID)
1370     {
1371         portStringCopy((char *)pSubSysVendorNameStr, szUnknownLen,
1372                        pszUnknown, szUnknownLen);
1373     }
1374 
1375     {
1376         portStringCopy((char *)pSliBondNameStr, szUnknownLen,
1377                        pszUnknown, szUnknownLen);
1378     }
1379 }
1380 
1381 //
1382 // This function sets the pdb properties to disable ASPM L0S\L1
1383 //
1384 void
1385 _Set_ASPM_L0S_L1
1386 (
1387     OBJCL         *pCl,
1388     NvBool         bDisableL0S,
1389     NvBool         bDisableL1
1390 )
1391 {
1392     //
1393     // this chipset is part of exception list to enable/disable L0S/L1
1394     // (refer bug 529308)
1395     //
1396     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IN_ASPM_POR_LIST, NV_TRUE);
1397 
1398     if (bDisableL0S)
1399     {
1400         // Not capable of ASPM-L0s
1401         pCl->setProperty(pCl, PDB_PROP_CL_ASPM_L0S_CHIPSET_DISABLED, NV_TRUE);
1402     }
1403     if (bDisableL1)
1404     {
1405         // Not capable of ASPM L1
1406         pCl->setProperty(pCl, PDB_PROP_CL_ASPM_L1_CHIPSET_DISABLED, NV_TRUE);
1407     }
1408 }
1409 
1410