aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/host/pci-tegra.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/host/pci-tegra.c')
-rw-r--r--drivers/pci/host/pci-tegra.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 0dadb81eca70..b3722b7709df 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -233,8 +233,8 @@ 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;
237 u64 phys;
238 int irq; 238 int irq;
239}; 239};
240 240
@@ -1448,9 +1448,8 @@ static int tegra_msi_setup_irq(struct msi_controller *chip,
1448 1448
1449 irq_set_msi_desc(irq, desc); 1449 irq_set_msi_desc(irq, desc);
1450 1450
1451 msg.address_lo = virt_to_phys((void *)msi->pages); 1451 msg.address_lo = lower_32_bits(msi->phys);
1452 /* 32 bit address only */ 1452 msg.address_hi = upper_32_bits(msi->phys);
1453 msg.address_hi = 0;
1454 msg.data = hwirq; 1453 msg.data = hwirq;
1455 1454
1456 pci_write_msi_msg(irq, &msg); 1455 pci_write_msi_msg(irq, &msg);
@@ -1499,7 +1498,6 @@ static int tegra_pcie_enable_msi(struct tegra_pcie *pcie)
1499 const struct tegra_pcie_soc *soc = pcie->soc; 1498 const struct tegra_pcie_soc *soc = pcie->soc;
1500 struct tegra_msi *msi = &pcie->msi; 1499 struct tegra_msi *msi = &pcie->msi;
1501 struct device *dev = pcie->dev; 1500 struct device *dev = pcie->dev;
1502 unsigned long base;
1503 int err; 1501 int err;
1504 u32 reg; 1502 u32 reg;
1505 1503
@@ -1531,12 +1529,25 @@ static int tegra_pcie_enable_msi(struct tegra_pcie *pcie)
1531 goto err; 1529 goto err;
1532 } 1530 }
1533 1531
1534 /* setup AFI/FPCI range */ 1532 /*
1535 msi->pages = __get_free_pages(GFP_KERNEL, 0); 1533 * The PCI host bridge on Tegra contains some logic that intercepts
1536 base = 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;
1537 1548
1538 afi_writel(pcie, base >> soc->msi_base_shift, AFI_MSI_FPCI_BAR_ST); 1549 afi_writel(pcie, msi->phys >> soc->msi_base_shift, AFI_MSI_FPCI_BAR_ST);
1539 afi_writel(pcie, base, AFI_MSI_AXI_BAR_ST); 1550 afi_writel(pcie, msi->phys, AFI_MSI_AXI_BAR_ST);
1540 /* this register is in 4K increments */ 1551 /* this register is in 4K increments */
1541 afi_writel(pcie, 1, AFI_MSI_BAR_SZ); 1552 afi_writel(pcie, 1, AFI_MSI_BAR_SZ);
1542 1553
@@ -1585,8 +1596,6 @@ static int tegra_pcie_disable_msi(struct tegra_pcie *pcie)
1585 afi_writel(pcie, 0, AFI_MSI_EN_VEC6); 1596 afi_writel(pcie, 0, AFI_MSI_EN_VEC6);
1586 afi_writel(pcie, 0, AFI_MSI_EN_VEC7); 1597 afi_writel(pcie, 0, AFI_MSI_EN_VEC7);
1587 1598
1588 free_pages(msi->pages, 0);
1589
1590 if (msi->irq > 0) 1599 if (msi->irq > 0)
1591 free_irq(msi->irq, pcie); 1600 free_irq(msi->irq, pcie);
1592 1601