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     switch (pCl->FHBBusInfo.deviceID)
762     {
763         case DEVICE_ID_INTEL_0C00_HASWELL_HOST_BRIDGE:
764         case DEVICE_ID_INTEL_0C04_HASWELL_HOST_BRIDGE:
765             pCl->setProperty(pCl, PDB_PROP_CL_ON_HASWELL_HOST_BRIDGE, NV_TRUE);
766             break;
767         default:
768             break;
769     }
770 
771     // Set ASPM L0S\L1 properties
772     _Set_ASPM_L0S_L1(pCl, NV_TRUE, NV_FALSE);
773 
774     // Enable L0s on mobile only
775     pCl->setProperty(pCl, PDB_PROP_CL_ASPM_L0S_CHIPSET_ENABLED_MOBILE_ONLY, NV_TRUE);
776 
777     return NV_OK;
778 }
779 
780 // Intel Z97 platform
781 static NV_STATUS
782 Intel_8CC4_setupFunc
783 (
784     OBJCL *pCl
785 )
786 {
787     return NV_OK;
788 }
789 
790 // Intel Z170 platform
791 static NV_STATUS
792 Intel_A145_setupFunc
793 (
794     OBJCL *pCl
795 )
796 {
797     return NV_OK;
798 }
799 
800 // Intel Z270 platform
801 static NV_STATUS
802 Intel_A2C5_setupFunc
803 (
804     OBJCL *pCl
805 )
806 {
807     return NV_OK;
808 }
809 
810 // Intel C62x/C422 platform
811 static NV_STATUS
812 Intel_A242_setupFunc
813 (
814     OBJCL *pCl
815 )
816 {
817     return NV_OK;
818 }
819 
820 // IntelX299 platform
821 static NV_STATUS
822 Intel_A2D2_setupFunc
823 (
824     OBJCL *pCl
825 )
826 {
827     return NV_OK;
828 }
829 
830 // Intel Z370 platform
831 static NV_STATUS
832 Intel_A2C9_setupFunc
833 (
834     OBJCL *pCl
835 )
836 {
837     return NV_OK;
838 }
839 
840 // Intel CannonLake platform
841 static NV_STATUS
842 Intel_A301_setupFunc
843 (
844     OBJCL *pCl
845 )
846 {
847     return NV_OK;
848 }
849 
850 // Intel Comet Lake platform
851 static NV_STATUS
852 Intel_0685_setupFunc
853 (
854     OBJCL *pCl
855 )
856 {
857     return NV_OK;
858 }
859 
860 // Intel Z590 platform (Rocket Lake)
861 static NV_STATUS
862 Intel_4381_setupFunc
863 (
864     OBJCL *pCl
865 )
866 {
867     pCl->setProperty(pCl, PDB_PROP_CL_HAS_RESIZABLE_BAR_ISSUE, NV_TRUE);
868 
869     //
870     // Apply the WAR to restrict the max target gen speed capable to previous gen
871     // on ASUS Z590 (Intel RKL-S) platform only
872     // Bug 3751839
873     //
874     if (pCl->chipsetIDInfo.subvendorID == PCI_VENDOR_ID_ASUS)
875     {
876         pCl->setProperty(pCl, PDB_PROP_CL_BUG_3751839_GEN_SPEED_WAR, NV_TRUE);
877     }
878 
879     return NV_OK;
880 }
881 
882 // Intel Z690 platform (Alder Lake)
883 static NV_STATUS
884 Intel_7A82_setupFunc
885 (
886     OBJCL *pCl
887 )
888 {
889     pCl->setProperty(pCl, PDB_PROP_CL_HAS_RESIZABLE_BAR_ISSUE, NV_TRUE);
890 
891     return NV_OK;
892 }
893 
894 // Intel Z790 platform (Raptor Lake)
895 static NV_STATUS
896 Intel_7A04_setupFunc
897 (
898     OBJCL *pCl
899 )
900 {
901     pCl->setProperty(pCl, PDB_PROP_CL_HAS_RESIZABLE_BAR_ISSUE, NV_TRUE);
902 
903     return NV_OK;
904 }
905 
906 static NV_STATUS
907 Nvidia_T210_setupFunc
908 (
909     OBJCL *pCl
910 )
911 {
912     if (!pCl->FHBAddr.valid)
913         return NV_ERR_GENERIC;
914 
915     if (clInsertPcieConfigSpaceBase(pCl, 0, 0, 0, (NvU8)(PCI_MAX_BUSES - 1)) == NV_OK)
916             pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE, NV_TRUE);
917 
918     //
919     // setting this prevents trying to access the PCI MCFG table to get config information;
920     // this is part of the ACPI spec, which doesn't apply to Tegra
921     //
922     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_SKIP_MCFG_READ, NV_TRUE);
923 
924     // Enable Gen2 ASLM
925     pCl->setProperty(pCl, PDB_PROP_CL_ASLM_SUPPORTS_GEN2_LINK_UPGRADE, NV_TRUE);
926 
927     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_FALSE);
928 
929     _Set_ASPM_L0S_L1(pCl, NV_FALSE, NV_FALSE);
930     return NV_OK;
931 }
932 
933 static NV_STATUS
934 Nvidia_T194_setupFunc
935 (
936     OBJCL *pCl
937 )
938 {
939     NV_STATUS status;
940 
941     status = Nvidia_T210_setupFunc(pCl);
942     if (status != NV_OK)
943         return status;
944 
945     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
946 
947     return NV_OK;
948 }
949 
950 static NV_STATUS
951 Nvidia_TH500_setupFunc
952 (
953     OBJCL *pCl
954 )
955 {
956     if (!pCl->FHBAddr.valid)
957         return NV_ERR_GENERIC;
958 
959     if (clInsertPcieConfigSpaceBase(pCl, 0, 0, 0, (NvU8)(PCI_MAX_BUSES - 1)) == NV_OK)
960         pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE, NV_TRUE);
961 
962     // Enable Gen2 ASLM
963     pCl->setProperty(pCl, PDB_PROP_CL_ASLM_SUPPORTS_GEN2_LINK_UPGRADE, NV_TRUE);
964 
965     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
966 
967     pCl->setProperty(pCl, PDB_PROP_CL_BUG_3562968_WAR_ALLOW_PCIE_ATOMICS, NV_TRUE);
968 
969     _Set_ASPM_L0S_L1(pCl, NV_FALSE, NV_FALSE);
970 
971     return NV_OK;
972 }
973 
974 static NV_STATUS
975 SiS_656_setupFunc
976 (
977     OBJCL *pCl
978 )
979 {
980     NvU32 PcieConfigBaseReg;
981     RmPhysAddr baseAddress;
982 
983     if (!pCl->FHBAddr.valid)
984         return NV_ERR_GENERIC;
985 
986     PcieConfigBaseReg = osPciReadDword(pCl->FHBAddr.handle,
987             SIS_656_CONFIG_SPACE_BASE);
988 
989     baseAddress = (RmPhysAddr)(REF_VAL(SIS_656_CONFIG_SPACE_BASE_ADDRESS, PcieConfigBaseReg ));
990 
991     if (baseAddress)
992     {
993         baseAddress <<= 28;
994         if (clInsertPcieConfigSpaceBase(pCl, baseAddress, 0, 0, (NvU8)(PCI_MAX_BUSES - 1)) == NV_OK)
995             pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE, NV_TRUE);
996     }
997 
998     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_CONFIG_SKIP_MCFG_READ, NV_TRUE);
999 
1000     return NV_OK;
1001 }
1002 
1003 static NV_STATUS
1004 ATI_RS400_setupFunc
1005 (
1006     OBJCL *pCl
1007 )
1008 {
1009     NvU32 nbcfg;
1010 
1011     if (!pCl->FHBAddr.valid)
1012         return NV_ERR_GENERIC;
1013 
1014     // Distinguish chipset revisions. A21 and earlier have PCI-E issues
1015     // that require special treatment.
1016     nbcfg = osPciReadDword(pCl->FHBAddr.handle, 0x9c);
1017     if (nbcfg & 1)
1018         pCl->Chipset = CS_ATI_RS400;
1019     else
1020         pCl->Chipset = CS_ATI_RS400_A21;
1021 
1022     return NV_OK;
1023 }
1024 
1025 static NV_STATUS
1026 ATI_RS480_setupFunc
1027 (
1028     OBJCL *pCl
1029 )
1030 {
1031     NvU32 rev;
1032 
1033     if (!pCl->FHBAddr.valid)
1034         return NV_ERR_GENERIC;
1035 
1036     // Distinguish chipset revisions. A21 and earlier have PCI-E issues
1037     // that require special treatment.
1038     rev = osPciReadDword(pCl->FHBAddr.handle, 0x08);
1039     if (rev & 0xff)
1040         pCl->Chipset = CS_ATI_RS480;
1041     else
1042         pCl->Chipset = CS_ATI_RS480_A21;
1043 
1044     return NV_OK;
1045 }
1046 
1047 //
1048 // AMD RS 780 and GX790
1049 //
1050 NV_STATUS
1051 AMD_RS780_setupFunc(OBJCL *pCl)
1052 {
1053     if (!pCl->FHBAddr.valid)
1054         return NV_ERR_GENERIC;
1055 
1056     _Set_ASPM_L0S_L1(pCl, NV_FALSE, NV_TRUE);
1057     return NV_OK;
1058 }
1059 
1060 //
1061 // AMD FX 790
1062 //
1063 NV_STATUS
1064 AMD_FX790_setupFunc(OBJCL *pCl)
1065 {
1066     if (!pCl->FHBAddr.valid)
1067         return NV_ERR_GENERIC;
1068 
1069     _Set_ASPM_L0S_L1(pCl, NV_TRUE, NV_FALSE);
1070     return NV_OK;
1071 }
1072 
1073 NV_STATUS ATI_RD870_setupFunc(OBJCL *pCl)
1074 {
1075     return NV_OK;
1076 }
1077 
1078 NV_STATUS ATI_RD890_setupFunc(OBJCL *pCl)
1079 {
1080     pCl->setProperty(pCl, PDB_PROP_CL_RELAXED_ORDERING_NOT_CAPABLE, NV_TRUE);
1081     return NV_OK;
1082 }
1083 
1084 NV_STATUS ATI_RX780_setupFunc(OBJCL *pCl)
1085 {
1086     pCl->setProperty(pCl, PDB_PROP_CL_RELAXED_ORDERING_NOT_CAPABLE, NV_TRUE);
1087     return NV_OK;
1088 }
1089 
1090 // AMD FX890 and AMD GX890 Chipset Setup Function
1091 static NV_STATUS
1092 AMD_FX890_setupFunc
1093 (
1094     OBJCL *pCl
1095 )
1096 {
1097    // Set ASPM L0S\L1 properties
1098     _Set_ASPM_L0S_L1(pCl, NV_FALSE, NV_FALSE);
1099 
1100    return NV_OK;
1101 }
1102 
1103 // AMD FX990 and AMD X990 Chipset Setup Function
1104 static NV_STATUS
1105 ATI_FX990_setupFunc
1106 (
1107     OBJCL *pCl
1108 )
1109 {
1110     pCl->setProperty(pCl, PDB_PROP_CL_BUG_999673_P2P_ARBITRARY_SPLIT_WAR, NV_TRUE);
1111 
1112    // Set ASPM L0S\L1 properties
1113     _Set_ASPM_L0S_L1(pCl, NV_FALSE, NV_FALSE);
1114 
1115     return NV_OK;
1116 }
1117 
1118 
1119 // AMD X370 Chipset Setup Function
1120 static NV_STATUS
1121 AMD_X370_setupFunc
1122 (
1123     OBJCL *pCl
1124 )
1125 {
1126 
1127     // Set ASPM L0S\L1 properties
1128     _Set_ASPM_L0S_L1(pCl, NV_FALSE, NV_FALSE);
1129 
1130     return NV_OK;
1131 }
1132 
1133 // VIA VX900 Chipset Setup Function
1134 static NV_STATUS
1135 VIA_VX900_setupFunc
1136 (
1137     OBJCL *pCl
1138 )
1139 {
1140     // This chipset is not capable of Gen1/Gen2 switch.
1141     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_GEN1_GEN2_SWITCH_CHIPSET_DISABLED, NV_TRUE);
1142 
1143    return NV_OK;
1144 }
1145 
1146 // AppliedMicro XGene Storm Setup Function
1147 static NV_STATUS
1148 APM_Storm_setupFunc
1149 (
1150     OBJCL *pCl
1151 )
1152 {
1153     // This chipset has trouble with multiple traffic classes
1154     pCl->setProperty(pCl, PDB_PROP_CL_PCIE_NON_COHERENT_USE_TC0_ONLY, NV_TRUE);
1155 
1156     return NV_OK;
1157 }
1158 
1159 // Generic ARMV8 setup function
1160 static NV_STATUS
1161 ARMV8_generic_setupFunc
1162 (
1163     OBJCL *pCl
1164 )
1165 {
1166     return NV_OK;
1167 }
1168 
1169 // Marvell ThunderX2 Setup Function
1170 static NV_STATUS
1171 Marvell_ThunderX2_setupFunc
1172 (
1173     OBJCL *pCl
1174 )
1175 {
1176     // TODO Need to check if any more PDB properties should be set
1177     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
1178     return NV_OK;
1179 }
1180 
1181 // QEMU Setup Function
1182 static NV_STATUS
1183 QEMU_setupFunc
1184 (
1185     OBJCL *pCl
1186 )
1187 {
1188     //
1189     // TODO Need to check if any more PDB properties should be set and
1190     // use ACPI tables to determine whether system is I/O coherent,
1191     // instead of hard coding.
1192     //
1193     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
1194     return NV_OK;
1195 }
1196 
1197 // Ampere eMag Setup Function
1198 static NV_STATUS
1199 Ampere_eMag_setupFunc
1200 (
1201     OBJCL *pCl
1202 )
1203 {
1204     // TODO Need to check if any more PDB properties should be set
1205     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
1206     return NV_OK;
1207 }
1208 
1209 // Huawei Kunpeng Setup Function
1210 static NV_STATUS
1211 Huawei_Kunpeng920_setupFunc
1212 (
1213     OBJCL *pCl
1214 )
1215 {
1216     //
1217     // TODO Need to check if any more PDB properties should be set and
1218     // use ACPI tables to determine whether system is I/O coherent,
1219     // instead of hard coding.
1220     //
1221     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
1222     return NV_OK;
1223 }
1224 
1225 // Mellanox BlueField Setup Function
1226 static NV_STATUS
1227 Mellanox_BlueField_setupFunc
1228 (
1229     OBJCL *pCl
1230 )
1231 {
1232     // TODO Need to check if any more PDB properties should be set
1233     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
1234     return NV_OK;
1235 }
1236 
1237 // Mellanox BlueField3 Setup Function
1238 static NV_STATUS
1239 Mellanox_BlueField3_setupFunc
1240 (
1241     OBJCL *pCl
1242 )
1243 {
1244     // Bug 4151565: BlueField 3 does not support WC mapping
1245     pCl->setProperty(pCl, PDB_PROP_CL_DISABLE_IOMAP_WC, NV_TRUE);
1246     return NV_OK;
1247 }
1248 
1249 
1250 // Amazon Gravitron2 Setup Function
1251 static NV_STATUS
1252 Amazon_Gravitron2_setupFunc
1253 (
1254     OBJCL *pCl
1255 )
1256 {
1257     // TODO Need to check if any more PDB properties should be set
1258     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
1259     return NV_OK;
1260 }
1261 
1262 // Fujitsu A64FX Setup Function
1263 static NV_STATUS
1264 Fujitsu_A64FX_setupFunc
1265 (
1266     OBJCL *pCl
1267 )
1268 {
1269     // TODO Need to check if any more PDB properties should be set
1270     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
1271     return NV_OK;
1272 }
1273 
1274 // Ampere Quicksilver Setup Function
1275 static NV_STATUS
1276 Ampere_Altra_setupFunc
1277 (
1278     OBJCL *pCl
1279 )
1280 {
1281     // TODO Need to check if any more PDB properties should be set
1282     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
1283 
1284     // WAR bug 2915474: Ampere Altra rev0 does not correctly handle UC/WC iomaps.
1285     if (pCl->pBusTopologyInfo->busInfo.revisionID == 0x0)
1286     {
1287         pCl->setProperty(pCl, PDB_PROP_CL_DISABLE_IOMAP_WC, NV_TRUE);
1288     }
1289 
1290     return NV_OK;
1291 }
1292 
1293 static NV_STATUS
1294 Arm_NeoverseN1_setupFunc
1295 (
1296     OBJCL *pCl
1297 )
1298 {
1299     // TODO Need to check if any more PDB properties should be set
1300     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE);
1301     return NV_OK;
1302 }
1303 
1304 void
1305 csGetInfoStrings
1306 (
1307     OBJCL *pCl,
1308     NvU8 *pChipsetNameStr,
1309     NvU8 *pVendorNameStr,
1310     NvU8 *pSliBondNameStr,
1311     NvU8 *pSubSysVendorNameStr,
1312     NvU32 nameStrLen
1313 )
1314 {
1315     NvU32 i;
1316     const char* pszUnknown = "Unknown";
1317     NvU32 szUnknownLen = portStringLength(pszUnknown);
1318 
1319     if (!pCl->chipsetIDBusAddr.valid)
1320     {
1321         portStringCopy((char *) pChipsetNameStr, szUnknownLen,
1322                        pszUnknown, szUnknownLen);
1323         portStringCopy((char *) pVendorNameStr, szUnknownLen,
1324                        pszUnknown, szUnknownLen);
1325         portStringCopy((char *) pSliBondNameStr, szUnknownLen,
1326                        pszUnknown, szUnknownLen);
1327         portStringCopy((char *) pSubSysVendorNameStr, szUnknownLen,
1328                        pszUnknown, szUnknownLen);
1329         return ;
1330     }
1331 
1332     for (i = 0; chipsetInfo[i].chipset; i++)
1333     {
1334         if ((pCl->chipsetIDInfo.vendorID == chipsetInfo[i].vendorID) &&
1335              (pCl->chipsetIDInfo.deviceID == chipsetInfo[i].deviceID))
1336         {
1337             portStringCopy((char*)pChipsetNameStr,
1338                             nameStrLen,
1339                             chipsetInfo[i].name,
1340                             nameStrLen);
1341             break;
1342         }
1343     }
1344     if (!chipsetInfo[i].chipset)
1345     {
1346         portStringCopy((char *) pChipsetNameStr, szUnknownLen,
1347                        pszUnknown, szUnknownLen);
1348     }
1349 
1350     for (i = 0; vendorName[i].vendorID; i++)
1351     {
1352         if (pCl->chipsetIDInfo.vendorID == vendorName[i].vendorID)
1353         {
1354             portStringCopy((char*)pVendorNameStr,
1355                             nameStrLen,
1356                             vendorName[i].name,
1357                             nameStrLen);
1358             break;
1359         }
1360     }
1361     if (!vendorName[i].vendorID)
1362     {
1363         portStringCopy((char *) pVendorNameStr, szUnknownLen,
1364                        pszUnknown, szUnknownLen);
1365     }
1366 
1367     for (i = 0; vendorName[i].vendorID; i++)
1368     {
1369         if (pCl->chipsetIDInfo.subvendorID == vendorName[i].vendorID)
1370         {
1371             portStringCopy((char*)pSubSysVendorNameStr,
1372                             nameStrLen,
1373                             vendorName[i].name,
1374                             nameStrLen);
1375             break;
1376         }
1377     }
1378     if (!vendorName[i].vendorID)
1379     {
1380         portStringCopy((char *)pSubSysVendorNameStr, szUnknownLen,
1381                        pszUnknown, szUnknownLen);
1382     }
1383 
1384     {
1385         portStringCopy((char *)pSliBondNameStr, szUnknownLen,
1386                        pszUnknown, szUnknownLen);
1387     }
1388 }
1389 
1390 //
1391 // This function sets the pdb properties to disable ASPM L0S\L1
1392 //
1393 void
1394 _Set_ASPM_L0S_L1
1395 (
1396     OBJCL         *pCl,
1397     NvBool         bDisableL0S,
1398     NvBool         bDisableL1
1399 )
1400 {
1401     //
1402     // this chipset is part of exception list to enable/disable L0S/L1
1403     // (refer bug 529308)
1404     //
1405     pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IN_ASPM_POR_LIST, NV_TRUE);
1406 
1407     if (bDisableL0S)
1408     {
1409         // Not capable of ASPM-L0s
1410         pCl->setProperty(pCl, PDB_PROP_CL_ASPM_L0S_CHIPSET_DISABLED, NV_TRUE);
1411     }
1412     if (bDisableL1)
1413     {
1414         // Not capable of ASPM L1
1415         pCl->setProperty(pCl, PDB_PROP_CL_ASPM_L1_CHIPSET_DISABLED, NV_TRUE);
1416     }
1417 }
1418 
1419