diff options
Diffstat (limited to 'sys-kernel/armv8multi-sources/files/0009-PCI-aardvark-set-host-and-device-to-the-same-MAX-pay.patch')
-rw-r--r-- | sys-kernel/armv8multi-sources/files/0009-PCI-aardvark-set-host-and-device-to-the-same-MAX-pay.patch | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/sys-kernel/armv8multi-sources/files/0009-PCI-aardvark-set-host-and-device-to-the-same-MAX-pay.patch b/sys-kernel/armv8multi-sources/files/0009-PCI-aardvark-set-host-and-device-to-the-same-MAX-pay.patch new file mode 100644 index 0000000..126d4dc --- /dev/null +++ b/sys-kernel/armv8multi-sources/files/0009-PCI-aardvark-set-host-and-device-to-the-same-MAX-pay.patch @@ -0,0 +1,123 @@ +From de86d635fa690376dab31c76586af2e76432c520 Mon Sep 17 00:00:00 2001 +From: Victor Gu <xigu@marvell.com> +Date: Fri, 8 Sep 2017 11:53:44 +0200 +Subject: [PATCH 09/14] PCI: aardvark: set host and device to the same MAX + payload size + +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(-) + +diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c +index b43351a6b6ce..7f195c083e20 100644 +--- 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) +@@ -298,7 +300,8 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie) + + /* 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 @@ 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; +@@ -952,6 +1007,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.15.0 + |