From: Geetha sowjanya <gak...@marvell.com>

HW interprets RVU_AF_MSIXTR_BASE address as an IOVA, hence
create a IOMMU mapping for the physcial address configured by
firmware and reconfig RVU_AF_MSIXTR_BASE with IOVA.

Signed-off-by: Geetha sowjanya <gak...@marvell.com>
Signed-off-by: Sunil Goutham <sgout...@marvell.com>
---
 drivers/soc/marvell/octeontx2/rvu.c | 33 ++++++++++++++++++++++++++++++---
 drivers/soc/marvell/octeontx2/rvu.h |  1 +
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/drivers/soc/marvell/octeontx2/rvu.c 
b/drivers/soc/marvell/octeontx2/rvu.c
index 8ac3524..40684c9 100644
--- a/drivers/soc/marvell/octeontx2/rvu.c
+++ b/drivers/soc/marvell/octeontx2/rvu.c
@@ -442,9 +442,10 @@ static int rvu_setup_msix_resources(struct rvu *rvu)
 {
        struct rvu_hwinfo *hw = rvu->hw;
        int pf, vf, numvfs, hwvf, err;
+       int nvecs, offset, max_msix;
        struct rvu_pfvf *pfvf;
-       int nvecs, offset;
-       u64 cfg;
+       u64 cfg, phy_addr;
+       dma_addr_t iova;
 
        for (pf = 0; pf < hw->total_pfs; pf++) {
                cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_PFX_CFG(pf));
@@ -523,6 +524,22 @@ static int rvu_setup_msix_resources(struct rvu *rvu)
                }
        }
 
+       /* HW interprets RVU_AF_MSIXTR_BASE address as an IOVA, hence
+        * create a IOMMU mapping for the physcial address configured by
+        * firmware and reconfig RVU_AF_MSIXTR_BASE with IOVA.
+        */
+       cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_CONST);
+       max_msix = cfg & 0xFFFFF;
+       phy_addr = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_MSIXTR_BASE);
+       iova = dma_map_single(rvu->dev, (void *)phy_addr,
+                             max_msix * PCI_MSIX_ENTRY_SIZE,
+                             DMA_BIDIRECTIONAL);
+       if (dma_mapping_error(rvu->dev, iova))
+               return -ENOMEM;
+
+       rvu_write64(rvu, BLKADDR_RVUM, RVU_AF_MSIXTR_BASE, (u64)iova);
+       rvu->msix_base_iova = iova;
+
        return 0;
 }
 
@@ -531,7 +548,8 @@ static void rvu_free_hw_resources(struct rvu *rvu)
        struct rvu_hwinfo *hw = rvu->hw;
        struct rvu_block *block;
        struct rvu_pfvf  *pfvf;
-       int id;
+       int id, max_msix;
+       u64 cfg;
 
        /* Free block LF bitmaps */
        for (id = 0; id < BLK_COUNT; id++) {
@@ -549,6 +567,15 @@ static void rvu_free_hw_resources(struct rvu *rvu)
                pfvf = &rvu->hwvf[id];
                kfree(pfvf->msix.bmap);
        }
+
+       /* Unmap MSIX vector base IOVA mapping */
+       if (!rvu->msix_base_iova)
+               return;
+       cfg = rvu_read64(rvu, BLKADDR_RVUM, RVU_PRIV_CONST);
+       max_msix = cfg & 0xFFFFF;
+       dma_unmap_single(rvu->dev, rvu->msix_base_iova,
+                        max_msix * PCI_MSIX_ENTRY_SIZE,
+                        DMA_BIDIRECTIONAL);
 }
 
 static int rvu_setup_hw_resources(struct rvu *rvu)
diff --git a/drivers/soc/marvell/octeontx2/rvu.h 
b/drivers/soc/marvell/octeontx2/rvu.h
index 7435e83..92c2022 100644
--- a/drivers/soc/marvell/octeontx2/rvu.h
+++ b/drivers/soc/marvell/octeontx2/rvu.h
@@ -99,6 +99,7 @@ struct rvu {
        u16                     num_vec;
        char                    *irq_name;
        bool                    *irq_allocated;
+       dma_addr_t              msix_base_iova;
 };
 
 static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val)
-- 
2.7.4

Reply via email to