|
@@ -1363,31 +1363,25 @@ static int pcie_find_smpss(struct pci_dev *dev, void *data)
|
|
|
|
|
|
static void pcie_write_mps(struct pci_dev *dev, int mps)
|
|
static void pcie_write_mps(struct pci_dev *dev, int mps)
|
|
{
|
|
{
|
|
- int rc, dev_mpss;
|
|
|
|
-
|
|
|
|
- dev_mpss = 128 << dev->pcie_mpss;
|
|
|
|
|
|
+ int rc;
|
|
|
|
|
|
if (pcie_bus_config == PCIE_BUS_PERFORMANCE) {
|
|
if (pcie_bus_config == PCIE_BUS_PERFORMANCE) {
|
|
- if (dev->bus->self) {
|
|
|
|
- dev_dbg(&dev->bus->dev, "Bus MPSS %d\n",
|
|
|
|
- 128 << dev->bus->self->pcie_mpss);
|
|
|
|
|
|
+ mps = 128 << dev->pcie_mpss;
|
|
|
|
|
|
- /* For "MPS Force Max", the assumption is made that
|
|
|
|
|
|
+ if (dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && dev->bus->self)
|
|
|
|
+ /* For "Performance", the assumption is made that
|
|
* downstream communication will never be larger than
|
|
* downstream communication will never be larger than
|
|
* the MRRS. So, the MPS only needs to be configured
|
|
* the MRRS. So, the MPS only needs to be configured
|
|
* for the upstream communication. This being the case,
|
|
* for the upstream communication. This being the case,
|
|
* walk from the top down and set the MPS of the child
|
|
* walk from the top down and set the MPS of the child
|
|
* to that of the parent bus.
|
|
* to that of the parent bus.
|
|
|
|
+ *
|
|
|
|
+ * Configure the device MPS with the smaller of the
|
|
|
|
+ * device MPSS or the bridge MPS (which is assumed to be
|
|
|
|
+ * properly configured at this point to the largest
|
|
|
|
+ * allowable MPS based on its parent bus).
|
|
*/
|
|
*/
|
|
- mps = 128 << dev->bus->self->pcie_mpss;
|
|
|
|
- if (mps > dev_mpss)
|
|
|
|
- dev_warn(&dev->dev, "MPS configured higher than"
|
|
|
|
- " maximum supported by the device. If"
|
|
|
|
- " a bus issue occurs, try running with"
|
|
|
|
- " pci=pcie_bus_safe.\n");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- dev->pcie_mpss = ffs(mps) - 8;
|
|
|
|
|
|
+ mps = min(mps, pcie_get_mps(dev->bus->self));
|
|
}
|
|
}
|
|
|
|
|
|
rc = pcie_set_mps(dev, mps);
|
|
rc = pcie_set_mps(dev, mps);
|
|
@@ -1395,25 +1389,22 @@ static void pcie_write_mps(struct pci_dev *dev, int mps)
|
|
dev_err(&dev->dev, "Failed attempting to set the MPS\n");
|
|
dev_err(&dev->dev, "Failed attempting to set the MPS\n");
|
|
}
|
|
}
|
|
|
|
|
|
-static void pcie_write_mrrs(struct pci_dev *dev, int mps)
|
|
|
|
|
|
+static void pcie_write_mrrs(struct pci_dev *dev)
|
|
{
|
|
{
|
|
- int rc, mrrs, dev_mpss;
|
|
|
|
|
|
+ int rc, mrrs;
|
|
|
|
|
|
/* In the "safe" case, do not configure the MRRS. There appear to be
|
|
/* In the "safe" case, do not configure the MRRS. There appear to be
|
|
* issues with setting MRRS to 0 on a number of devices.
|
|
* issues with setting MRRS to 0 on a number of devices.
|
|
*/
|
|
*/
|
|
-
|
|
|
|
if (pcie_bus_config != PCIE_BUS_PERFORMANCE)
|
|
if (pcie_bus_config != PCIE_BUS_PERFORMANCE)
|
|
return;
|
|
return;
|
|
|
|
|
|
- dev_mpss = 128 << dev->pcie_mpss;
|
|
|
|
-
|
|
|
|
/* For Max performance, the MRRS must be set to the largest supported
|
|
/* For Max performance, the MRRS must be set to the largest supported
|
|
* value. However, it cannot be configured larger than the MPS the
|
|
* value. However, it cannot be configured larger than the MPS the
|
|
- * device or the bus can support. This assumes that the largest MRRS
|
|
|
|
- * available on the device cannot be smaller than the device MPSS.
|
|
|
|
|
|
+ * device or the bus can support. This should already be properly
|
|
|
|
+ * configured by a prior call to pcie_write_mps.
|
|
*/
|
|
*/
|
|
- mrrs = min(mps, dev_mpss);
|
|
|
|
|
|
+ mrrs = pcie_get_mps(dev);
|
|
|
|
|
|
/* MRRS is a R/W register. Invalid values can be written, but a
|
|
/* MRRS is a R/W register. Invalid values can be written, but a
|
|
* subsequent read will verify if the value is acceptable or not.
|
|
* subsequent read will verify if the value is acceptable or not.
|
|
@@ -1421,16 +1412,18 @@ static void pcie_write_mrrs(struct pci_dev *dev, int mps)
|
|
* shrink the value until it is acceptable to the HW.
|
|
* shrink the value until it is acceptable to the HW.
|
|
*/
|
|
*/
|
|
while (mrrs != pcie_get_readrq(dev) && mrrs >= 128) {
|
|
while (mrrs != pcie_get_readrq(dev) && mrrs >= 128) {
|
|
- dev_warn(&dev->dev, "Attempting to modify the PCI-E MRRS value"
|
|
|
|
- " to %d. If any issues are encountered, please try "
|
|
|
|
- "running with pci=pcie_bus_safe\n", mrrs);
|
|
|
|
rc = pcie_set_readrq(dev, mrrs);
|
|
rc = pcie_set_readrq(dev, mrrs);
|
|
- if (rc)
|
|
|
|
- dev_err(&dev->dev,
|
|
|
|
- "Failed attempting to set the MRRS\n");
|
|
|
|
|
|
+ if (!rc)
|
|
|
|
+ break;
|
|
|
|
|
|
|
|
+ dev_warn(&dev->dev, "Failed attempting to set the MRRS\n");
|
|
mrrs /= 2;
|
|
mrrs /= 2;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ if (mrrs < 128)
|
|
|
|
+ dev_err(&dev->dev, "MRRS was unable to be configured with a "
|
|
|
|
+ "safe value. If problems are experienced, try running "
|
|
|
|
+ "with pci=pcie_bus_safe.\n");
|
|
}
|
|
}
|
|
|
|
|
|
static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
|
|
static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
|
|
@@ -1444,7 +1437,7 @@ static int pcie_bus_configure_set(struct pci_dev *dev, void *data)
|
|
pcie_get_mps(dev), 128<<dev->pcie_mpss, pcie_get_readrq(dev));
|
|
pcie_get_mps(dev), 128<<dev->pcie_mpss, pcie_get_readrq(dev));
|
|
|
|
|
|
pcie_write_mps(dev, mps);
|
|
pcie_write_mps(dev, mps);
|
|
- pcie_write_mrrs(dev, mps);
|
|
|
|
|
|
+ pcie_write_mrrs(dev);
|
|
|
|
|
|
dev_dbg(&dev->dev, "Dev MPS %d MPSS %d MRRS %d\n",
|
|
dev_dbg(&dev->dev, "Dev MPS %d MPSS %d MRRS %d\n",
|
|
pcie_get_mps(dev), 128<<dev->pcie_mpss, pcie_get_readrq(dev));
|
|
pcie_get_mps(dev), 128<<dev->pcie_mpss, pcie_get_readrq(dev));
|