524-PCI-aardvark-set-host-and-device-to-the-same-MAX-payload-size.patch 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. From patchwork Thu Sep 28 12:58:34 2017
  2. Content-Type: text/plain; charset="utf-8"
  3. MIME-Version: 1.0
  4. Content-Transfer-Encoding: 7bit
  5. Subject: [v2,
  6. 3/7] PCI: aardvark: set host and device to the same MAX payload size
  7. X-Patchwork-Submitter: Thomas Petazzoni <[email protected]>
  8. X-Patchwork-Id: 819587
  9. Message-Id: <[email protected]>
  10. To: Bjorn Helgaas <[email protected]>, [email protected]
  11. Cc: Jason Cooper <[email protected]>, Andrew Lunn <[email protected]>,
  12. Sebastian Hesselbarth <[email protected]>, Gregory Clement
  13. <[email protected]>,
  14. Nadav Haklai <[email protected]>, Hanna Hawa <[email protected]>,
  15. Yehuda Yitschak <[email protected]>,
  16. [email protected], Antoine Tenart
  17. <[email protected]>, =?utf-8?q?Miqu=C3=A8l_Raynal?=
  18. <[email protected]>, Victor Gu <[email protected]>,
  19. Thomas Petazzoni <[email protected]>
  20. Date: Thu, 28 Sep 2017 14:58:34 +0200
  21. From: Thomas Petazzoni <[email protected]>
  22. List-Id: <linux-pci.vger.kernel.org>
  23. From: Victor Gu <[email protected]>
  24. Since the Aardvark does not implement a PCIe root bus, the Linux PCIe
  25. subsystem will not align the MAX payload size between the host and the
  26. device. This patch ensures that the host and device have the same MAX
  27. payload size, fixing a number of problems with various PCIe devices.
  28. This is part of fixing bug
  29. https://bugzilla.kernel.org/show_bug.cgi?id=196339, this commit was
  30. reported as the user to be important to get a Intel 7260 mini-PCIe
  31. WiFi card working.
  32. Fixes: Fixes: 8c39d710363c1 ("PCI: aardvark: Add Aardvark PCI host controller driver")
  33. Signed-off-by: Victor Gu <[email protected]>
  34. Reviewed-by: Evan Wang <[email protected]>
  35. Reviewed-by: Nadav Haklai <[email protected]>
  36. [Thomas: tweak commit log.]
  37. Signed-off-by: Thomas Petazzoni <[email protected]>
  38. ---
  39. drivers/pci/host/pci-aardvark.c | 60 ++++++++++++++++++++++++++++++++++++++++-
  40. 1 file changed, 59 insertions(+), 1 deletion(-)
  41. --- a/drivers/pci/host/pci-aardvark.c
  42. +++ b/drivers/pci/host/pci-aardvark.c
  43. @@ -30,9 +30,11 @@
  44. #define PCIE_CORE_DEV_CTRL_STATS_REG 0xc8
  45. #define PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE (0 << 4)
  46. #define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT 5
  47. +#define PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ 0x2
  48. #define PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE (0 << 11)
  49. #define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT 12
  50. #define PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ 0x2
  51. +#define PCIE_CORE_MPS_UNIT_BYTE 128
  52. #define PCIE_CORE_LINK_CTRL_STAT_REG 0xd0
  53. #define PCIE_CORE_LINK_L0S_ENTRY BIT(0)
  54. #define PCIE_CORE_LINK_TRAINING BIT(5)
  55. @@ -297,7 +299,8 @@ static void advk_pcie_setup_hw(struct ad
  56. /* Set PCIe Device Control and Status 1 PF0 register */
  57. reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE |
  58. - (7 << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) |
  59. + (PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ <<
  60. + PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT) |
  61. PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE |
  62. (PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SZ <<
  63. PCIE_CORE_DEV_CTRL_STATS_MAX_RD_REQ_SIZE_SHIFT);
  64. @@ -886,6 +889,58 @@ out_release_res:
  65. return err;
  66. }
  67. +static int advk_pcie_find_smpss(struct pci_dev *dev, void *data)
  68. +{
  69. + u8 *smpss = data;
  70. +
  71. + if (!dev)
  72. + return 0;
  73. +
  74. + if (!pci_is_pcie(dev))
  75. + return 0;
  76. +
  77. + if (*smpss > dev->pcie_mpss)
  78. + *smpss = dev->pcie_mpss;
  79. +
  80. + return 0;
  81. +}
  82. +
  83. +static int advk_pcie_bus_configure_mps(struct pci_dev *dev, void *data)
  84. +{
  85. + int mps;
  86. +
  87. + if (!dev)
  88. + return 0;
  89. +
  90. + if (!pci_is_pcie(dev))
  91. + return 0;
  92. +
  93. + mps = PCIE_CORE_MPS_UNIT_BYTE << *(u8 *)data;
  94. + pcie_set_mps(dev, mps);
  95. +
  96. + return 0;
  97. +}
  98. +
  99. +static void advk_pcie_configure_mps(struct pci_bus *bus, struct advk_pcie *pcie)
  100. +{
  101. + u8 smpss = PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ;
  102. + u32 reg;
  103. +
  104. + /* Find the minimal supported MAX payload size */
  105. + advk_pcie_find_smpss(bus->self, &smpss);
  106. + pci_walk_bus(bus, advk_pcie_find_smpss, &smpss);
  107. +
  108. + /* Configure RC MAX payload size */
  109. + reg = advk_readl(pcie, PCIE_CORE_DEV_CTRL_STATS_REG);
  110. + reg &= ~PCI_EXP_DEVCTL_PAYLOAD;
  111. + reg |= smpss << PCIE_CORE_DEV_CTRL_STATS_MAX_PAYLOAD_SZ_SHIFT;
  112. + advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG);
  113. +
  114. + /* Configure device MAX payload size */
  115. + advk_pcie_bus_configure_mps(bus->self, &smpss);
  116. + pci_walk_bus(bus, advk_pcie_bus_configure_mps, &smpss);
  117. +}
  118. +
  119. static int advk_pcie_probe(struct platform_device *pdev)
  120. {
  121. struct device *dev = &pdev->dev;
  122. @@ -959,6 +1014,9 @@ static int advk_pcie_probe(struct platfo
  123. list_for_each_entry(child, &bus->children, node)
  124. pcie_bus_configure_settings(child);
  125. + /* Configure the MAX pay load size */
  126. + advk_pcie_configure_mps(bus, pcie);
  127. +
  128. pci_bus_add_devices(bus);
  129. return 0;
  130. }