aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2017-05-04 16:10:32 -0400
committerBjorn Helgaas <bhelgaas@google.com>2017-07-02 19:46:20 -0400
commitd7bd554f27c942e6b8b54100b4044f9be1038edf (patch)
tree022dae6e2bf8d18a5a305904cc8ab323a32b4ce2 /drivers
parentc016555091119b469fe49d1b1b359f0ae3fc6ed7 (diff)
PCI: tegra: Do not allocate MSI target memory
The PCI host bridge found on Tegra SoCs doesn't require the MSI target address to be backed by physical system memory. Writes are intercepted within the controller and never make it to the memory pointed to. Since no actual system memory is required, remove the allocation of a single page and hardcode the MSI target address with a special address that maps to the last 4 KiB page within the range that is reserved for system memory and memory-mapped I/O in the FPCI address map. Signed-off-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: Stephen Warren <swarren@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/host/pci-tegra.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 1d1d87e8bcbf..b3722b7709df 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -233,7 +233,6 @@ struct tegra_msi {
233 struct msi_controller chip; 233 struct msi_controller chip;
234 DECLARE_BITMAP(used, INT_PCI_MSI_NR); 234 DECLARE_BITMAP(used, INT_PCI_MSI_NR);
235 struct irq_domain *domain; 235 struct irq_domain *domain;
236 unsigned long pages;
237 struct mutex lock; 236 struct mutex lock;
238 u64 phys; 237 u64 phys;
239 int irq; 238 int irq;
@@ -1530,9 +1529,22 @@ static int tegra_pcie_enable_msi(struct tegra_pcie *pcie)
1530 goto err; 1529 goto err;
1531 } 1530 }
1532 1531
1533 /* setup AFI/FPCI range */ 1532 /*
1534 msi->pages = __get_free_pages(GFP_KERNEL, 0); 1533 * The PCI host bridge on Tegra contains some logic that intercepts
1535 msi->phys = virt_to_phys((void *)msi->pages); 1534 * MSI writes, which means that the MSI target address doesn't have
1535 * to point to actual physical memory. Rather than allocating one 4
1536 * KiB page of system memory that's never used, we can simply pick
1537 * an arbitrary address within an area reserved for system memory
1538 * in the FPCI address map.
1539 *
1540 * However, in order to avoid confusion, we pick an address that
1541 * doesn't map to physical memory. The FPCI address map reserves a
1542 * 1012 GiB region for system memory and memory-mapped I/O. Since
1543 * none of the Tegra SoCs that contain this PCI host bridge can
1544 * address more than 16 GiB of system memory, the last 4 KiB of
1545 * these 1012 GiB is a good candidate.
1546 */
1547 msi->phys = 0xfcfffff000;
1536 1548
1537 afi_writel(pcie, msi->phys >> soc->msi_base_shift, AFI_MSI_FPCI_BAR_ST); 1549 afi_writel(pcie, msi->phys >> soc->msi_base_shift, AFI_MSI_FPCI_BAR_ST);
1538 afi_writel(pcie, msi->phys, AFI_MSI_AXI_BAR_ST); 1550 afi_writel(pcie, msi->phys, AFI_MSI_AXI_BAR_ST);
@@ -1584,8 +1596,6 @@ static int tegra_pcie_disable_msi(struct tegra_pcie *pcie)
1584 afi_writel(pcie, 0, AFI_MSI_EN_VEC6); 1596 afi_writel(pcie, 0, AFI_MSI_EN_VEC6);
1585 afi_writel(pcie, 0, AFI_MSI_EN_VEC7); 1597 afi_writel(pcie, 0, AFI_MSI_EN_VEC7);
1586 1598
1587 free_pages(msi->pages, 0);
1588
1589 if (msi->irq > 0) 1599 if (msi->irq > 0)
1590 free_irq(msi->irq, pcie); 1600 free_irq(msi->irq, pcie);
1591 1601