diff options
author | Thierry Reding <treding@nvidia.com> | 2017-05-04 16:10:31 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2017-07-02 19:46:20 -0400 |
commit | c016555091119b469fe49d1b1b359f0ae3fc6ed7 (patch) | |
tree | 799b0b293f7e2ab6ece698bde2c874197d1a3989 | |
parent | 769b461fc0c0451bacf75826d5830fc07c5a57e4 (diff) |
PCI: tegra: Support MSI 64-bit addressing
The MSI target address can reside beyond the 32-bit boundary on devices
with more than 2 GiB of system memory. The PCI host bridge on Tegra can
easily support 64-bit addresses, so make sure to pass the upper 32 bits of
the target address to endpoints when allocating MSI entries.
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Stephen Warren <swarren@nvidia.com>
-rw-r--r-- | drivers/pci/host/pci-tegra.c | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 0dadb81eca70..1d1d87e8bcbf 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c | |||
@@ -235,6 +235,7 @@ struct tegra_msi { | |||
235 | struct irq_domain *domain; | 235 | struct irq_domain *domain; |
236 | unsigned long pages; | 236 | unsigned long pages; |
237 | struct mutex lock; | 237 | struct mutex lock; |
238 | u64 phys; | ||
238 | int irq; | 239 | int irq; |
239 | }; | 240 | }; |
240 | 241 | ||
@@ -1448,9 +1449,8 @@ static int tegra_msi_setup_irq(struct msi_controller *chip, | |||
1448 | 1449 | ||
1449 | irq_set_msi_desc(irq, desc); | 1450 | irq_set_msi_desc(irq, desc); |
1450 | 1451 | ||
1451 | msg.address_lo = virt_to_phys((void *)msi->pages); | 1452 | msg.address_lo = lower_32_bits(msi->phys); |
1452 | /* 32 bit address only */ | 1453 | msg.address_hi = upper_32_bits(msi->phys); |
1453 | msg.address_hi = 0; | ||
1454 | msg.data = hwirq; | 1454 | msg.data = hwirq; |
1455 | 1455 | ||
1456 | pci_write_msi_msg(irq, &msg); | 1456 | pci_write_msi_msg(irq, &msg); |
@@ -1499,7 +1499,6 @@ static int tegra_pcie_enable_msi(struct tegra_pcie *pcie) | |||
1499 | const struct tegra_pcie_soc *soc = pcie->soc; | 1499 | const struct tegra_pcie_soc *soc = pcie->soc; |
1500 | struct tegra_msi *msi = &pcie->msi; | 1500 | struct tegra_msi *msi = &pcie->msi; |
1501 | struct device *dev = pcie->dev; | 1501 | struct device *dev = pcie->dev; |
1502 | unsigned long base; | ||
1503 | int err; | 1502 | int err; |
1504 | u32 reg; | 1503 | u32 reg; |
1505 | 1504 | ||
@@ -1533,10 +1532,10 @@ static int tegra_pcie_enable_msi(struct tegra_pcie *pcie) | |||
1533 | 1532 | ||
1534 | /* setup AFI/FPCI range */ | 1533 | /* setup AFI/FPCI range */ |
1535 | msi->pages = __get_free_pages(GFP_KERNEL, 0); | 1534 | msi->pages = __get_free_pages(GFP_KERNEL, 0); |
1536 | base = virt_to_phys((void *)msi->pages); | 1535 | msi->phys = virt_to_phys((void *)msi->pages); |
1537 | 1536 | ||
1538 | afi_writel(pcie, base >> soc->msi_base_shift, AFI_MSI_FPCI_BAR_ST); | 1537 | afi_writel(pcie, msi->phys >> soc->msi_base_shift, AFI_MSI_FPCI_BAR_ST); |
1539 | afi_writel(pcie, base, AFI_MSI_AXI_BAR_ST); | 1538 | afi_writel(pcie, msi->phys, AFI_MSI_AXI_BAR_ST); |
1540 | /* this register is in 4K increments */ | 1539 | /* this register is in 4K increments */ |
1541 | afi_writel(pcie, 1, AFI_MSI_BAR_SZ); | 1540 | afi_writel(pcie, 1, AFI_MSI_BAR_SZ); |
1542 | 1541 | ||