]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
Merge branch 'pci/misc'
authorBjorn Helgaas <bhelgaas@google.com>
Wed, 21 Oct 2020 14:58:36 +0000 (09:58 -0500)
committerBjorn Helgaas <bhelgaas@google.com>
Wed, 21 Oct 2020 14:58:36 +0000 (09:58 -0500)
- Remove unnecessary #includes (Gustavo Pimentel)

- Fix intel_mid_pci.c build error when !CONFIG_ACPI (Randy Dunlap)

- Use scnprintf(), not snprintf(), in sysfs "show" functions (Krzysztof
  Wilczyński)

- Simplify pci-pf-stub by using module_pci_driver() (Liu Shixin)

- Print IRQ used by Link Bandwidth Notification (Dongdong Liu)

- Update sysfs mmap-related #ifdef comments (Clint Sbisa)

- Simplify pci_dev_reset_slot_function() (Lukas Wunner)

- Use "NULL" instead of "0" to fix sparse warnings (Gustavo Pimentel)

- Simplify bool comparisons (Krzysztof Wilczyński)

- Drop double zeroing for P2PDMA sg_init_table() (Julia Lawall)

* pci/misc:
  PCI: v3-semi: Remove unneeded break
  PCI/P2PDMA: Drop double zeroing for sg_init_table()
  PCI: Simplify bool comparisons
  PCI: endpoint: Use "NULL" instead of "0" as a NULL pointer
  PCI: Simplify pci_dev_reset_slot_function()
  PCI: Update mmap-related #ifdef comments
  PCI/LINK: Print IRQ number used by port
  PCI/IOV: Simplify pci-pf-stub with module_pci_driver()
  PCI: Use scnprintf(), not snprintf(), in sysfs "show" functions
  x86/PCI: Fix intel_mid_pci.c build error when ACPI is not enabled
  PCI: Remove unnecessary header includes

25 files changed:
Documentation/power/pci.rst
arch/x86/pci/fixup.c
arch/x86/pci/intel_mid_pci.c
drivers/acpi/pci_mcfg.c
drivers/hid/intel-ish-hid/ipc/ipc.c
drivers/net/ethernet/marvell/sky2.c
drivers/pci/Kconfig
drivers/pci/ecam.c
drivers/pci/hotplug/pciehp_ctrl.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/hotplug/rpadlpar_core.c
drivers/pci/hotplug/shpchp_ctrl.c
drivers/pci/pci-acpi.c
drivers/pci/pci-driver.c
drivers/pci/pci-sysfs.c
drivers/pci/pci.c
drivers/pci/pci.h
drivers/pci/pcie/aspm.c
drivers/pci/pcie/dpc.c
drivers/pci/probe.c
drivers/pci/quirks.c
drivers/staging/media/atomisp/pci/atomisp_v4l2.c
include/linux/pci-ecam.h
include/linux/pci.h
include/uapi/linux/pci_regs.h

index 1831e431f7259973126bf72edc5a3b6adb5d4350..b04fb18cc4e2826a2800fd36087a5d00b3a31dcc 100644 (file)
@@ -320,7 +320,7 @@ that these callbacks operate on::
        unsigned int    d2_support:1;   /* Low power state D2 is supported */
        unsigned int    no_d1d2:1;      /* D1 and D2 are forbidden */
        unsigned int    wakeup_prepared:1;  /* Device prepared for wake up */
-       unsigned int    d3_delay;       /* D3->D0 transition time in ms */
+       unsigned int    d3hot_delay;    /* D3hot->D0 transition time in ms */
        ...
   };
 
index b8c9a5b87f3728c0777b8907ffe12bbd466a5079..0a0e168be1cbec0da9bad7cf2266d11118eae977 100644 (file)
@@ -587,7 +587,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0xa26d, pci_invalid_bar);
 static void pci_fixup_amd_ehci_pme(struct pci_dev *dev)
 {
        dev_info(&dev->dev, "PME# does not work under D3, disabling it\n");
-       dev->pme_support &= ~((PCI_PM_CAP_PME_D3 | PCI_PM_CAP_PME_D3cold)
+       dev->pme_support &= ~((PCI_PM_CAP_PME_D3hot | PCI_PM_CAP_PME_D3cold)
                >> PCI_PM_CAP_PME_SHIFT);
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x7808, pci_fixup_amd_ehci_pme);
index 0aaf31917061dc5df2cc17225406f954c935fe83..24ca4ee2802fbb2422b31c98cdbe96a2e0d37d1c 100644 (file)
@@ -323,7 +323,7 @@ static void pci_d3delay_fixup(struct pci_dev *dev)
         */
        if (type1_access_ok(dev->bus->number, dev->devfn, PCI_DEVICE_ID))
                return;
-       dev->d3_delay = 0;
+       dev->d3hot_delay = 0;
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_d3delay_fixup);
 
index 54b36b7ad47d95269e445cc11eb47039962fdc47..7ddd57abadd1da36cf559db61e7df4343b74b584 100644 (file)
@@ -142,6 +142,26 @@ static struct mcfg_fixup mcfg_quirks[] = {
        XGENE_V2_ECAM_MCFG(4, 0),
        XGENE_V2_ECAM_MCFG(4, 1),
        XGENE_V2_ECAM_MCFG(4, 2),
+
+#define ALTRA_ECAM_QUIRK(rev, seg) \
+       { "Ampere", "Altra   ", rev, seg, MCFG_BUS_ANY, &pci_32b_read_ops }
+
+       ALTRA_ECAM_QUIRK(1, 0),
+       ALTRA_ECAM_QUIRK(1, 1),
+       ALTRA_ECAM_QUIRK(1, 2),
+       ALTRA_ECAM_QUIRK(1, 3),
+       ALTRA_ECAM_QUIRK(1, 4),
+       ALTRA_ECAM_QUIRK(1, 5),
+       ALTRA_ECAM_QUIRK(1, 6),
+       ALTRA_ECAM_QUIRK(1, 7),
+       ALTRA_ECAM_QUIRK(1, 8),
+       ALTRA_ECAM_QUIRK(1, 9),
+       ALTRA_ECAM_QUIRK(1, 10),
+       ALTRA_ECAM_QUIRK(1, 11),
+       ALTRA_ECAM_QUIRK(1, 12),
+       ALTRA_ECAM_QUIRK(1, 13),
+       ALTRA_ECAM_QUIRK(1, 14),
+       ALTRA_ECAM_QUIRK(1, 15),
 };
 
 static char mcfg_oem_id[ACPI_OEM_ID_SIZE];
@@ -280,5 +300,5 @@ void __init pci_mmcfg_late_init(void)
 {
        int err = acpi_table_parse(ACPI_SIG_MCFG, pci_mcfg_parse);
        if (err)
-               pr_err("Failed to parse MCFG (%d)\n", err);
+               pr_debug("Failed to parse MCFG (%d)\n", err);
 }
index 8f8dfdf64833e2d56a7fd41d0d0a82f58e1b065d..a45ac7fa417b9aa97e673603bd166dda77c5379d 100644 (file)
@@ -755,7 +755,7 @@ static int _ish_hw_reset(struct ishtp_device *dev)
        csr |= PCI_D3hot;
        pci_write_config_word(pdev, pdev->pm_cap + PCI_PM_CTRL, csr);
 
-       mdelay(pdev->d3_delay);
+       mdelay(pdev->d3hot_delay);
 
        csr &= ~PCI_PM_CTRL_STATE_MASK;
        csr |= PCI_D0;
