From 85d74730e0aefda9425ebe205619b63cedf2636e Mon Sep 17 00:00:00 2001 From: Victor Gu Date: Fri, 24 Mar 2017 20:52:30 +0800 Subject: [PATCH 10/11] 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 Reviewed-on: http://vgitil04.il.marvell.com:8080/37927 Tested-by: iSoC Platform CI Reviewed-by: Evan Wang --- 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.3