Commit e57080f1 authored by Alexey Kardashevskiy's avatar Alexey Kardashevskiy Committed by Michael Ellerman

powerpc/powernv/ioda2: Add TCE invalidation for all attached groups

The iommu_table struct keeps a list of IOMMU groups it is used for.
At the moment there is just a single group attached but further
patches will add TCE table sharing. When sharing is enabled, TCE cache
in each PE needs to be invalidated so does the patch.

This does not change pnv_pci_ioda1_tce_invalidate() as there is no plan
to enable TCE table sharing on PHBs older than IODA2.
Signed-off-by: default avatarAlexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
Reviewed-by: default avatarGavin Shan <gwshan@linux.vnet.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 5780fb04
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/msi.h> #include <linux/msi.h>
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/iommu.h> #include <linux/iommu.h>
#include <linux/rculist.h>
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -1765,23 +1766,15 @@ static inline void pnv_pci_ioda2_tce_invalidate_entire(struct pnv_ioda_pe *pe) ...@@ -1765,23 +1766,15 @@ static inline void pnv_pci_ioda2_tce_invalidate_entire(struct pnv_ioda_pe *pe)
__raw_writeq(cpu_to_be64(val), phb->ioda.tce_inval_reg); __raw_writeq(cpu_to_be64(val), phb->ioda.tce_inval_reg);
} }
static void pnv_pci_ioda2_tce_invalidate(struct iommu_table *tbl, static void pnv_pci_ioda2_do_tce_invalidate(unsigned pe_number, bool rm,
unsigned long index, unsigned long npages, bool rm) __be64 __iomem *invalidate, unsigned shift,
unsigned long index, unsigned long npages)
{ {
struct iommu_table_group_link *tgl = list_first_entry_or_null(
&tbl->it_group_list, struct iommu_table_group_link,
next);
struct pnv_ioda_pe *pe = container_of(tgl->table_group,
struct pnv_ioda_pe, table_group);
unsigned long start, end, inc; unsigned long start, end, inc;
__be64 __iomem *invalidate = rm ?
(__be64 __iomem *)pe->phb->ioda.tce_inval_reg_phys :
pe->phb->ioda.tce_inval_reg;
const unsigned shift = tbl->it_page_shift;
/* We'll invalidate DMA address in PE scope */ /* We'll invalidate DMA address in PE scope */
start = 0x2ull << 60; start = 0x2ull << 60;
start |= (pe->pe_number & 0xFF); start |= (pe_number & 0xFF);
end = start; end = start;
/* Figure out the start, end and step */ /* Figure out the start, end and step */
...@@ -1799,6 +1792,24 @@ static void pnv_pci_ioda2_tce_invalidate(struct iommu_table *tbl, ...@@ -1799,6 +1792,24 @@ static void pnv_pci_ioda2_tce_invalidate(struct iommu_table *tbl,
} }
} }
static void pnv_pci_ioda2_tce_invalidate(struct iommu_table *tbl,
unsigned long index, unsigned long npages, bool rm)
{
struct iommu_table_group_link *tgl;
list_for_each_entry_rcu(tgl, &tbl->it_group_list, next) {
struct pnv_ioda_pe *pe = container_of(tgl->table_group,
struct pnv_ioda_pe, table_group);
__be64 __iomem *invalidate = rm ?
(__be64 __iomem *)pe->phb->ioda.tce_inval_reg_phys :
pe->phb->ioda.tce_inval_reg;
pnv_pci_ioda2_do_tce_invalidate(pe->pe_number, rm,
invalidate, tbl->it_page_shift,
index, npages);
}
}
static int pnv_ioda2_tce_build(struct iommu_table *tbl, long index, static int pnv_ioda2_tce_build(struct iommu_table *tbl, long index,
long npages, unsigned long uaddr, long npages, unsigned long uaddr,
enum dma_data_direction direction, enum dma_data_direction direction,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment