]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - arch/powerpc/platforms/powernv/pci.c
powerpc/powernv: Implement multilevel TCE tables
[karo-tx-linux.git] / arch / powerpc / platforms / powernv / pci.c
index d465b9c32388dac3f41f855b87fdbde00f5ecbfe..765d8ed558d0e16a6dddc16dc7d67d6b6b44b2ce 100644 (file)
@@ -575,6 +575,19 @@ struct pci_ops pnv_pci_ops = {
 static __be64 *pnv_tce(struct iommu_table *tbl, long idx)
 {
        __be64 *tmp = ((__be64 *)tbl->it_base);
+       int  level = tbl->it_indirect_levels;
+       const long shift = ilog2(tbl->it_level_size);
+       unsigned long mask = (tbl->it_level_size - 1) << (level * shift);
+
+       while (level) {
+               int n = (idx & mask) >> (level * shift);
+               unsigned long tce = be64_to_cpu(tmp[n]);
+
+               tmp = __va(tce & ~(TCE_PCI_READ | TCE_PCI_WRITE));
+               idx &= ~mask;
+               mask >>= shift;
+               --level;
+       }
 
        return tmp + idx;
 }