powerpc/powernv/ioda2: Introduce pnv_pci_ioda2_set_window
authorAlexey Kardashevskiy <aik@ozlabs.ru>
Fri, 5 Jun 2015 06:35:18 +0000 (16:35 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 11 Jun 2015 05:16:51 +0000 (15:16 +1000)
This is a part of moving DMA window programming to an iommu_ops
callback. pnv_pci_ioda2_set_window() takes an iommu_table_group as
a first parameter (not pnv_ioda_pe) as it is going to be used as
a callback for VFIO DDW code.

This should cause no behavioural change.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
arch/powerpc/platforms/powernv/pci-ioda.c

index e61610c..552f6ac 100644 (file)
@@ -1970,6 +1970,43 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
        }
 }
 
+static long pnv_pci_ioda2_set_window(struct iommu_table_group *table_group,
+               int num, struct iommu_table *tbl)
+{
+       struct pnv_ioda_pe *pe = container_of(table_group, struct pnv_ioda_pe,
+                       table_group);
+       struct pnv_phb *phb = pe->phb;
+       int64_t rc;
+       const __u64 start_addr = tbl->it_offset << tbl->it_page_shift;
+       const __u64 win_size = tbl->it_size << tbl->it_page_shift;
+
+       pe_info(pe, "Setting up window %llx..%llx pg=%x\n",
+                       start_addr, start_addr + win_size - 1,
+                       IOMMU_PAGE_SIZE(tbl));
+
+       /*
+        * Map TCE table through TVT. The TVE index is the PE number
+        * shifted by 1 bit for 32-bits DMA space.
+        */
+       rc = opal_pci_map_pe_dma_window(phb->opal_id,
+                       pe->pe_number,
+                       pe->pe_number << 1,
+                       1,
+                       __pa(tbl->it_base),
+                       tbl->it_size << 3,
+                       IOMMU_PAGE_SIZE(tbl));
+       if (rc) {
+               pe_err(pe, "Failed to configure TCE table, err %ld\n", rc);
+               return rc;
+       }
+
+       pnv_pci_link_table_and_group(phb->hose->node, num,
+                       tbl, &pe->table_group);
+       pnv_pci_ioda2_tce_invalidate_entire(pe);
+
+       return 0;
+}
+
 static void pnv_pci_ioda2_set_bypass(struct pnv_ioda_pe *pe, bool enable)
 {
        uint16_t window_id = (pe->pe_number << 1 ) + 1;
@@ -2125,21 +2162,13 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb,
        pe->table_group.ops = &pnv_pci_ioda2_ops;
 #endif
 
-       /*
-        * Map TCE table through TVT. The TVE index is the PE number
-        * shifted by 1 bit for 32-bits DMA space.
-        */
-       rc = opal_pci_map_pe_dma_window(phb->opal_id, pe->pe_number,
-                       pe->pe_number << 1, 1, __pa(tbl->it_base),
-                       tbl->it_size << 3, 1ULL << tbl->it_page_shift);
+       rc = pnv_pci_ioda2_set_window(&pe->table_group, 0, tbl);
        if (rc) {
                pe_err(pe, "Failed to configure 32-bit TCE table,"
                       " err %ld\n", rc);
                goto fail;
        }
 
-       pnv_pci_ioda2_tce_invalidate_entire(pe);
-
        /* OPAL variant of PHB3 invalidated TCEs */
        if (phb->ioda.tce_inval_reg)
                tbl->it_type |= (TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE);