diff options
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 795c9026d55f..8473727b29fa 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -856,6 +856,8 @@ void set_pcie_port_type(struct pci_dev *pdev) | |||
856 | pdev->pcie_cap = pos; | 856 | pdev->pcie_cap = pos; |
857 | pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); | 857 | pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); |
858 | pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; | 858 | pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; |
859 | pci_read_config_word(pdev, pos + PCI_EXP_DEVCAP, ®16); | ||
860 | pdev->pcie_mpss = reg16 & PCI_EXP_DEVCAP_PAYLOAD; | ||
859 | } | 861 | } |
860 | 862 | ||
861 | void set_pcie_hotplug_bridge(struct pci_dev *pdev) | 863 | void set_pcie_hotplug_bridge(struct pci_dev *pdev) |
@@ -1326,6 +1328,150 @@ int pci_scan_slot(struct pci_bus *bus, int devfn) | |||
1326 | return nr; | 1328 | return nr; |
1327 | } | 1329 | } |
1328 | 1330 | ||
1331 | static int pcie_find_smpss(struct pci_dev *dev, void *data) | ||
1332 | { | ||
1333 | u8 *smpss = data; | ||
1334 | |||
1335 | if (!pci_is_pcie(dev)) | ||
1336 | return 0; | ||
1337 | |||
1338 | /* For PCIE hotplug enabled slots not connected directly to a | ||
1339 | * PCI-E root port, there can be problems when hotplugging | ||
1340 | * devices. This is due to the possibility of hotplugging a | ||
1341 | * device into the fabric with a smaller MPS that the devices | ||
1342 | * currently running have configured. Modifying the MPS on the | ||
1343 | * running devices could cause a fatal bus error due to an | ||
1344 | * incoming frame being larger than the newly configured MPS. | ||
1345 | * To work around this, the MPS for the entire fabric must be | ||
1346 | * set to the minimum size. Any devices hotplugged into this | ||
1347 | * fabric will have the minimum MPS set. If the PCI hotplug | ||
1348 | * slot is directly connected to the root port and there are not | ||
1349 | * other devices on the fabric (which seems to be the most | ||
1350 | * common case), then this is not an issue and MPS discovery | ||
1351 | * will occur as normal. | ||
1352 | */ | ||
1353 | if (dev->is_hotplug_bridge && (!list_is_singular(&dev->bus->devices) || | ||
1354 | dev->bus->self->pcie_type != PCI_EXP_TYPE_ROOT_PORT)) | ||
1355 | *smpss = 0; | ||
1356 | |||
1357 | if (*smpss > dev->pcie_mpss) | ||
1358 | *smpss = dev->pcie_mpss; | ||
1359 | |||
1360 | return 0; | ||
1361 | } | ||
1362 | |||
1363 | static void pcie_write_mps(struct pci_dev *dev, int mps) | ||
1364 | { | ||
1365 | int rc, dev_mpss; | ||
1366 | |||
1367 | dev_mpss = 128 << dev->pcie_mpss; | ||
1368 | |||
1369 | if (pcie_bus_config == PCIE_BUS_PERFORMANCE) { | ||
1370 | if (dev->bus->self) { | ||
1371 | dev_dbg(&dev->bus->dev, "Bus MPSS %d\n", | ||
1372 | 128 << dev->bus->self->pcie_mpss); | ||
1373 | |||
1374 | /* For "MPS Force Max", the assumption is made that | ||
1375 | * downstream communication will never be larger than | ||
1376 | * the MRRS. So, the MPS only needs to be configured | ||
1377 | * for the upstream communication. This being the case, | ||
1378 | * walk from the top down and set the MPS of the child | ||
1379 | * to that of the parent bus. | ||
1380 | */ | ||
1381 | mps = 128 << dev->bus->self->pcie_mpss; | ||
1382 | if (mps > dev_mpss) | ||
1383 | dev_warn(&dev->dev, "MPS configured higher than" | ||
1384 | " maximum supported by the device. If" | ||
1385 | " a bus issue occurs, try running with" | ||
1386 | " pci=pcie_bus_safe.\n"); | ||
1387 | } | ||
1388 | |||
1389 | dev->pcie_mpss = ffs(mps) - 8; | ||
1390 | } | ||
1391 | |||
1392 | rc = pcie_set_mps(dev, mps); | ||
1393 | if (rc) | ||
1394 | dev_err(&dev->dev, "Failed attempting to set the MPS\n"); | ||
1395 | } | ||
1396 | |||
1397 | static void pcie_write_mrrs(struct pci_dev *dev, int mps) | ||
1398 | { | ||
1399 | int rc, mrrs; | ||
1400 | |||
1401 | if (pcie_bus_config == PCIE_BUS_PERFORMANCE) { | ||
1402 | int dev_mpss = 128 << dev->pcie_mpss; | ||
1403 | |||
1404 | /* For Max performance, the MRRS must be set to the largest | ||
1405 | * supported value. However, it cannot be configured larger | ||
1406 | * than the MPS the device or the bus can support. This assumes | ||
1407 | * that the largest MRRS available on the device cannot be | ||
1408 | * smaller than the device MPSS. | ||
1409 | */ | ||
1410 | mrrs = mps < dev_mpss ? mps : dev_mpss; | ||
1411 | } else | ||
1412 | /* In the "safe" case, configure the MRRS for fairness on the | ||
1413 | * bus by making all devices have the same size | ||
1414 | */ | ||
1415 | mrrs = mps; | ||
1416 | |||
1417 | |||
1418 | /* MRRS is a R/W register. Invalid values can be written, but a | ||
1419 | * subsiquent read will verify if the value is acceptable or not. | ||
1420 | * If the MRRS value provided is not acceptable (e.g., too large), | ||
1421 | * shrink the value until it is acceptable to the HW. | ||
1422 | */ | ||
1423 | while (mrrs != pcie_get_readrq(dev) && mrrs >= 128) { | ||
1424 | rc = pcie_set_readrq(dev, mrrs); | ||
1425 | if (rc) | ||
1426 | dev_err(&dev->dev, "Failed attempting to set the MRRS\n"); | ||
1427 | |||
1428 | mrrs /= 2; | ||
1429 | } | ||
1430 | } | ||
1431 | |||
1432 | static int pcie_bus_configure_set(struct pci_dev *dev, void *data) | ||
1433 | { | ||
1434 | int mps = 128 << *(u8 *)data; | ||
1435 | |||
1436 | if (!pci_is_pcie(dev)) | ||
1437 | return 0; | ||
1438 | |||
1439 | dev_info(&dev->dev, "Dev MPS %d MPSS %d MRRS %d\n", | ||
1440 | pcie_get_mps(dev), 128<<dev->pcie_mpss, pcie_get_readrq(dev)); | ||
1441 | |||
1442 | pcie_write_mps(dev, mps); | ||
1443 | pcie_write_mrrs(dev, mps); | ||
1444 | |||
1445 | dev_info(&dev->dev, "Dev MPS %d MPSS %d MRRS %d\n", | ||
1446 | pcie_get_mps(dev), 128<<dev->pcie_mpss, pcie_get_readrq(dev)); | ||
1447 | |||
1448 | return 0; | ||
1449 | } | ||
1450 | |||
1451 | /* pcie_bus_configure_mps requires that pci_walk_bus work in a top-down, | ||
1452 | * parents then children fashion. If this changes, then this code will not | ||
1453 | * work as designed. | ||
1454 | */ | ||
1455 | void pcie_bus_configure_settings(struct pci_bus *bus, u8 mpss) | ||
1456 | { | ||
1457 | u8 smpss = mpss; | ||
1458 | |||
1459 | if (!bus->self) | ||
1460 | return; | ||
1461 | |||
1462 | if (!pci_is_pcie(bus->self)) | ||
1463 | return; | ||
1464 | |||
1465 | if (pcie_bus_config == PCIE_BUS_SAFE) { | ||
1466 | pcie_find_smpss(bus->self, &smpss); | ||
1467 | pci_walk_bus(bus, pcie_find_smpss, &smpss); | ||
1468 | } | ||
1469 | |||
1470 | pcie_bus_configure_set(bus->self, &smpss); | ||
1471 | pci_walk_bus(bus, pcie_bus_configure_set, &smpss); | ||
1472 | } | ||
1473 | EXPORT_SYMBOL_GPL(pcie_bus_configure_settings); | ||
1474 | |||
1329 | unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) | 1475 | unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) |
1330 | { | 1476 | { |
1331 | unsigned int devfn, pass, max = bus->secondary; | 1477 | unsigned int devfn, pass, max = bus->secondary; |