| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- From patchwork Thu Sep 28 12:58:34 2017
- Content-Type: text/plain; charset="utf-8"
- MIME-Version: 1.0
- Content-Transfer-Encoding: 7bit
- Subject: [v2,
- 3/7] PCI: aardvark: set host and device to the same MAX payload size
- X-Patchwork-Submitter: Thomas Petazzoni <[email protected]>
- X-Patchwork-Id: 819587
- Message-Id: <[email protected]>
- To: Bjorn Helgaas <[email protected]>, [email protected]
- Cc: Jason Cooper <[email protected]>, Andrew Lunn <[email protected]>,
- Sebastian Hesselbarth <[email protected]>, Gregory Clement
- <[email protected]>,
- Nadav Haklai <[email protected]>, Hanna Hawa <[email protected]>,
- Yehuda Yitschak <[email protected]>,
- [email protected], Antoine Tenart
- <[email protected]>, =?utf-8?q?Miqu=C3=A8l_Raynal?=
- <[email protected]>, Victor Gu <[email protected]>,
- Thomas Petazzoni <[email protected]>
- Date: Thu, 28 Sep 2017 14:58:34 +0200
- From: Thomas Petazzoni <[email protected]>
- List-Id: <linux-pci.vger.kernel.org>
- From: Victor Gu <[email protected]>
- Since the Aardvark does not implement a PCIe root bus, the Linux PCIe
- subsystem will not align the MAX payload size between the host and the
- device. This patch ensures that the host and device have the same MAX
- payload size, fixing a number of problems with various PCIe devices.
- This is part of fixing bug
- https://bugzilla.kernel.org/show_bug.cgi?id=196339, this commit was
- reported as the user to be important to get a Intel 7260 mini-PCIe
- WiFi card working.
- Fixes: Fixes: 8c39d710363c1 ("PCI: aardvark: Add Aardvark PCI host controller driver")
- Signed-off-by: Victor Gu <[email protected]>
- Reviewed-by: Evan Wang <[email protected]>
- Reviewed-by: Nadav Haklai <[email protected]>
- [Thomas: tweak commit log.]
- Signed-off-by: Thomas Petazzoni <[email protected]>
- ---
- drivers/pci/host/pci-aardvark.c | 60 ++++++++++++++++++++++++++++++++++++++++-
- 1 file changed, 59 insertions(+), 1 deletion(-)
- --- a/drivers/pci/host/pci-aardvark.c
- +++ b/drivers/pci/host/pci-aardvark.c
- @@ -30,9 +30,11 @@
- #define PCIE_CORE_DEV_CTRL_STATS_REG 0xc8
- #define PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE (0 << 4)
- #define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT 5
- +#define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ 0x2
- #define PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE (0 << 11)
- #define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT 12
- #define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ 0x2
- +#define PCIE_CORE_MPS_UNIT_BYTE 128
- #define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0
- #define PCIE_CORE_LINK_L0S_ENTRY BIT(0)
- #define PCIE_CORE_LINK_TRAINING BIT(5)
- @@ -297,7 +299,8 @@ static void advk_pcie_setup_hw(struct ad
-
- /* Set PCIe Device Control and Status 1 PF0 register */
- reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE |
- - (7 << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) |
- + (PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ <<
- + PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) |
- PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE |
- (PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ <<
- PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT);
- @@ -886,6 +889,58 @@ out_release_res:
- return err;
- }
-
- +static int advk_pcie_find_smpss(struct pci_dev *dev, void *data)
- +{
- + u8 *smpss = data;
- +
- + if (!dev)
- + return 0;
- +
- + if (!pci_is_pcie(dev))
- + return 0;
- +
- + if (*smpss > dev->pcie_mpss)
- + *smpss = dev->pcie_mpss;
- +
- + return 0;
- +}
- +
- +static int advk_pcie_bus_configure_mps(struct pci_dev *dev, void *data)
- +{
- + int mps;
- +
- + if (!dev)
- + return 0;
- +
- + if (!pci_is_pcie(dev))
- + return 0;
- +
- + mps = PCIE_CORE_MPS_UNIT_BYTE << *(u8 *)data;
- + pcie_set_mps(dev, mps);
- +
- + return 0;
- +}
- +
- +static void advk_pcie_configure_mps(struct pci_bus *bus, struct advk_pcie *pcie)
- +{
- + u8 smpss = PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ;
- + u32 reg;
- +
- + /* Find the minimal supported MAX payload size */
- + advk_pcie_find_smpss(bus->self, &smpss);
- + pci_walk_bus(bus, advk_pcie_find_smpss, &smpss);
- +
- + /* Configure RC MAX payload size */
- + reg = advk_readl(pcie, PCIE_CORE_DEV_CTRL_STATS_REG);
- + reg &= ~PCI_EXP_DEVCTL_PAYLOAD;
- + reg |= smpss << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT;
- + advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG);
- +
- + /* Configure device MAX payload size */
- + advk_pcie_bus_configure_mps(bus->self, &smpss);
- + pci_walk_bus(bus, advk_pcie_bus_configure_mps, &smpss);
- +}
- +
- static int advk_pcie_probe(struct platform_device *pdev)
- {
- struct device *dev = &pdev->dev;
- @@ -959,6 +1014,9 @@ static int advk_pcie_probe(struct platfo
- list_for_each_entry(child, &bus->children, node)
- pcie_bus_configure_settings(child);
-
- + /* Configure the MAX pay load size */
- + advk_pcie_configure_mps(bus, pcie);
- +
- pci_bus_add_devices(bus);
- return 0;
- }
|