index cec8124301c7f5683c41be085e0de9832f6dc23e..dd11c06ca7f93f9c61408f6b3e61d720473a2896 100644 (file)
@@ -5105,7 +5105,7 @@ static int sky2_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        INIT_WORK(&hw->restart_work, sky2_restart);
 
        pci_set_drvdata(pdev, hw);
-       pdev->d3_delay = 300;
+       pdev->d3hot_delay = 300;
 
        return 0;
 
index 4bef5c2bae9f587e5739b3cb8b57a4fc270b7681..d323b25ae27e4bc6d0bea410e84b11e2b34c59f7 100644 (file)
@@ -187,6 +187,68 @@ config PCI_HYPERV
          The PCI device frontend driver allows the kernel to import arbitrary
          PCI devices from a PCI backend to support PCI driver domains.
 
+choice
+       prompt "PCI Express hierarchy optimization setting"
+       default PCIE_BUS_DEFAULT
+       depends on PCI && EXPERT
+       help
+         MPS (Max Payload Size) and MRRS (Max Read Request Size) are PCIe
+         device parameters that affect performance and the ability to
+         support hotplug and peer-to-peer DMA.
+
+         The following choices set the MPS and MRRS optimization strategy
+         at compile-time.  The choices are the same as those offered for
+         the kernel command-line parameter 'pci', i.e.,
+         'pci=pcie_bus_tune_off', 'pci=pcie_bus_safe',
+         'pci=pcie_bus_perf', and 'pci=pcie_bus_peer2peer'.
+
+         This is a compile-time setting and can be overridden by the above
+         command-line parameters.  If unsure, choose PCIE_BUS_DEFAULT.
+
+config PCIE_BUS_TUNE_OFF
+       bool "Tune Off"
+       depends on PCI
+       help
+         Use the BIOS defaults; don't touch MPS at all.  This is the same
+         as booting with 'pci=pcie_bus_tune_off'.
+
+config PCIE_BUS_DEFAULT
+       bool "Default"
+       depends on PCI
+       help
+         Default choice; ensure that the MPS matches upstream bridge.
+
+config PCIE_BUS_SAFE
+       bool "Safe"
+       depends on PCI
+       help
+         Use largest MPS that boot-time devices support.  If you have a
+         closed system with no possibility of adding new devices, this
+         will use the largest MPS that's supported by all devices.  This
+         is the same as booting with 'pci=pcie_bus_safe'.
+
+config PCIE_BUS_PERFORMANCE
+       bool "Performance"
+       depends on PCI
+       help
+         Use MPS and MRRS for best performance.  Ensure that a given
+         device's MPS is no larger than its parent MPS, which allows us to
+         keep all switches/bridges to the max MPS supported by their
+         parent.  This is the same as booting with 'pci=pcie_bus_perf'.
+
+config PCIE_BUS_PEER2PEER
+       bool "Peer2peer"
+       depends on PCI
+       help
+         Set MPS = 128 for all devices.  MPS configuration effected by the
+         other options could cause the MPS on one root port to be
+         different than that of the MPS on another, which may cause
+         hot-added devices or peer-to-peer DMA to fail.  Set MPS to the
+         smallest possible value (128B) system-wide to avoid these issues.
+         This is the same as booting with 'pci=pcie_bus_peer2peer'.
+
+endchoice
+
 source "drivers/pci/hotplug/Kconfig"
 source "drivers/pci/controller/Kconfig"
 source "drivers/pci/endpoint/Kconfig"
index 8f065a42fc1a2ec958fa71cb8250369e4d89e556..b54d32a31669360697259f2c5c44a37795f9d897 100644 (file)
@@ -168,4 +168,14 @@ const struct pci_ecam_ops pci_32b_ops = {
                .write          = pci_generic_config_write32,
        }
 };
+
+/* ECAM ops for 32-bit read only (non-compliant) */
+const struct pci_ecam_ops pci_32b_read_ops = {
+       .bus_shift      = 20,
+       .pci_ops        = {
+               .map_bus        = pci_ecam_map_bus,
+               .read           = pci_generic_config_read32,
+               .write          = pci_generic_config_write,
+       }
+};
 #endif
index 6503d15effbbd314b4cfbc60358262fbbb23193f..2f5f4bb42dcc6f4019995191d897e42f0814e76a 100644 (file)
@@ -73,10 +73,8 @@ static int board_added(struct controller *ctrl)
 
        /* Check link training status */
        retval = pciehp_check_link_status(ctrl);
-       if (retval) {
-               ctrl_err(ctrl, "Failed to check link status\n");
+       if (retval)
                goto err_exit;
-       }
 
        /* Check for a power fault */
        if (ctrl->power_fault_detected || pciehp_query_power_fault(ctrl)) {
index 53433b37e18122f52f0da595b595ff5cf7f9de9d..fb3840e222addf7527469b59513b33bf74861aad 100644 (file)
@@ -283,8 +283,6 @@ static void pcie_wait_for_presence(struct pci_dev *pdev)
                msleep(10);
                timeout -= 10;
        } while (timeout > 0);
-
-       pci_info(pdev, "Timeout waiting for Presence Detect\n");
 }
 
 int pciehp_check_link_status(struct controller *ctrl)
@@ -293,8 +291,10 @@ int pciehp_check_link_status(struct controller *ctrl)
        bool found;
        u16 lnk_status;
 
-       if (!pcie_wait_for_link(pdev, true))
+       if (!pcie_wait_for_link(pdev, true)) {
+               ctrl_info(ctrl, "Slot(%s): No link\n", slot_name(ctrl));
                return -1;
+       }
 
        if (ctrl->inband_presence_disabled)
                pcie_wait_for_presence(pdev);
@@ -311,15 +311,18 @@ int pciehp_check_link_status(struct controller *ctrl)
        ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status);
        if ((lnk_status & PCI_EXP_LNKSTA_LT) ||
            !(lnk_status & PCI_EXP_LNKSTA_NLW)) {
-               ctrl_err(ctrl, "link training error: status %#06x\n",
-                        lnk_status);
+               ctrl_info(ctrl, "Slot(%s): Cannot train link: status %#06x\n",
+                         slot_name(ctrl), lnk_status);
                return -1;
        }
 
        pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status);
 
-       if (!found)
+       if (!found) {
+               ctrl_info(ctrl, "Slot(%s): No device found\n",
+                         slot_name(ctrl));
                return -1;
+       }
 
        return 0;
 }
