1 /* 2 * SPDX-FileCopyrightText: Copyright (c) 1993-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 25 /***************************** HW State Routines ***************************\ 26 * Core Logic Object Function Definitions. * 27 \***************************************************************************/ 28 29 #include "core/system.h" 30 #include "platform/chipset/chipset.h" 31 #include "platform/platform.h" 32 #include "platform/chipset/chipset_info.h" 33 #include "os/os.h" 34 #include "nvRmReg.h" 35 #include "nvpcie.h" 36 #include "nv_ref.h" 37 #include "kernel/gpu/bif/kernel_bif.h" 38 #include "gpu_mgr/gpu_mgr.h" 39 #include "gpu/gsp/gsp_static_config.h" 40 #include "ctrl/ctrl2080/ctrl2080bus.h" 41 42 // local static funcs 43 static void clDestructHWBC(OBJHWBC *pHWBC); 44 45 NV_STATUS 46 clConstruct_IMPL(OBJCL *pCl) 47 { 48 // Used to track when the link has gone into Recovery, which can cause CEs. 49 pCl->EnteredRecoverySinceErrorsLastChecked = NV_FALSE; 50 51 pCl->pPcieConfigSpaceBase = NULL; 52 53 // 54 // We set this property by default. 55 // Chipset setup function can override this. 56 // Right now only Tegra chipsets overide this setting. 57 // 58 pCl->setProperty(pCl, PDB_PROP_CL_IS_CHIPSET_IO_COHERENT, NV_TRUE); 59 60 return NV_OK; 61 } 62 63 64 void 65 clInitPropertiesFromRegistry_IMPL(OBJGPU *pGpu, OBJCL *pCl) 66 { 67 NvU32 data32; 68 OBJSYS *pSys = SYS_GET_INSTANCE(); 69 OBJOS *pOS = SYS_GET_OS(pSys); 70 71 if (osReadRegistryDword(pGpu, NV_REG_STR_RM_DISABLE_BR03_FLOW_CONTROL, &data32) == NV_OK 72 && data32) 73 { 74 pCl->setProperty(pCl, PDB_PROP_CL_DISABLE_BR03_FLOW_CONTROL, NV_TRUE); 75 } 76 77 if (osReadRegistryDword(pGpu, NV_REG_STR_RM_FORCE_ENABLE_GEN2, &data32) == NV_OK) 78 { 79 if (NV_REG_STR_RM_FORCE_ENABLE_GEN2_YES == data32) 80 { 81 pCl->setProperty(pCl, PDB_PROP_CL_PCIE_FORCE_GEN2_ENABLE, NV_TRUE); 82 } 83 } 84 85 pOS->osQADbgRegistryInit(pOS); 86 } 87 88 static void 89 clDestructHWBC(OBJHWBC *pHWBC) 90 { 91 if (pHWBC->pSibling) 92 { 93 clDestructHWBC(pHWBC->pSibling); 94 pHWBC->pSibling = NULL; 95 } 96 if (pHWBC->pFirstChild) 97 { 98 clDestructHWBC(pHWBC->pFirstChild); 99 pHWBC->pFirstChild = NULL; 100 } 101 102 portMemFree(pHWBC); 103 } 104 105 void 106 clDestruct_IMPL(OBJCL *pCl) 107 { 108 if (pCl->pHWBC) 109 { 110 clDestructHWBC(pCl->pHWBC); 111 pCl->pHWBC = NULL; 112 } 113 114 clFreeBusTopologyCache(pCl); 115 116 clFreePcieConfigSpaceBase(pCl); 117 } 118 119 // 120 // Find our NV device on the PCI bus and save it's pci bus/device address. 121 // 122 NvU32 123 clInitMappingPciBusDevice_IMPL 124 ( 125 OBJGPU *pGpu, 126 OBJCL *pCl 127 ) 128 { 129 void *handle; 130 NvU32 domain; 131 NvU16 bus; 132 NvU8 device; 133 NvU16 vendorID, deviceID; 134 NvBool bFoundDevice = NV_FALSE; 135 136 if (IsT194(pGpu) || IsT234(pGpu)) 137 return NV0000_CTRL_GPU_INVALID_ID; 138 139 // do we already know our domain/bus/device? 140 if (gpuGetDBDF(pGpu) == 0) 141 { 142 // we're checking all the device/funcs for the first 10 buses! 143 // Note that we give up the enumeration once we find our first 144 // or in the Multichip case our second device. 145 for (domain = 0; (domain < PCI_MAX_DOMAINS) && !bFoundDevice; domain++) 146 { 147 for (bus = 0; (bus < PCI_MAX_BUSES) && !bFoundDevice; bus++) 148 { 149 for (device = 0; device < PCI_MAX_DEVICES; device++) 150 { 151 // read at domain, bus, device (we're always function 0) 152 handle = osPciInitHandle(domain, (NvU8) bus, device, 0, &vendorID, &deviceID); 153 if (!handle) 154 continue; 155 156 if (vendorID != NV_CONFIG_PCI_NV_0_VENDOR_ID_NVIDIA) 157 continue; 158 159 // make sure we're a VGA device class 160 if ((osPciReadByte(handle, 0xB)) != PCI_CLASS_DISPLAY_DEV) 161 continue; 162 163 // if the BAR0 matches our PhysAddr, it's the correct device 164 if ((osPciReadDword(handle, PCI_BASE_ADDRESS_0)) != 165 pGpu->busInfo.gpuPhysAddr) 166 continue; 167 168 // save our domain/bus/device/function 169 pGpu->busInfo.nvDomainBusDeviceFunc = gpuEncodeDomainBusDevice(domain, (NvU8)bus, device); 170 171 bFoundDevice = NV_TRUE; 172 173 if (!(IS_SIMULATION(pGpu) || IS_SIM_MODS(GPU_GET_OS(pGpu)))) 174 { 175 NV_ASSERT(gpuGetDBDF(pGpu) != 0); 176 } 177 // On the HP "Wilson's Peak"/McKinley system 178 // the graphics is located at 179 // domain==0, bus==0, device==0. 180 // Why should this be invalid? 181 // In simulation, the fmodel can put this at bus==0, device==0 182 break; 183 } 184 } 185 } 186 } 187 188 domain = gpuGetDomain(pGpu); 189 bus = gpuGetBus(pGpu); 190 device = gpuGetDevice(pGpu); 191 192 if (gpuGetDBDF(pGpu) == 0) 193 { 194 if (!(IS_SIMULATION(pGpu)|| IS_SIM_MODS(GPU_GET_OS(pGpu))) 195 || (bFoundDevice == NV_FALSE)) 196 { 197 NV_PRINTF(LEVEL_ERROR, 198 "NVRM initMappingPciBusDevice: can't find a device!\n"); 199 return NV0000_CTRL_GPU_INVALID_ID; // couldn't find it 200 } 201 } 202 203 return gpuGenerate32BitId(domain, (NvU8)bus, device); 204 } 205 206 // 207 // Walk the PCIE Capabilities and if the subsystem ID is found then return 208 // the subvendorID and subdeviceID 209 // 210 static void getSubsystemFromPCIECapabilities 211 ( 212 NvU32 domain, 213 NvU8 bus, 214 NvU8 device, 215 NvU8 func, 216 NvU16 *subvendorID, 217 NvU16 *subdeviceID 218 ) 219 { 220 void *handle; 221 NvU32 PCIECapPtr; 222 NvU32 PCIECap; 223 NvU32 PCIECapNext; 224 225 handle = osPciInitHandle(domain, bus, device, func, NULL, NULL); 226 227 // We start from Cap. List and search for Subsystem ID Capability 228 PCIECapNext = osPciReadByte(handle, PCI_CAPABILITY_LIST); 229 if (PCIECapNext) 230 { 231 do 232 { 233 PCIECapPtr = PCIECapNext; 234 PCIECap = osPciReadDword(handle, CL_PCIE_CAP - CL_PCIE_BEGIN + PCIECapPtr); 235 PCIECapNext = (NvU8)((PCIECap >> 8) & 0xFF); 236 } while ((PCIECapNext != 0) && 237 ((PCIECap & CAP_ID_MASK) != CAP_ID_SUBSYSTEM_ID)); 238 239 if ((PCIECap & CAP_ID_MASK) == CAP_ID_SUBSYSTEM_ID) 240 { 241 if (subvendorID) 242 { 243 *subvendorID = osPciReadWord(handle, CL_PCIE_CAP - CL_PCIE_BEGIN + PCIECapPtr + 4); 244 } 245 if (subdeviceID) 246 { 247 *subdeviceID = osPciReadWord(handle, CL_PCIE_CAP - CL_PCIE_BEGIN + PCIECapPtr + 6); 248 } 249 } 250 } 251 } 252 253 // 254 // PCI Express Support 255 // Find first host bridge's domain, bus, device, function, if not already found 256 // 257 258 NV_STATUS 259 clFindFHBAndGetChipsetInfoIndex_IMPL 260 ( 261 OBJCL *pCl, 262 NvU16 *pChipsetInfoIndex 263 ) 264 { 265 void *handle; 266 NvU32 domain; 267 NvU8 revisionID = 0; 268 NvU32 i; 269 NvBool matchFound = NV_FALSE; 270 NvU16 bus; 271 NvU8 device, func; 272 NvU16 vendorID, deviceID, subvendorID, subdeviceID; 273 PBUSTOPOLOGYINFO pBusTopologyInfo; 274 // 275 // PC motherboards have a host bridge to connect PCIE root complex to rest of the system. 276 // However, Tegra devices only have a PCI-to-PCI bridge. 277 // So allow Tegra chipset initialization, even if a host bridge is not found. 278 // See bug 1547160 comment#17 for more details. 279 // 280 NvU16 pciSubBaseClass[2] = {PCI_COMMON_CLASS_SUBBASECLASS_HOST, PCI_COMMON_CLASS_SUBBASECLASS_P2P}; 281 282 // return it, if we've got it already 283 if (pCl->chipsetIDBusAddr.valid) 284 return NV_OK; 285 286 // Initialize to 0 287 pCl->chipsetIDBusAddr.domain = 0x0; 288 pCl->chipsetIDBusAddr.bus = 0x0; 289 pCl->chipsetIDBusAddr.device = 0x0; 290 pCl->chipsetIDBusAddr.func = 0x0; 291 pCl->chipsetIDBusAddr.valid = 0x0; 292 pCl->chipsetIDBusAddr.handle = NULL; 293 pCl->chipsetIDInfo.deviceID = PCI_INVALID_DEVICEID; 294 pCl->chipsetIDInfo.vendorID = PCI_INVALID_VENDORID; 295 pCl->chipsetIDInfo.subdeviceID = PCI_INVALID_SUBDEVICEID; 296 pCl->chipsetIDInfo.subvendorID = PCI_INVALID_SUBVENDORID; 297 298 for (i = 0; chipsetInfo[i].vendorID; i++) 299 { 300 pBusTopologyInfo = pCl->pBusTopologyInfo; 301 while (pBusTopologyInfo) 302 { 303 if ((pBusTopologyInfo->busInfo.vendorID == chipsetInfo[i].vendorID) && 304 (pBusTopologyInfo->busInfo.deviceID == chipsetInfo[i].deviceID)) 305 { 306 matchFound = NV_TRUE; 307 break; 308 } 309 pBusTopologyInfo = pBusTopologyInfo->next; 310 } 311 312 if (matchFound) 313 { 314 if (pChipsetInfoIndex != NULL) 315 { 316 *pChipsetInfoIndex = (NvU16) i; 317 } 318 319 // 320 // IBM Wildhorse system has NV chipset attached to secondary K8 at bus 0x80 321 // (bug 227308). 322 // Do not change the algorithm for older chipsets where the devcie at bus%0x40 ==0, 0, 0 is 323 // considered as a host bridge. 324 // 325 if (((pBusTopologyInfo->pciSubBaseClass & 0xFF) == PCI_SUBCLASS_BR_HOST) || 326 (!(pBusTopologyInfo->bus % 0x40) && !pBusTopologyInfo->device && !pBusTopologyInfo->func)) 327 { 328 pCl->FHBAddr.domain = pBusTopologyInfo->domain; 329 pCl->FHBAddr.bus = pBusTopologyInfo->bus; 330 pCl->FHBAddr.device = pBusTopologyInfo->device; 331 pCl->FHBAddr.func = pBusTopologyInfo->func; 332 pCl->FHBAddr.valid = 0x1; 333 pCl->FHBAddr.handle = pBusTopologyInfo->handle; 334 335 // Store a copy of deviceID, vendorID, subdeviceID and subvendorID; 336 pCl->FHBBusInfo.deviceID = pBusTopologyInfo->busInfo.deviceID; 337 pCl->FHBBusInfo.vendorID = pBusTopologyInfo->busInfo.vendorID; 338 pCl->FHBBusInfo.subdeviceID = pBusTopologyInfo->busInfo.subdeviceID; 339 pCl->FHBBusInfo.subvendorID = pBusTopologyInfo->busInfo.subvendorID; 340 pCl->FHBBusInfo.revisionID = pBusTopologyInfo->busInfo.revisionID; 341 342 pCl->chipsetIDBusAddr.domain = pBusTopologyInfo->domain; 343 pCl->chipsetIDBusAddr.bus = pBusTopologyInfo->bus; 344 pCl->chipsetIDBusAddr.device = pBusTopologyInfo->device; 345 pCl->chipsetIDBusAddr.func = pBusTopologyInfo->func; 346 pCl->chipsetIDBusAddr.valid = 0x1; 347 pCl->chipsetIDBusAddr.handle = pBusTopologyInfo->handle; 348 349 // Store a copy of deviceID, vendorID, subdeviceID and subvendorID; 350 pCl->chipsetIDInfo.deviceID = pBusTopologyInfo->busInfo.deviceID; 351 pCl->chipsetIDInfo.vendorID = pBusTopologyInfo->busInfo.vendorID; 352 pCl->chipsetIDInfo.subdeviceID = pBusTopologyInfo->busInfo.subdeviceID; 353 pCl->chipsetIDInfo.subvendorID = pBusTopologyInfo->busInfo.subvendorID; 354 return NV_OK; 355 } 356 else 357 { 358 pCl->chipsetIDBusAddr.domain = pBusTopologyInfo->domain; 359 pCl->chipsetIDBusAddr.bus = pBusTopologyInfo->bus; 360 pCl->chipsetIDBusAddr.device = pBusTopologyInfo->device; 361 pCl->chipsetIDBusAddr.func = pBusTopologyInfo->func; 362 pCl->chipsetIDBusAddr.valid = 0x1; 363 pCl->chipsetIDBusAddr.handle = pBusTopologyInfo->handle; 364 365 // Store a copy of deviceID, vendorID, subdeviceID and subvendorID; 366 pCl->chipsetIDInfo.deviceID = pBusTopologyInfo->busInfo.deviceID; 367 pCl->chipsetIDInfo.vendorID = pBusTopologyInfo->busInfo.vendorID; 368 pCl->chipsetIDInfo.subdeviceID = pBusTopologyInfo->busInfo.subdeviceID; 369 pCl->chipsetIDInfo.subvendorID = pBusTopologyInfo->busInfo.subvendorID; 370 371 if (pCl->chipsetIDInfo.subvendorID == 0) 372 { 373 getSubsystemFromPCIECapabilities(pCl->chipsetIDBusAddr.domain, 374 pCl->chipsetIDBusAddr.bus, 375 pCl->chipsetIDBusAddr.device, 376 pCl->chipsetIDBusAddr.func, 377 &pCl->chipsetIDInfo.subvendorID, 378 &pCl->chipsetIDInfo.subdeviceID); 379 } 380 break; 381 } 382 } 383 } 384 385 if ((!matchFound) && (pChipsetInfoIndex != NULL)) 386 { 387 // This should be the entry with NULL information 388 NV_ASSERT(chipsetInfo[i].vendorID == 0); 389 *pChipsetInfoIndex = (NvU16) i; 390 } 391 392 // 393 // We are here because VendorId and deviceId in chipsetInfo table does not 394 // match with Host Bridge ID. In that case we need to find FHB either in 395 // cached bus topology or need to loop through PCI bus to find the FHB. 396 // 397 for (i = 0; i < 2; i++) 398 { 399 pBusTopologyInfo = pCl->pBusTopologyInfo; 400 while (pBusTopologyInfo) 401 { 402 if (pBusTopologyInfo->pciSubBaseClass == pciSubBaseClass[i]) 403 { 404 pCl->FHBAddr.domain = pBusTopologyInfo->domain; 405 pCl->FHBAddr.bus = pBusTopologyInfo->bus; 406 pCl->FHBAddr.device = pBusTopologyInfo->device; 407 pCl->FHBAddr.func = pBusTopologyInfo->func; 408 pCl->FHBAddr.valid = 0x1; 409 pCl->FHBAddr.handle = pBusTopologyInfo->handle; 410 411 // Store a copy of deviceID, vendorID, subdeviceID and subvendorID; 412 pCl->FHBBusInfo.deviceID = pBusTopologyInfo->busInfo.deviceID; 413 pCl->FHBBusInfo.vendorID = pBusTopologyInfo->busInfo.vendorID; 414 pCl->FHBBusInfo.subdeviceID = pBusTopologyInfo->busInfo.subdeviceID; 415 pCl->FHBBusInfo.subvendorID = pBusTopologyInfo->busInfo.subvendorID; 416 pCl->FHBBusInfo.revisionID = pBusTopologyInfo->busInfo.revisionID; 417 418 if (!matchFound) 419 { 420 pCl->chipsetIDBusAddr.domain = pBusTopologyInfo->domain; 421 pCl->chipsetIDBusAddr.bus = pBusTopologyInfo->bus; 422 pCl->chipsetIDBusAddr.device = pBusTopologyInfo->device; 423 pCl->chipsetIDBusAddr.func = pBusTopologyInfo->func; 424 pCl->chipsetIDBusAddr.valid = 0x1; 425 pCl->chipsetIDBusAddr.handle = pBusTopologyInfo->handle; 426 427 // Store a copy of deviceID, vendorID, subdeviceID and subvendorID; 428 pCl->chipsetIDInfo.deviceID = pBusTopologyInfo->busInfo.deviceID; 429 pCl->chipsetIDInfo.vendorID = pBusTopologyInfo->busInfo.vendorID; 430 pCl->chipsetIDInfo.subdeviceID = pBusTopologyInfo->busInfo.subdeviceID; 431 pCl->chipsetIDInfo.subvendorID = pBusTopologyInfo->busInfo.subvendorID; 432 433 if (pCl->chipsetIDInfo.subvendorID == 0) 434 { 435 getSubsystemFromPCIECapabilities(pCl->chipsetIDBusAddr.domain, 436 pCl->chipsetIDBusAddr.bus, 437 pCl->chipsetIDBusAddr.device, 438 pCl->chipsetIDBusAddr.func, 439 &pCl->chipsetIDInfo.subvendorID, 440 &pCl->chipsetIDInfo.subdeviceID); 441 } 442 } 443 return NV_OK; 444 } 445 pBusTopologyInfo = pBusTopologyInfo->next; 446 } 447 448 NV_PRINTF(LEVEL_INFO, 449 "NVRM : Host bridge device not found. Looking for a PCI-to-PCI bridge device!!!\n"); 450 } 451 452 NV_PRINTF(LEVEL_ERROR, 453 "NVRM : This is Bad. FHB not found in cached bus topology!!!\n"); 454 455 // HB is not present in cached bus topology. 456 NV_ASSERT(0); 457 458 // 459 // Don't bother scanning all domains, which takes approximately forever. 460 // If we can't find it in domain 0, we're probably not going to anyway 461 // (and something is already wrong). 462 // 463 domain = 0; 464 465 for (bus = 0; bus < PCI_MAX_BUSES; bus++) 466 { 467 for (device = 0; device < PCI_MAX_DEVICES; device++) 468 { 469 for (func = 0; func < PCI_MAX_FUNCTION; func++) 470 { 471 // read at domain, bus, device, func 472 handle = osPciInitHandle(domain, (NvU8)bus, device, func, &vendorID, &deviceID); 473 if (!handle) 474 { 475 if (func == 0) 476 { 477 // If a read to function zero of a specified bus/device master aborts, 478 // then it is assumed that no such device exists on the bus since 479 // devices are required to implement function number zero. 480 // In this case reads to the remaining functions are not necessary. 481 break; 482 } 483 else 484 { 485 continue; 486 } 487 } 488 489 if (!PCI_IS_VENDORID_VALID(vendorID)) 490 break; // skip to the next device 491 492 if ((osPciReadByte(handle, PCI_HEADER_TYPE0_BASECLASS)) != PCI_CLASS_BRIDGE_DEV) 493 break; // not a bridge device 494 495 if ((osPciReadByte(handle, PCI_HEADER_TYPE0_SUBCLASS)) != PCI_SUBCLASS_BR_HOST) 496 break; // not a host bridge 497 498 subdeviceID = osPciReadWord(handle, PCI_HEADER_TYPE0_SUBSYS_ID); 499 subvendorID = osPciReadWord(handle, PCI_HEADER_TYPE0_SUBSYS_VEN_ID); 500 revisionID = osPciReadByte(handle, PCI_HEADER_TYPE0_REVISION_ID); 501 502 // Found it 503 pCl->FHBAddr.domain = domain; 504 pCl->FHBAddr.bus = (NvU8)bus; 505 pCl->FHBAddr.device = device; 506 pCl->FHBAddr.func = func; 507 pCl->FHBAddr.valid = 0x1; 508 pCl->FHBAddr.handle = handle; 509 510 // Store a copy of deviceID, vendorID, subdeviceID and subvendorID; 511 pCl->FHBBusInfo.deviceID = deviceID; 512 pCl->FHBBusInfo.vendorID = vendorID; 513 pCl->FHBBusInfo.subdeviceID = subdeviceID; 514 pCl->FHBBusInfo.subvendorID = subvendorID; 515 pCl->FHBBusInfo.revisionID = revisionID; 516 517 if (!matchFound) 518 { 519 pCl->chipsetIDBusAddr.domain = domain; 520 pCl->chipsetIDBusAddr.bus = (NvU8)bus; 521 pCl->chipsetIDBusAddr.device = device; 522 pCl->chipsetIDBusAddr.func = func; 523 pCl->chipsetIDBusAddr.valid = 0x1; 524 pCl->chipsetIDBusAddr.handle = handle; 525 526 // Store a copy of deviceID, vendorID, subdeviceID and subvendorID; 527 pCl->chipsetIDInfo.deviceID = deviceID; 528 pCl->chipsetIDInfo.vendorID = vendorID; 529 pCl->chipsetIDInfo.subdeviceID = subdeviceID; 530 pCl->chipsetIDInfo.subvendorID = subvendorID; 531 } 532 return NV_OK; 533 } 534 } 535 } 536 537 // This is bad, we didn't find the First Host Bridge device (assume domain0/bus0/device0/func0) 538 pCl->FHBAddr.domain = 0x0; 539 pCl->FHBAddr.bus = 0x0; 540 pCl->FHBAddr.device = 0x0; 541 pCl->FHBAddr.func = 0x0; 542 pCl->FHBAddr.valid = 0x1; 543 pCl->FHBAddr.handle = NULL; 544 pCl->FHBBusInfo.deviceID = PCI_INVALID_DEVICEID; 545 pCl->FHBBusInfo.vendorID = PCI_INVALID_VENDORID; 546 pCl->FHBBusInfo.subdeviceID = PCI_INVALID_SUBDEVICEID; 547 pCl->FHBBusInfo.subvendorID = PCI_INVALID_SUBVENDORID; 548 549 DBG_BREAKPOINT(); 550 551 NV_ASSERT(0); //We can't find a host bridge, bad! 552 553 554 return NV_ERR_NOT_SUPPORTED; 555 } 556 557 NvBool 558 clIsL1MaskEnabledForUpstreamPort_IMPL 559 ( 560 OBJGPU *pGpu, 561 OBJCL *pCl 562 ) 563 { 564 NvU32 linkCtrl; 565 NvBool bEnable = NV_FALSE; 566 567 if (!pGpu->gpuClData.upstreamPort.addr.valid) 568 { 569 if (!pGpu->gpuClData.rootPort.addr.valid) 570 { 571 bEnable = NV_TRUE; 572 } 573 else 574 { 575 if (clPcieReadPortConfigReg(pGpu, pCl, &pGpu->gpuClData.rootPort, 576 CL_PCIE_LINK_CTRL_STATUS, &linkCtrl) != NV_OK) 577 { 578 bEnable = NV_TRUE; 579 } 580 else 581 { 582 if (!(linkCtrl & CL_PCIE_LINK_CTRL_STATUS_ASPM_L1_BIT)) 583 { 584 bEnable = NV_TRUE; 585 } 586 } 587 } 588 } 589 else 590 { 591 if (clPcieReadPortConfigReg(pGpu, pCl, &pGpu->gpuClData.upstreamPort, 592 CL_PCIE_LINK_CTRL_STATUS, &linkCtrl) != NV_OK) 593 { 594 bEnable = NV_TRUE; 595 } 596 else 597 { 598 if (!(linkCtrl & CL_PCIE_LINK_CTRL_STATUS_ASPM_L1_BIT)) 599 { 600 bEnable = NV_TRUE; 601 } 602 } 603 } 604 605 return bEnable; 606 } 607 608 /*! 609 * @brief Check if L0s mask is enabled for upstream component 610 * 611 * @param[in] pGpu GPU object pointer 612 * @param[in] pCl CL object pointer 613 * 614 * @return NV_TRUE if mask is enabled (implies L0s is disabled) 615 */ 616 NvBool 617 clIsL0sMaskEnabledForUpstreamPort_IMPL 618 ( 619 OBJGPU *pGpu, 620 OBJCL *pCl 621 ) 622 { 623 NvU32 linkCtrl; 624 NvBool bEnable = NV_FALSE; 625 626 if (!pGpu->gpuClData.upstreamPort.addr.valid) 627 { 628 if (!pGpu->gpuClData.rootPort.addr.valid) 629 { 630 bEnable = NV_TRUE; 631 } 632 else 633 { 634 if (clPcieReadPortConfigReg(pGpu, pCl, &pGpu->gpuClData.rootPort, 635 CL_PCIE_LINK_CTRL_STATUS, &linkCtrl) != NV_OK) 636 { 637 bEnable = NV_TRUE; 638 } 639 else 640 { 641 if (!(linkCtrl & CL_PCIE_LINK_CTRL_STATUS_ASPM_L0S_BIT)) 642 { 643 bEnable = NV_TRUE; 644 } 645 } 646 } 647 } 648 else 649 { 650 if (clPcieReadPortConfigReg(pGpu, pCl, &pGpu->gpuClData.upstreamPort, 651 CL_PCIE_LINK_CTRL_STATUS, &linkCtrl) != NV_OK) 652 { 653 bEnable = NV_TRUE; 654 } 655 else 656 { 657 if (!(linkCtrl & CL_PCIE_LINK_CTRL_STATUS_ASPM_L0S_BIT)) 658 { 659 bEnable = NV_TRUE; 660 } 661 } 662 } 663 664 return bEnable; 665 } 666 667 NV_STATUS 668 clInit_IMPL( 669 OBJGPU *pGpu, 670 OBJCL *pCl 671 ) 672 { 673 // 674 // Common code for all buses 675 // 676 (void)clInitMappingPciBusDevice(pGpu, pCl); 677 678 if (kbifGetBusIntfType_HAL(GPU_GET_KERNEL_BIF(pGpu)) == 679 NV2080_CTRL_BUS_INFO_TYPE_PCI_EXPRESS) 680 { 681 return clInitPcie(pGpu, pCl); 682 } 683 684 return NV_OK; // no Init is needed for PCI 685 } 686 687 void 688 clUpdateConfig_IMPL 689 ( 690 OBJGPU *pGpu, 691 OBJCL *pCl 692 ) 693 { 694 // Common code for all buses 695 clInitMappingPciBusDevice(pGpu, pCl); 696 697 if (kbifGetBusIntfType_HAL(GPU_GET_KERNEL_BIF(pGpu)) == 698 NV2080_CTRL_BUS_INFO_TYPE_PCI_EXPRESS) 699 { 700 clUpdatePcieConfig(pGpu, pCl); 701 return; 702 } 703 704 return; // no Update is needed for PCI 705 } 706 707 NV_STATUS 708 clTeardown_IMPL( 709 OBJGPU *pGpu, 710 OBJCL *pCl 711 ) 712 { 713 KernelBif *pKernelBif = GPU_GET_KERNEL_BIF(pGpu); 714 715 if (pKernelBif == NULL) 716 { 717 return NV_ERR_NOT_SUPPORTED; 718 } 719 720 clFreeBusTopologyCache(pCl); 721 722 switch (kbifGetBusIntfType_HAL(pKernelBif)) 723 { 724 case NV2080_CTRL_BUS_INFO_TYPE_PCI_EXPRESS: 725 return clTeardownPcie(pGpu, pCl); 726 727 case NV2080_CTRL_BUS_INFO_TYPE_PCI: 728 case NV2080_CTRL_BUS_INFO_TYPE_FPCI: 729 return NV_OK; 730 731 default: 732 return NV_ERR_GENERIC; 733 } 734 } 735 736 NV_STATUS 737 subdeviceCtrlCmdBusGetBFD_IMPL 738 ( 739 Subdevice *pSubdevice, 740 NV2080_CTRL_BUS_GET_BFD_PARAMSARR *pBusGetBFDParams 741 ) 742 { 743 OBJSYS *pSys = SYS_GET_INSTANCE(); 744 OBJCL *pCl = SYS_GET_CL(pSys); 745 BUSTOPOLOGYINFO *pBusTopologyInfo = pCl->pBusTopologyInfo; 746 NvU32 i = 0; 747 748 while(pBusTopologyInfo && i < 32) 749 { 750 pBusGetBFDParams->params[i].valid = NV_TRUE; 751 pBusGetBFDParams->params[i].deviceID = pBusTopologyInfo->busInfo.deviceID; 752 pBusGetBFDParams->params[i].vendorID = pBusTopologyInfo->busInfo.vendorID; 753 pBusGetBFDParams->params[i].domain = pBusTopologyInfo->domain; 754 pBusGetBFDParams->params[i].bus = (NvU16)pBusTopologyInfo->bus; 755 pBusGetBFDParams->params[i].device = (NvU16)pBusTopologyInfo->device; 756 pBusGetBFDParams->params[i].function = (NvU8)pBusTopologyInfo->func; 757 i++; 758 pBusTopologyInfo = pBusTopologyInfo->next; 759 } 760 if(i < 32) 761 { 762 pBusGetBFDParams->params[i].valid = NV_FALSE; 763 } 764 765 pBusTopologyInfo = pCl->pBusTopologyInfo; 766 return NV_OK; 767 } 768 769 void clSyncWithGsp_IMPL(OBJCL *pCl, GspSystemInfo *pGSI) 770 { 771 NvU32 idx = 0; 772 #define CL_SYNC_PDB(prop) \ 773 do { \ 774 pGSI->clPdbProperties |= pCl->getProperty(pCl, prop) ? NVBIT64(idx) : 0;\ 775 idx++; \ 776 } while (0) 777 778 CL_SYNC_PDB(PDB_PROP_CL_PCIE_CONFIG_ACCESSIBLE); 779 CL_SYNC_PDB(PDB_PROP_CL_FORCE_SNOOP_READS_AND_WRITES_WAR_BUG_410390); 780 CL_SYNC_PDB(PDB_PROP_CL_DISABLE_BR03_FLOW_CONTROL); 781 CL_SYNC_PDB(PDB_PROP_CL_ASLM_SUPPORTS_NV_LINK_UPGRADE); 782 CL_SYNC_PDB(PDB_PROP_CL_ASLM_SUPPORTS_FAST_LINK_UPGRADE); 783 CL_SYNC_PDB(PDB_PROP_CL_ASLM_SUPPORTS_HOT_RESET); 784 CL_SYNC_PDB(PDB_PROP_CL_ASLM_SUPPORTS_GEN2_LINK_UPGRADE); 785 CL_SYNC_PDB(PDB_PROP_CL_IS_CHIPSET_IN_ASPM_POR_LIST); 786 CL_SYNC_PDB(PDB_PROP_CL_ASPM_L0S_CHIPSET_DISABLED); 787 CL_SYNC_PDB(PDB_PROP_CL_ASPM_L1_CHIPSET_DISABLED); 788 CL_SYNC_PDB(PDB_PROP_CL_ASPM_L0S_CHIPSET_ENABLED_MOBILE_ONLY); 789 CL_SYNC_PDB(PDB_PROP_CL_ASPM_L1_CHIPSET_ENABLED_MOBILE_ONLY); 790 CL_SYNC_PDB(PDB_PROP_CL_ASPM_UPSTREAM_PORT_L1_MASK_ENABLED); 791 CL_SYNC_PDB(PDB_PROP_CL_PCIE_GEN1_GEN2_SWITCH_CHIPSET_DISABLED); 792 CL_SYNC_PDB(PDB_PROP_CL_PCIE_GEN1_GEN2_SWITCH_CHIPSET_DISABLED_GEFORCE); 793 CL_SYNC_PDB(PDB_PROP_CL_EXTENDED_TAG_FIELD_NOT_CAPABLE); 794 CL_SYNC_PDB(PDB_PROP_CL_NOSNOOP_NOT_CAPABLE); 795 CL_SYNC_PDB(PDB_PROP_CL_RELAXED_ORDERING_NOT_CAPABLE); 796 CL_SYNC_PDB(PDB_PROP_CL_PCIE_FORCE_GEN2_ENABLE); 797 CL_SYNC_PDB(PDB_PROP_CL_PCIE_GEN2_AT_LESS_THAN_X16_DISABLED); 798 CL_SYNC_PDB(PDB_PROP_CL_ROOTPORT_NEEDS_NOSNOOP_WAR); 799 CL_SYNC_PDB(PDB_PROP_CL_INTEL_CPU_ROOTPORT1_NEEDS_H57_WAR); 800 CL_SYNC_PDB(PDB_PROP_CL_PCIE_CONFIG_SKIP_MCFG_READ); 801 CL_SYNC_PDB(PDB_PROP_CL_ON_PCIE_GEN3_PATSBURG); 802 CL_SYNC_PDB(PDB_PROP_CL_ALLOW_PCIE_GEN3_ON_PATSBURG_WITH_IVBE_CPU); 803 CL_SYNC_PDB(PDB_PROP_CL_BUG_999673_P2P_ARBITRARY_SPLIT_WAR); 804 CL_SYNC_PDB(PDB_PROP_CL_UPSTREAM_LTR_SUPPORTED); 805 CL_SYNC_PDB(PDB_PROP_CL_BUG_1340801_DISABLE_GEN3_ON_GIGABYTE_SNIPER_3); 806 CL_SYNC_PDB(PDB_PROP_CL_BUG_1681803_WAR_DISABLE_MSCG); 807 CL_SYNC_PDB(PDB_PROP_CL_ON_HASWELL_HOST_BRIDGE); 808 CL_SYNC_PDB(PDB_PROP_CL_PCIE_NON_COHERENT_USE_TC0_ONLY); 809 CL_SYNC_PDB(PDB_PROP_CL_UNSUPPORTED_CHIPSET); 810 CL_SYNC_PDB(PDB_PROP_CL_IS_CHIPSET_IO_COHERENT); 811 CL_SYNC_PDB(PDB_PROP_CL_DISABLE_IOMAP_WC); 812 CL_SYNC_PDB(PDB_PROP_CL_HAS_RESIZABLE_BAR_ISSUE); 813 CL_SYNC_PDB(PDB_PROP_CL_IS_EXTERNAL_GPU); 814 CL_SYNC_PDB(PDB_PROP_CL_BUG_3751839_GEN_SPEED_WAR); 815 CL_SYNC_PDB(PDB_PROP_CL_BUG_3562968_WAR_ALLOW_PCIE_ATOMICS); 816 817 #undef CL_SYNC_PDB 818 819 NV_ASSERT(idx < (sizeof(pGSI->clPdbProperties) * 8)); 820 821 pGSI->Chipset = pCl->Chipset; 822 pGSI->FHBBusInfo = pCl->FHBBusInfo; 823 pGSI->chipsetIDInfo = pCl->chipsetIDInfo; 824 825 } 826