mirror of
git://git.openwrt.org/openwrt/openwrt.git
synced 2024-12-09 08:20:39 +00:00
138 lines
4.7 KiB
Diff
138 lines
4.7 KiB
Diff
|
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 <thomas.petazzoni@free-electrons.com>
|
||
|
X-Patchwork-Id: 819587
|
||
|
Message-Id: <20170928125838.11887-4-thomas.petazzoni@free-electrons.com>
|
||
|
To: Bjorn Helgaas <bhelgaas@google.com>, linux-pci@vger.kernel.org
|
||
|
Cc: Jason Cooper <jason@lakedaemon.net>, Andrew Lunn <andrew@lunn.ch>,
|
||
|
Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>, Gregory Clement
|
||
|
<gregory.clement@free-electrons.com>,
|
||
|
Nadav Haklai <nadavh@marvell.com>, Hanna Hawa <hannah@marvell.com>,
|
||
|
Yehuda Yitschak <yehuday@marvell.com>,
|
||
|
linux-arm-kernel@lists.infradead.org, Antoine Tenart
|
||
|
<antoine.tenart@free-electrons.com>, =?utf-8?q?Miqu=C3=A8l_Raynal?=
|
||
|
<miquel.raynal@free-electrons.com>, Victor Gu <xigu@marvell.com>,
|
||
|
Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||
|
Date: Thu, 28 Sep 2017 14:58:34 +0200
|
||
|
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||
|
List-Id: <linux-pci.vger.kernel.org>
|
||
|
|
||
|
From: Victor Gu <xigu@marvell.com>
|
||
|
|
||
|
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 <xigu@marvell.com>
|
||
|
Reviewed-by: Evan Wang <xswang@marvell.com>
|
||
|
Reviewed-by: Nadav Haklai <nadavh@marvell.com>
|
||
|
[Thomas: tweak commit log.]
|
||
|
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||
|
---
|
||
|
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,8 +30,10 @@
|
||
|
#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_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_SIZE_SHIFT;
|
||
|
advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG);
|
||
|
@@ -879,6 +882,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;
|
||
|
@@ -952,6 +1007,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;
|
||
|
}
|