index f979b7098acf3448a638caea7a53ad86d3025612..0a3c80ba66be4c4e48098fa7efa0f0972c504b88 100644 (file)
@@ -40,13 +40,13 @@ static DEFINE_MUTEX(rpadlpar_mutex);
 static struct device_node *find_vio_slot_node(char *drc_name)
 {
        struct device_node *parent = of_find_node_by_name(NULL, "vdevice");
-       struct device_node *dn = NULL;
+       struct device_node *dn;
        int rc;
 
        if (!parent)
                return NULL;
 
-       while ((dn = of_get_next_child(parent, dn))) {
+       for_each_child_of_node(parent, dn) {
                rc = rpaphp_check_drc_props(dn, drc_name, NULL);
                if (rc == 0)
                        break;
@@ -60,10 +60,10 @@ static struct device_node *find_vio_slot_node(char *drc_name)
 static struct device_node *find_php_slot_pci_node(char *drc_name,
                                                  char *drc_type)
 {
-       struct device_node *np = NULL;
+       struct device_node *np;
        int rc;
 
-       while ((np = of_find_node_by_name(np, "pci"))) {
+       for_each_node_by_name(np, "pci") {
                rc = rpaphp_check_drc_props(np, drc_name, drc_type);
                if (rc == 0)
                        break;
index afdc52d1cae75ede21970718e965601a30ee22ea..aedd9dfd2a16a8ba740bc03274e2a84fb1ee9ed4 100644 (file)
@@ -299,7 +299,6 @@ static int board_added(struct slot *p_slot)
        if (p_slot->status == 0xFF) {
                /* power fault occurred, but it was benign */
                ctrl_dbg(ctrl, "%s: Power fault\n", __func__);
-               rc = POWER_FAILURE;
                p_slot->status = 0;
                goto err_exit;
        }
index d5869a03f748368e31e5be96ae0d477f88d2d494..154db9a47511948a2f703c0be696699fa1482bab 100644 (file)
@@ -1167,7 +1167,7 @@ static struct acpi_device *acpi_pci_find_companion(struct device *dev)
  * @pdev: the PCI device whose delay is to be updated
  * @handle: ACPI handle of this device
  *
- * Update the d3_delay and d3cold_delay of a PCI device from the ACPI _DSM
+ * Update the d3hot_delay and d3cold_delay of a PCI device from the ACPI _DSM
  * control method of either the device itself or the PCI host bridge.
  *
  * Function 8, "Reset Delay," applies to the entire hierarchy below a PCI
@@ -1206,8 +1206,8 @@ static void pci_acpi_optimize_delay(struct pci_dev *pdev,
                }
                if (elements[3].type == ACPI_TYPE_INTEGER) {
                        value = (int)elements[3].integer.value / 1000;
-                       if (value < PCI_PM_D3_WAIT)
-                               pdev->d3_delay = value;
+                       if (value < PCI_PM_D3HOT_WAIT)
+                               pdev->d3hot_delay = value;
                }
        }
        ACPI_FREE(obj);
index 449466f71040d22e0709800862fc170c66904c52..40be221e69cf4fecc221bf927004dbb0a3ead9ea 100644 (file)
@@ -969,12 +969,6 @@ static int pci_pm_resume(struct device *dev)
 
 #ifdef CONFIG_HIBERNATE_CALLBACKS
 
-/*
- * pcibios_pm_ops - provide arch-specific hooks when a PCI device is doing
- * a hibernate transition
- */
-struct dev_pm_ops __weak pcibios_pm_ops;
-
 static int pci_pm_freeze(struct device *dev)
 {
        struct pci_dev *pci_dev = to_pci_dev(dev);
@@ -1033,9 +1027,6 @@ static int pci_pm_freeze_noirq(struct device *dev)
 
        pci_pm_set_unknown_state(pci_dev);
 
-       if (pcibios_pm_ops.freeze_noirq)
-               return pcibios_pm_ops.freeze_noirq(dev);
-
        return 0;
 }
 
@@ -1043,13 +1034,6 @@ static int pci_pm_thaw_noirq(struct device *dev)
 {
        struct pci_dev *pci_dev = to_pci_dev(dev);
        const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-       int error;
-
-       if (pcibios_pm_ops.thaw_noirq) {
-               error = pcibios_pm_ops.thaw_noirq(dev);
-               if (error)
-                       return error;
-       }
 
        /*
         * The pm->thaw_noirq() callback assumes the device has been
@@ -1174,9 +1158,6 @@ static int pci_pm_poweroff_noirq(struct device *dev)
 
        pci_fixup_device(pci_fixup_suspend_late, pci_dev);
 
-       if (pcibios_pm_ops.poweroff_noirq)
-               return pcibios_pm_ops.poweroff_noirq(dev);
-
        return 0;
 }
 
@@ -1184,13 +1165,6 @@ static int pci_pm_restore_noirq(struct device *dev)
 {
        struct pci_dev *pci_dev = to_pci_dev(dev);
        const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-       int error;
-
-       if (pcibios_pm_ops.restore_noirq) {
-               error = pcibios_pm_ops.restore_noirq(dev);
-               if (error)
-                       return error;
-       }
 
        pci_pm_default_resume_early(pci_dev);
        pci_fixup_device(pci_fixup_resume_early, pci_dev);
index 5142d749aee56f3f22ec32f72bda061ad3a2b2a9..d15c881e2e7e70bbc39bb8ec73bba3ba9063a1b7 100644 (file)
@@ -708,6 +708,7 @@ static ssize_t pci_read_config(struct file *filp, struct kobject *kobj,
                data[off - init_off + 3] = (val >> 24) & 0xff;
                off += 4;
                size -= 4;
+               cond_resched();
        }
 
        if (size >= 2) {
index 42364a1a7cb75ce69238fc9e45e040918d97e104..0e63e0e777088f86d8d75231b012d58e3d024acd 100644 (file)
@@ -46,7 +46,7 @@ EXPORT_SYMBOL(isa_dma_bridge_buggy);
 int pci_pci_problems;
 EXPORT_SYMBOL(pci_pci_problems);
 
-unsigned int pci_pm_d3_delay;
+unsigned int pci_pm_d3hot_delay;
 
 static void pci_pme_list_scan(struct work_struct *work);
 
@@ -63,10 +63,10 @@ struct pci_pme_device {
 
 static void pci_dev_d3_sleep(struct pci_dev *dev)
 {
-       unsigned int delay = dev->d3_delay;
+       unsigned int delay = dev->d3hot_delay;
 
-       if (delay < pci_pm_d3_delay)
-               delay = pci_pm_d3_delay;
+       if (delay < pci_pm_d3hot_delay)
+               delay = pci_pm_d3hot_delay;
 
        if (delay)
                msleep(delay);
@@ -98,7 +98,19 @@ unsigned long pci_hotplug_mmio_pref_size = DEFAULT_HOTPLUG_MMIO_PREF_SIZE;
 #define DEFAULT_HOTPLUG_BUS_SIZE       1
 unsigned long pci_hotplug_bus_size = DEFAULT_HOTPLUG_BUS_SIZE;
 
+
+/* PCIe MPS/MRRS strategy; can be overridden by kernel command-line param */
+#ifdef CONFIG_PCIE_BUS_TUNE_OFF
+enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_TUNE_OFF;
+#elif defined CONFIG_PCIE_BUS_SAFE
+enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_SAFE;
+#elif defined CONFIG_PCIE_BUS_PERFORMANCE
+enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_PERFORMANCE;
+#elif defined CONFIG_PCIE_BUS_PEER2PEER
+enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_PEER2PEER;
+#else
 enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_DEFAULT;
+#endif
 
 /*
  * The default CLS is used if arch didn't set CLS explicitly and not
@@ -873,6 +885,10 @@ static void pci_std_enable_acs(struct pci_dev *dev)
        /* Upstream Forwarding */
        ctrl |= (cap & PCI_ACS_UF);
 
+       /* Enable Translation Blocking for external devices */
+       if (dev->external_facing || dev->untrusted)
+               ctrl |= (cap & PCI_ACS_TB);
+
        pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl);
 }
 
@@ -1062,7 +1078,7 @@ static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
        if (state == PCI_D3hot || dev->current_state == PCI_D3hot)
                pci_dev_d3_sleep(dev);
        else if (state == PCI_D2 || dev->current_state == PCI_D2)
-               msleep(PCI_PM_D2_DELAY);
+               udelay(PCI_PM_D2_DELAY);
 
        pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
        dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK);
@@ -3010,7 +3026,7 @@ void pci_pm_init(struct pci_dev *dev)
        }
 
        dev->pm_cap = pm;
-       dev->d3_delay = PCI_PM_D3_WAIT;
+       dev->d3hot_delay = PCI_PM_D3HOT_WAIT;
        dev->d3cold_delay = PCI_PM_D3COLD_WAIT;
        dev->bridge_d3 = pci_bridge_d3_possible(dev);
        dev->d3cold_allowed = true;
@@ -3035,7 +3051,7 @@ void pci_pm_init(struct pci_dev *dev)
                         (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "",
                         (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "",
                         (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "",
-                        (pmc & PCI_PM_CAP_PME_D3) ? " D3hot" : "",
+                        (pmc & PCI_PM_CAP_PME_D3hot) ? " D3hot" : "",
                         (pmc & PCI_PM_CAP_PME_D3cold) ? " D3cold" : "");
                dev->pme_support = pmc >> PCI_PM_CAP_PME_SHIFT;
                dev->pme_poll = true;
@@ -4618,7 +4634,7 @@ static int pci_af_flr(struct pci_dev *dev, int probe)
  *
  * NOTE: This causes the caller to sleep for twice the device power transition
  * cooldown period, which for the D0->D3hot and D3hot->D0 transitions is 10 ms
- * by default (i.e. unless the @dev's d3_delay field has a different value).
+ * by default (i.e. unless the @dev's d3hot_delay field has a different value).
  * Moreover, only devices in D0 can be reset by this function.
  */
 static int pci_pm_reset(struct pci_dev *dev, int probe)
@@ -4698,9 +4714,7 @@ static bool pcie_wait_for_link_delay(struct pci_dev *pdev, bool active,
        }
        if (active && ret)
                msleep(delay);
-       else if (ret != active)
-               pci_info(pdev, "Data Link Layer Link Active not %s in 1000 msec\n",
-                       active ? "set" : "cleared");
+
        return ret == active;
 }
 
@@ -4825,6 +4839,7 @@ void pci_bridge_wait_for_secondary_bus(struct pci_dev *dev)
                        delay);
                if (!pcie_wait_for_link_delay(dev, true, delay)) {
                        /* Did not train, no need to wait any further */
+                       pci_info(dev, "Data Link Layer Link Active not set in 1000 msec\n");
                        return;
                }
        }
index fa12f7cbc1a095ea3e7e2cdca90ad511be4c3c00..f86cae9aa1f4102c8ab684a7c930b82b5c8bdf2a 100644 (file)
@@ -43,10 +43,9 @@ int pci_probe_reset_function(struct pci_dev *dev);
 int pci_bridge_secondary_bus_reset(struct pci_dev *dev);
 int pci_bus_error_reset(struct pci_dev *dev);
 
-#define PCI_PM_D2_DELAY         200
-#define PCI_PM_D3_WAIT          10
-#define PCI_PM_D3COLD_WAIT      100
-#define PCI_PM_BUS_WAIT         50
+#define PCI_PM_D2_DELAY         200    /* usec; see PCIe r4.0, sec 5.9.1 */
+#define PCI_PM_D3HOT_WAIT       10     /* msec */
+#define PCI_PM_D3COLD_WAIT      100    /* msec */
 
 /**
  * struct pci_platform_pm_ops - Firmware PM callbacks
@@ -178,7 +177,7 @@ extern struct mutex pci_slot_mutex;
 
 extern raw_spinlock_t pci_lock;
 
-extern unsigned int pci_pm_d3_delay;
+extern unsigned int pci_pm_d3hot_delay;
 
 #ifdef CONFIG_PCI_MSI
 void pci_no_msi(void);
index 253c30cc19678a99f0280da6db28a08fb0bec0ee..ac0557a305aff383f7a0d9e7ea4112904081f351 100644 (file)
@@ -74,14 +74,6 @@ struct pcie_link_state {
         * has one slot under it, so at most there are 8 functions.
         */
        struct aspm_latency acceptable[8];
-
-       /* L1 PM Substate info */
-       struct {
-               u32 up_cap_ptr;         /* L1SS cap ptr in upstream dev */
-               u32 dw_cap_ptr;         /* L1SS cap ptr in downstream dev */
-               u32 ctl1;               /* value to be programmed in ctl1 */
-               u32 ctl2;               /* value to be programmed in ctl2 */
-       } l1ss;
 };
 
 static int aspm_disabled, aspm_force;
@@ -308,8 +300,10 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
 }
 
 /* Convert L0s latency encoding to ns */
-static u32 calc_l0s_latency(u32 encoding)
+static u32 calc_l0s_latency(u32 lnkcap)
 {
+       u32 encoding = (lnkcap & PCI_EXP_LNKCAP_L0SEL) >> 12;
+
        if (encoding == 0x7)
                return (5 * 1000);      /* > 4us */
        return (64 << encoding);
@@ -324,8 +318,10 @@ static u32 calc_l0s_acceptable(u32 encoding)
 }
 
 /* Convert L1 latency encoding to ns */
-static u32 calc_l1_latency(u32 encoding)
+static u32 calc_l1_latency(u32 lnkcap)
 {
+       u32 encoding = (lnkcap & PCI_EXP_LNKCAP_L1EL) >> 15;
+
        if (encoding == 0x7)
                return (65 * 1000);     /* > 64us */
        return (1000 << encoding);
@@ -380,58 +376,6 @@ static void encode_l12_threshold(u32 threshold_us, u32 *scale, u32 *value)
        }
 }
 
