diff options
Diffstat (limited to 'drivers/pci/host/pci-msm.c')
-rw-r--r-- | drivers/pci/host/pci-msm.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c index 9dc678ce4a48..f364882943e1 100644 --- a/drivers/pci/host/pci-msm.c +++ b/drivers/pci/host/pci-msm.c @@ -5811,9 +5811,10 @@ static int msm_pcie_map_qgic_addr(struct msm_pcie_dev_t *dev, struct msi_msg *msg) { struct iommu_domain *domain = iommu_get_domain_for_dev(&pdev->dev); - int ret, bypass_en = 0; + struct iommu_domain_geometry geometry; + int ret, fastmap_en = 0, bypass_en = 0; dma_addr_t iova; - phys_addr_t pcie_base_addr, gicm_db_offset; + phys_addr_t gicm_db_offset; msg->address_hi = 0; msg->address_lo = dev->msi_gicm_addr; @@ -5835,16 +5836,25 @@ static int msm_pcie_map_qgic_addr(struct msm_pcie_dev_t *dev, if (bypass_en) return 0; - gicm_db_offset = dev->msi_gicm_addr - - rounddown(dev->msi_gicm_addr, PAGE_SIZE); - /* - * Use PCIe DBI address as the IOVA since client cannot - * use this address for their IOMMU mapping. This will - * prevent any conflicts between PCIe host and - * client's mapping. - */ - pcie_base_addr = dev->res[MSM_PCIE_RES_DM_CORE].resource->start; - iova = rounddown(pcie_base_addr, PAGE_SIZE); + iommu_domain_get_attr(domain, DOMAIN_ATTR_FAST, &fastmap_en); + if (fastmap_en) { + iommu_domain_get_attr(domain, DOMAIN_ATTR_GEOMETRY, &geometry); + iova = geometry.aperture_start; + PCIE_DBG(dev, + "PCIe: RC%d: Use client's IOVA 0x%llx to map QGIC MSI address\n", + dev->rc_idx, iova); + } else { + phys_addr_t pcie_base_addr; + + /* + * Use PCIe DBI address as the IOVA since client cannot + * use this address for their IOMMU mapping. This will + * prevent any conflicts between PCIe host and + * client's mapping. + */ + pcie_base_addr = dev->res[MSM_PCIE_RES_DM_CORE].resource->start; + iova = rounddown(pcie_base_addr, PAGE_SIZE); + } ret = iommu_map(domain, iova, rounddown(dev->msi_gicm_addr, PAGE_SIZE), PAGE_SIZE, IOMMU_READ | IOMMU_WRITE); @@ -5855,6 +5865,8 @@ static int msm_pcie_map_qgic_addr(struct msm_pcie_dev_t *dev, return -ENOMEM; } + gicm_db_offset = dev->msi_gicm_addr - + rounddown(dev->msi_gicm_addr, PAGE_SIZE); msg->address_lo = iova + gicm_db_offset; return 0; |