PKGBUILDs/core/linux-espressobin/0011-pci-aardvard-set-host-and-device-to-the-same-MAX-pay.patch
2017-07-13 00:21:51 +00:00

105 lines
3 KiB
Diff

From 4455b4e78d3696f842d7b27ff6e4c1c15adffbf3 Mon Sep 17 00:00:00 2001
From: Victor Gu <xigu@marvell.com>
Date: Fri, 24 Mar 2017 20:52:30 +0800
Subject: [PATCH 11/12] pci: aardvard: set host and device to the same MAX
payload size
Since the Aardvard does not implement PCIe root bus, the Linux PCIe
framework will not align the MAX payload size between host and device
for it.
This patch sets host and device to the same MAX payload size in Aardvard
PCIe driver.
Change-Id: I3979397b3af98911c067f7ad384922aa3f05497f
Signed-off-by: Victor Gu <xigu@marvell.com>
Reviewed-on: http://vgitil04.il.marvell.com:8080/37927
Tested-by: iSoC Platform CI <ykjenk@marvell.com>
Reviewed-by: Evan Wang <xswang@marvell.com>
---
drivers/pci/host/pci-aardvark.c | 56 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c
index 10154dcf219b..0407c8cb89fb 100644
--- a/drivers/pci/host/pci-aardvark.c
+++ b/drivers/pci/host/pci-aardvark.c
@@ -32,6 +32,7 @@
#define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT 5
#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)
@@ -886,6 +887,58 @@ static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *pcie)
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;
@@ -948,6 +1001,9 @@ static int advk_pcie_probe(struct platform_device *pdev)
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;
}
--
2.13.2