-struct aspm_register_info {
-       u32 support:2;
-       u32 enabled:2;
-       u32 latency_encoding_l0s;
-       u32 latency_encoding_l1;
-
-       /* L1 substates */
-       u32 l1ss_cap_ptr;
-       u32 l1ss_cap;
-       u32 l1ss_ctl1;
-       u32 l1ss_ctl2;
-};
-
-static void pcie_get_aspm_reg(struct pci_dev *pdev,
-                             struct aspm_register_info *info)
-{
-       u16 reg16;
-       u32 reg32;
-
-       pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, &reg32);
-       info->support = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10;
-       info->latency_encoding_l0s = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12;
-       info->latency_encoding_l1  = (reg32 & PCI_EXP_LNKCAP_L1EL) >> 15;
-       pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &reg16);
-       info->enabled = reg16 & PCI_EXP_LNKCTL_ASPMC;
-
-       /* Read L1 PM substate capabilities */
-       info->l1ss_cap = info->l1ss_ctl1 = info->l1ss_ctl2 = 0;
-       info->l1ss_cap_ptr = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_L1SS);
-       if (!info->l1ss_cap_ptr)
-               return;
-       pci_read_config_dword(pdev, info->l1ss_cap_ptr + PCI_L1SS_CAP,
-                             &info->l1ss_cap);
-       if (!(info->l1ss_cap & PCI_L1SS_CAP_L1_PM_SS)) {
-               info->l1ss_cap = 0;
-               return;
-       }
-
-       /*
-        * If we don't have LTR for the entire path from the Root Complex
-        * to this device, we can't use ASPM L1.2 because it relies on the
-        * LTR_L1.2_THRESHOLD.  See PCIe r4.0, secs 5.5.4, 6.18.
-        */
-       if (!pdev->ltr_path)
-               info->l1ss_cap &= ~PCI_L1SS_CAP_ASPM_L1_2;
-
-       pci_read_config_dword(pdev, info->l1ss_cap_ptr + PCI_L1SS_CTL1,
-                             &info->l1ss_ctl1);
-       pci_read_config_dword(pdev, info->l1ss_cap_ptr + PCI_L1SS_CTL2,
-                             &info->l1ss_ctl2);
-}
-
 static void pcie_aspm_check_latency(struct pci_dev *endpoint)
 {
        u32 latency, l1_switch_latency = 0;
@@ -493,39 +437,49 @@ static struct pci_dev *pci_function_0(struct pci_bus *linkbus)
        return NULL;
 }
 
+static void pci_clear_and_set_dword(struct pci_dev *pdev, int pos,
+                                   u32 clear, u32 set)
+{
+       u32 val;
+
+       pci_read_config_dword(pdev, pos, &val);
+       val &= ~clear;
+       val |= set;
+       pci_write_config_dword(pdev, pos, val);
+}
+
 /* Calculate L1.2 PM substate timing parameters */
 static void aspm_calc_l1ss_info(struct pcie_link_state *link,
-                               struct aspm_register_info *upreg,
-                               struct aspm_register_info *dwreg)
+                               u32 parent_l1ss_cap, u32 child_l1ss_cap)
 {
+       struct pci_dev *child = link->downstream, *parent = link->pdev;
        u32 val1, val2, scale1, scale2;
        u32 t_common_mode, t_power_on, l1_2_threshold, scale, value;
-
-       link->l1ss.up_cap_ptr = upreg->l1ss_cap_ptr;
-       link->l1ss.dw_cap_ptr = dwreg->l1ss_cap_ptr;
-       link->l1ss.ctl1 = link->l1ss.ctl2 = 0;
+       u32 ctl1 = 0, ctl2 = 0;
+       u32 pctl1, pctl2, cctl1, cctl2;
+       u32 pl1_2_enables, cl1_2_enables;
 
        if (!(link->aspm_support & ASPM_STATE_L1_2_MASK))
                return;
 
        /* Choose the greater of the two Port Common_Mode_Restore_Times */
-       val1 = (upreg->l1ss_cap & PCI_L1SS_CAP_CM_RESTORE_TIME) >> 8;
-       val2 = (dwreg->l1ss_cap & PCI_L1SS_CAP_CM_RESTORE_TIME) >> 8;
+       val1 = (parent_l1ss_cap & PCI_L1SS_CAP_CM_RESTORE_TIME) >> 8;
+       val2 = (child_l1ss_cap & PCI_L1SS_CAP_CM_RESTORE_TIME) >> 8;
        t_common_mode = max(val1, val2);
 
        /* Choose the greater of the two Port T_POWER_ON times */
-       val1   = (upreg->l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_VALUE) >> 19;
-       scale1 = (upreg->l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_SCALE) >> 16;
-       val2   = (dwreg->l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_VALUE) >> 19;
-       scale2 = (dwreg->l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_SCALE) >> 16;
-
-       if (calc_l1ss_pwron(link->pdev, scale1, val1) >
-           calc_l1ss_pwron(link->downstream, scale2, val2)) {
-               link->l1ss.ctl2 |= scale1 | (val1 << 3);
-               t_power_on = calc_l1ss_pwron(link->pdev, scale1, val1);
+       val1   = (parent_l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_VALUE) >> 19;
+       scale1 = (parent_l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_SCALE) >> 16;
+       val2   = (child_l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_VALUE) >> 19;
+       scale2 = (child_l1ss_cap & PCI_L1SS_CAP_P_PWR_ON_SCALE) >> 16;
+
+       if (calc_l1ss_pwron(parent, scale1, val1) >
+           calc_l1ss_pwron(child, scale2, val2)) {
+               ctl2 |= scale1 | (val1 << 3);
+               t_power_on = calc_l1ss_pwron(parent, scale1, val1);
        } else {
-               link->l1ss.ctl2 |= scale2 | (val2 << 3);
-               t_power_on = calc_l1ss_pwron(link->downstream, scale2, val2);
+               ctl2 |= scale2 | (val2 << 3);
+               t_power_on = calc_l1ss_pwron(child, scale2, val2);
        }
 
        /*
@@ -540,14 +494,60 @@ static void aspm_calc_l1ss_info(struct pcie_link_state *link,
         */
        l1_2_threshold = 2 + 4 + t_common_mode + t_power_on;
        encode_l12_threshold(l1_2_threshold, &scale, &value);
-       link->l1ss.ctl1 |= t_common_mode << 8 | scale << 29 | value << 16;
+       ctl1 |= t_common_mode << 8 | scale << 29 | value << 16;
+
+       pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CTL1, &pctl1);
+       pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CTL2, &pctl2);
+       pci_read_config_dword(child, child->l1ss + PCI_L1SS_CTL1, &cctl1);
+       pci_read_config_dword(child, child->l1ss + PCI_L1SS_CTL2, &cctl2);
+
+       if (ctl1 == pctl1 && ctl1 == cctl1 &&
+           ctl2 == pctl2 && ctl2 == cctl2)
+               return;
+
+       /* Disable L1.2 while updating.  See PCIe r5.0, sec 5.5.4, 7.8.3.3 */
+       pl1_2_enables = pctl1 & PCI_L1SS_CTL1_L1_2_MASK;
+       cl1_2_enables = cctl1 & PCI_L1SS_CTL1_L1_2_MASK;
+
+       if (pl1_2_enables || cl1_2_enables) {
+               pci_clear_and_set_dword(child, child->l1ss + PCI_L1SS_CTL1,
+                                       PCI_L1SS_CTL1_L1_2_MASK, 0);
+               pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
+                                       PCI_L1SS_CTL1_L1_2_MASK, 0);
+       }
+
+       /* Program T_POWER_ON times in both ports */
+       pci_write_config_dword(parent, parent->l1ss + PCI_L1SS_CTL2, ctl2);
+       pci_write_config_dword(child, child->l1ss + PCI_L1SS_CTL2, ctl2);
+
+       /* Program Common_Mode_Restore_Time in upstream device */
+       pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
+                               PCI_L1SS_CTL1_CM_RESTORE_TIME, ctl1);
+
+       /* Program LTR_L1.2_THRESHOLD time in both ports */
+       pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
+                               PCI_L1SS_CTL1_LTR_L12_TH_VALUE |
+                               PCI_L1SS_CTL1_LTR_L12_TH_SCALE, ctl1);
+       pci_clear_and_set_dword(child, child->l1ss + PCI_L1SS_CTL1,
+                               PCI_L1SS_CTL1_LTR_L12_TH_VALUE |
+                               PCI_L1SS_CTL1_LTR_L12_TH_SCALE, ctl1);
+
+       if (pl1_2_enables || cl1_2_enables) {
+               pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1, 0,
+                                       pl1_2_enables);
+               pci_clear_and_set_dword(child, child->l1ss + PCI_L1SS_CTL1, 0,
+                                       cl1_2_enables);
+       }
 }
 
 static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
 {
        struct pci_dev *child = link->downstream, *parent = link->pdev;
+       u32 parent_lnkcap, child_lnkcap;
+       u16 parent_lnkctl, child_lnkctl;
+       u32 parent_l1ss_cap, child_l1ss_cap;
+       u32 parent_l1ss_ctl1 = 0, child_l1ss_ctl1 = 0;
        struct pci_bus *linkbus = parent->subordinate;
-       struct aspm_register_info upreg, dwreg;
 
        if (blacklist) {
                /* Set enabled/disable so that we will disable ASPM later */
@@ -556,26 +556,28 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
                return;
        }
 
-       /* Get upstream/downstream components' register state */
-       pcie_get_aspm_reg(parent, &upreg);
-       pcie_get_aspm_reg(child, &dwreg);
-
        /*
         * If ASPM not supported, don't mess with the clocks and link,
         * bail out now.
         */
-       if (!(upreg.support & dwreg.support))
+       pcie_capability_read_dword(parent, PCI_EXP_LNKCAP, &parent_lnkcap);
+       pcie_capability_read_dword(child, PCI_EXP_LNKCAP, &child_lnkcap);
+       if (!(parent_lnkcap & child_lnkcap & PCI_EXP_LNKCAP_ASPMS))
                return;
 
        /* Configure common clock before checking latencies */
        pcie_aspm_configure_common_clock(link);
 
        /*
-        * Re-read upstream/downstream components' register state
-        * after clock configuration
+        * Re-read upstream/downstream components' register state after
+        * clock configuration.  L0s & L1 exit latencies in the otherwise
+        * read-only Link Capabilities may change depending on common clock
+        * configuration (PCIe r5.0, sec 7.5.3.6).
         */
-       pcie_get_aspm_reg(parent, &upreg);
-       pcie_get_aspm_reg(child, &dwreg);
+       pcie_capability_read_dword(parent, PCI_EXP_LNKCAP, &parent_lnkcap);
+       pcie_capability_read_dword(child, PCI_EXP_LNKCAP, &child_lnkcap);
+       pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &parent_lnkctl);
+       pcie_capability_read_word(child, PCI_EXP_LNKCTL, &child_lnkctl);
 
        /*
         * Setup L0s state
@@ -584,44 +586,71 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
         * given link unless components on both sides of the link each
         * support L0s.
         */
-       if (dwreg.support & upreg.support & PCIE_LINK_STATE_L0S)
+       if (parent_lnkcap & child_lnkcap & PCI_EXP_LNKCAP_ASPM_L0S)
                link->aspm_support |= ASPM_STATE_L0S;
-       if (dwreg.enabled & PCIE_LINK_STATE_L0S)
+
+       if (child_lnkctl & PCI_EXP_LNKCTL_ASPM_L0S)
                link->aspm_enabled |= ASPM_STATE_L0S_UP;
-       if (upreg.enabled & PCIE_LINK_STATE_L0S)
+       if (parent_lnkctl & PCI_EXP_LNKCTL_ASPM_L0S)
                link->aspm_enabled |= ASPM_STATE_L0S_DW;
-       link->latency_up.l0s = calc_l0s_latency(upreg.latency_encoding_l0s);
-       link->latency_dw.l0s = calc_l0s_latency(dwreg.latency_encoding_l0s);
+       link->latency_up.l0s = calc_l0s_latency(parent_lnkcap);
+       link->latency_dw.l0s = calc_l0s_latency(child_lnkcap);
 
        /* Setup L1 state */
-       if (upreg.support & dwreg.support & PCIE_LINK_STATE_L1)
+       if (parent_lnkcap & child_lnkcap & PCI_EXP_LNKCAP_ASPM_L1)
                link->aspm_support |= ASPM_STATE_L1;
-       if (upreg.enabled & dwreg.enabled & PCIE_LINK_STATE_L1)
+
+       if (parent_lnkctl & child_lnkctl & PCI_EXP_LNKCTL_ASPM_L1)
                link->aspm_enabled |= ASPM_STATE_L1;
-       link->latency_up.l1 = calc_l1_latency(upreg.latency_encoding_l1);
-       link->latency_dw.l1 = calc_l1_latency(dwreg.latency_encoding_l1);
+       link->latency_up.l1 = calc_l1_latency(parent_lnkcap);
+       link->latency_dw.l1 = calc_l1_latency(child_lnkcap);
 
        /* Setup L1 substate */
-       if (upreg.l1ss_cap & dwreg.l1ss_cap & PCI_L1SS_CAP_ASPM_L1_1)
+       pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CAP,
+                             &parent_l1ss_cap);
+       pci_read_config_dword(child, child->l1ss + PCI_L1SS_CAP,
+                             &child_l1ss_cap);
+
+       if (!(parent_l1ss_cap & PCI_L1SS_CAP_L1_PM_SS))
+               parent_l1ss_cap = 0;
+       if (!(child_l1ss_cap & PCI_L1SS_CAP_L1_PM_SS))
+               child_l1ss_cap = 0;
+
+       /*
+        * If we don't have LTR for the entire path from the Root Complex
+        * to this device, we can't use ASPM L1.2 because it relies on the
+        * LTR_L1.2_THRESHOLD.  See PCIe r4.0, secs 5.5.4, 6.18.
+        */
+       if (!child->ltr_path)
+               child_l1ss_cap &= ~PCI_L1SS_CAP_ASPM_L1_2;
+
+       if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_ASPM_L1_1)
                link->aspm_support |= ASPM_STATE_L1_1;
-       if (upreg.l1ss_cap & dwreg.l1ss_cap & PCI_L1SS_CAP_ASPM_L1_2)
+       if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_ASPM_L1_2)
                link->aspm_support |= ASPM_STATE_L1_2;
-       if (upreg.l1ss_cap & dwreg.l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_1)
+       if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_1)
                link->aspm_support |= ASPM_STATE_L1_1_PCIPM;
-       if (upreg.l1ss_cap & dwreg.l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_2)
+       if (parent_l1ss_cap & child_l1ss_cap & PCI_L1SS_CAP_PCIPM_L1_2)
                link->aspm_support |= ASPM_STATE_L1_2_PCIPM;
 
-       if (upreg.l1ss_ctl1 & dwreg.l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_1)
+       if (parent_l1ss_cap)
+               pci_read_config_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
+                                     &parent_l1ss_ctl1);
+       if (child_l1ss_cap)
+               pci_read_config_dword(child, child->l1ss + PCI_L1SS_CTL1,
+                                     &child_l1ss_ctl1);
+
+       if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_1)
                link->aspm_enabled |= ASPM_STATE_L1_1;
-       if (upreg.l1ss_ctl1 & dwreg.l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_2)
+       if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_ASPM_L1_2)
                link->aspm_enabled |= ASPM_STATE_L1_2;
-       if (upreg.l1ss_ctl1 & dwreg.l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_1)
+       if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_1)
                link->aspm_enabled |= ASPM_STATE_L1_1_PCIPM;
-       if (upreg.l1ss_ctl1 & dwreg.l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_2)
+       if (parent_l1ss_ctl1 & child_l1ss_ctl1 & PCI_L1SS_CTL1_PCIPM_L1_2)
                link->aspm_enabled |= ASPM_STATE_L1_2_PCIPM;
 
        if (link->aspm_support & ASPM_STATE_L1SS)
-               aspm_calc_l1ss_info(link, &upreg, &dwreg);
+               aspm_calc_l1ss_info(link, parent_l1ss_cap, child_l1ss_cap);
 
        /* Save default state */
        link->aspm_default = link->aspm_enabled;
@@ -651,24 +680,11 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
        }
 }
 
-static void pci_clear_and_set_dword(struct pci_dev *pdev, int pos,
-                                   u32 clear, u32 set)
-{
-       u32 val;
-
-       pci_read_config_dword(pdev, pos, &val);
-       val &= ~clear;
-       val |= set;
-       pci_write_config_dword(pdev, pos, val);
-}
-
 /* Configure the ASPM L1 substates */
 static void pcie_config_aspm_l1ss(struct pcie_link_state *link, u32 state)
 {
        u32 val, enable_req;
        struct pci_dev *child = link->downstream, *parent = link->pdev;
-       u32 up_cap_ptr = link->l1ss.up_cap_ptr;
-       u32 dw_cap_ptr = link->l1ss.dw_cap_ptr;
 
        enable_req = (link->aspm_enabled ^ state) & state;
 
@@ -686,9 +702,9 @@ static void pcie_config_aspm_l1ss(struct pcie_link_state *link, u32 state)
         */
 
        /* Disable all L1 substates */
-       pci_clear_and_set_dword(child, dw_cap_ptr + PCI_L1SS_CTL1,
+       pci_clear_and_set_dword(child, child->l1ss + PCI_L1SS_CTL1,
                                PCI_L1SS_CTL1_L1SS_MASK, 0);
-       pci_clear_and_set_dword(parent, up_cap_ptr + PCI_L1SS_CTL1,
+       pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
                                PCI_L1SS_CTL1_L1SS_MASK, 0);
        /*
         * If needed, disable L1, and it gets enabled later
@@ -701,30 +717,6 @@ static void pcie_config_aspm_l1ss(struct pcie_link_state *link, u32 state)
                                                   PCI_EXP_LNKCTL_ASPM_L1, 0);
        }
 
-       if (enable_req & ASPM_STATE_L1_2_MASK) {
-
-               /* Program T_POWER_ON times in both ports */
-               pci_write_config_dword(parent, up_cap_ptr + PCI_L1SS_CTL2,
-                                      link->l1ss.ctl2);
-               pci_write_config_dword(child, dw_cap_ptr + PCI_L1SS_CTL2,
-                                      link->l1ss.ctl2);
-
-               /* Program Common_Mode_Restore_Time in upstream device */
-               pci_clear_and_set_dword(parent, up_cap_ptr + PCI_L1SS_CTL1,
-                                       PCI_L1SS_CTL1_CM_RESTORE_TIME,
-                                       link->l1ss.ctl1);
-
-               /* Program LTR_L1.2_THRESHOLD time in both ports */
-               pci_clear_and_set_dword(parent, up_cap_ptr + PCI_L1SS_CTL1,
-                                       PCI_L1SS_CTL1_LTR_L12_TH_VALUE |
-                                       PCI_L1SS_CTL1_LTR_L12_TH_SCALE,
-                                       link->l1ss.ctl1);
-               pci_clear_and_set_dword(child, dw_cap_ptr + PCI_L1SS_CTL1,
-                                       PCI_L1SS_CTL1_LTR_L12_TH_VALUE |
-                                       PCI_L1SS_CTL1_LTR_L12_TH_SCALE,
-                                       link->l1ss.ctl1);
-       }
-
        val = 0;
        if (state & ASPM_STATE_L1_1)
                val |= PCI_L1SS_CTL1_ASPM_L1_1;
@@ -736,9 +728,9 @@ static void pcie_config_aspm_l1ss(struct pcie_link_state *link, u32 state)
                val |= PCI_L1SS_CTL1_PCIPM_L1_2;
 
        /* Enable what we need to enable */
-       pci_clear_and_set_dword(parent, up_cap_ptr + PCI_L1SS_CTL1,
+       pci_clear_and_set_dword(parent, parent->l1ss + PCI_L1SS_CTL1,
                                PCI_L1SS_CTL1_L1SS_MASK, val);
-       pci_clear_and_set_dword(child, dw_cap_ptr + PCI_L1SS_CTL1,
+       pci_clear_and_set_dword(child, child->l1ss + PCI_L1SS_CTL1,
                                PCI_L1SS_CTL1_L1SS_MASK, val);
 }
 
index daa9a4153776cefeb6e842a454a0c455454bb6e5..e05aba86a317920d1520b2a1773454360266a0e2 100644 (file)
@@ -103,7 +103,8 @@ pci_ers_result_t dpc_reset_link(struct pci_dev *pdev)
         * Wait until the Link is inactive, then clear DPC Trigger Status
         * to allow the Port to leave DPC.
         */
-       pcie_wait_for_link(pdev, false);
+       if (!pcie_wait_for_link(pdev, false))
+               pci_info(pdev, "Data Link Layer Link Active not cleared in 1000 msec\n");
 
        if (pdev->dpc_rp_extensions && dpc_wait_rp_inactive(pdev))
                return PCI_ERS_RESULT_DISCONNECT;
@@ -111,8 +112,10 @@ pci_ers_result_t dpc_reset_link(struct pci_dev *pdev)
        pci_write_config_word(pdev, cap + PCI_EXP_DPC_STATUS,
                              PCI_EXP_DPC_STATUS_TRIGGER);
 
-       if (!pcie_wait_for_link(pdev, true))
+       if (!pcie_wait_for_link(pdev, true)) {
+               pci_info(pdev, "Data Link Layer Link Active not set in 1000 msec\n");
                return PCI_ERS_RESULT_DISCONNECT;
+       }
 
        return PCI_ERS_RESULT_RECOVERED;
 }
index 03d37128a24f205602b7f6e9299dde8bb5fea81e..06f6bbcd81316889c98bc6f0f2396876948ac0eb 100644 (file)
@@ -2106,6 +2106,9 @@ static void pci_configure_ltr(struct pci_dev *dev)
        if (!pci_is_pcie(dev))
                return;
 
+       /* Read L1 PM substate capabilities */
+       dev->l1ss = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_L1SS);
+
        pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap);
        if (!(cap & PCI_EXP_DEVCAP2_LTR))
                return;
index bdf9b52567e030640b5ee98ad9e1cded7be37f72..eefed9d269453cc1b6b29d2bd623b5f315ee0189 100644 (file)
@@ -1846,7 +1846,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL,      PCI_DEVICE_ID_INTEL_PXHV,       quirk_pci
  */
 static void quirk_intel_pcie_pm(struct pci_dev *dev)
 {
-       pci_pm_d3_delay = 120;
+       pci_pm_d3hot_delay = 120;
        dev->no_d1d2 = 1;
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,   0x25e2, quirk_intel_pcie_pm);
@@ -1873,12 +1873,12 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL,    0x260b, quirk_intel_pcie_pm);
 
 static void quirk_d3hot_delay(struct pci_dev *dev, unsigned int delay)
 {
-       if (dev->d3_delay >= delay)
+       if (dev->d3hot_delay >= delay)
                return;
 
-       dev->d3_delay = delay;
+       dev->d3hot_delay = delay;
        pci_info(dev, "extending delay after power-on from D3hot to %d msec\n",
-                dev->d3_delay);
+                dev->d3hot_delay);
 }
 
 static void quirk_radeon_pm(struct pci_dev *dev)
@@ -3387,36 +3387,36 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0152, disable_igfx_irq);
  * PCI devices which are on Intel chips can skip the 10ms delay
  * before entering D3 mode.
  */
-static void quirk_remove_d3_delay(struct pci_dev *dev)
-{
-       dev->d3_delay = 0;
-}
-/* C600 Series devices do not need 10ms d3_delay */
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0412, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c00, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c0c, quirk_remove_d3_delay);
-/* Lynxpoint-H PCH devices do not need 10ms d3_delay */
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c02, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c18, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c1c, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c20, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c22, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c26, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c2d, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c31, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3a, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3d, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c4e, quirk_remove_d3_delay);
-/* Intel Cherrytrail devices do not need 10ms d3_delay */
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2280, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2298, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x229c, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b0, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b5, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b7, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b8, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22d8, quirk_remove_d3_delay);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22dc, quirk_remove_d3_delay);
+static void quirk_remove_d3hot_delay(struct pci_dev *dev)
+{
+       dev->d3hot_delay = 0;
+}
+/* C600 Series devices do not need 10ms d3hot_delay */
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0412, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c00, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c0c, quirk_remove_d3hot_delay);
+/* Lynxpoint-H PCH devices do not need 10ms d3hot_delay */
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c02, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c18, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c1c, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c20, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c22, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c26, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c2d, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c31, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3a, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3d, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c4e, quirk_remove_d3hot_delay);
+/* Intel Cherrytrail devices do not need 10ms d3hot_delay */
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2280, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2298, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x229c, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b0, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b5, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b7, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b8, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22d8, quirk_remove_d3hot_delay);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22dc, quirk_remove_d3hot_delay);
 
 /*
  * Some devices may pass our check in pci_intx_mask_supported() if
@@ -4949,6 +4949,13 @@ static void pci_quirk_enable_intel_rp_mpc_acs(struct pci_dev *dev)
        }
 }
 
+/*
+ * Currently this quirk does the equivalent of
+ * PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF
+ *
+ * TODO: This quirk also needs to do equivalent of PCI_ACS_TB,
+ * if dev->external_facing || dev->untrusted
+ */
 static int pci_quirk_enable_intel_pch_acs(struct pci_dev *dev)
 {
        if (!pci_quirk_intel_pch_acs_match(dev))
@@ -4988,6 +4995,9 @@ static int pci_quirk_enable_intel_spt_pch_acs(struct pci_dev *dev)
        ctrl |= (cap & PCI_ACS_CR);
        ctrl |= (cap & PCI_ACS_UF);
 
+       if (dev->external_facing || dev->untrusted)
+               ctrl |= (cap & PCI_ACS_TB);
+
        pci_write_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, ctrl);
 
        pci_info(dev, "Intel SPT PCH root port ACS workaround enabled\n");
index a000a1e316f78d705f320cefd8f855b017ccd655..beba430a197e19c7ad6e59342be33bde65f5a1b2 100644 (file)
@@ -1573,7 +1573,7 @@ static int atomisp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *i
        spin_lock_init(&isp->lock);
 
        /* This is not a true PCI device on SoC, so the delay is not needed. */
-       pdev->d3_delay = 0;
+       pdev->d3hot_delay = 0;
 
        pci_set_drvdata(pdev, isp);
 
index 1af5cb02ef7f90f4769047d8b60ad33b66677f99..033ce74f02e812b9707138209dd7c112d6482b1f 100644 (file)
@@ -51,6 +51,7 @@ extern const struct pci_ecam_ops pci_generic_ecam_ops;
 
 #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
 extern const struct pci_ecam_ops pci_32b_ops;  /* 32-bit accesses only */
+extern const struct pci_ecam_ops pci_32b_read_ops; /* 32-bit read only */
 extern const struct pci_ecam_ops hisi_pcie_ops;        /* HiSilicon */
 extern const struct pci_ecam_ops thunder_pem_ecam_ops; /* Cavium ThunderX 1.x & 2.x */
 extern const struct pci_ecam_ops pci_thunder_ecam_ops; /* Cavium ThunderX 1.x */
index 835530605c0d7b4a4626f65c5b869bc49f48fd5c..bc529610b5f49f28d1e54dbe6bf89193dc17b0ba 100644 (file)
@@ -373,13 +373,14 @@ struct pci_dev {
                                                      user sysfs */
        unsigned int    clear_retrain_link:1;   /* Need to clear Retrain Link
                                                   bit manually */
-       unsigned int    d3_delay;       /* D3->D0 transition time in ms */
+       unsigned int    d3hot_delay;    /* D3hot->D0 transition time in ms */
        unsigned int    d3cold_delay;   /* D3cold->D0 transition time in ms */
 
 #ifdef CONFIG_PCIEASPM
        struct pcie_link_state  *link_state;    /* ASPM link state */
        unsigned int    ltr_path:1;     /* Latency Tolerance Reporting
                                           supported from root to here */
+       int             l1ss;           /* L1SS Capability pointer */
 #endif
        unsigned int    eetlp_prefix_path:1;    /* End-to-End TLP Prefix */
 
@@ -2034,10 +2035,6 @@ int pcibios_alloc_irq(struct pci_dev *dev);
 void pcibios_free_irq(struct pci_dev *dev);
 resource_size_t pcibios_default_alignment(void);
 
-#ifdef CONFIG_HIBERNATE_CALLBACKS
-extern struct dev_pm_ops pcibios_pm_ops;
-#endif
-
 #if defined(CONFIG_PCI_MMCONFIG) || defined(CONFIG_ACPI_MCFG)
 void __init pci_mmcfg_early_init(void);
 void __init pci_mmcfg_late_init(void);
index f9701410d3b52b7cfc549c50f08ab5478e04e385..be85b54b3854a2235cf82cf1065110c617a4bf08 100644 (file)
 #define  PCI_PM_CAP_PME_D0     0x0800  /* PME# from D0 */
 #define  PCI_PM_CAP_PME_D1     0x1000  /* PME# from D1 */
 #define  PCI_PM_CAP_PME_D2     0x2000  /* PME# from D2 */
-#define  PCI_PM_CAP_PME_D3     0x4000  /* PME# from D3 (hot) */
+#define  PCI_PM_CAP_PME_D3hot  0x4000  /* PME# from D3 (hot) */
 #define  PCI_PM_CAP_PME_D3cold 0x8000  /* PME# from D3 (cold) */
 #define  PCI_PM_CAP_PME_SHIFT  11      /* Start of the PME Mask in PMC */
 #define PCI_PM_CTRL            4       /* PM control and status register */
 #define  PCI_EXP_LNKCAP_SLS_32_0GB 0x00000005 /* LNKCAP2 SLS Vector bit 4 */
 #define  PCI_EXP_LNKCAP_MLW    0x000003f0 /* Maximum Link Width */
 #define  PCI_EXP_LNKCAP_ASPMS  0x00000c00 /* ASPM Support */
+#define  PCI_EXP_LNKCAP_ASPM_L0S 0x00000400 /* ASPM L0s Support */
+#define  PCI_EXP_LNKCAP_ASPM_L1  0x00000800 /* ASPM L1 Support */
 #define  PCI_EXP_LNKCAP_L0SEL  0x00007000 /* L0s Exit Latency */
 #define  PCI_EXP_LNKCAP_L1EL   0x00038000 /* L1 Exit Latency */
 #define  PCI_EXP_LNKCAP_CLKPM  0x00040000 /* Clock Power Management */
 #define  PCI_L1SS_CTL1_PCIPM_L1_1      0x00000002  /* PCI-PM L1.1 Enable */
 #define  PCI_L1SS_CTL1_ASPM_L1_2       0x00000004  /* ASPM L1.2 Enable */
 #define  PCI_L1SS_CTL1_ASPM_L1_1       0x00000008  /* ASPM L1.1 Enable */
+#define  PCI_L1SS_CTL1_L1_2_MASK       0x00000005
 #define  PCI_L1SS_CTL1_L1SS_MASK       0x0000000f
 #define  PCI_L1SS_CTL1_CM_RESTORE_TIME 0x0000ff00  /* Common_Mode_Restore_Time */
 #define  PCI_L1SS_CTL1_LTR_L12_TH_VALUE        0x03ff0000  /* LTR_L1.2_THRESHOLD_Value */