|
@@ -2910,6 +2910,34 @@ static void pnv_pci_ioda2_table_free_pages(struct iommu_table *tbl)
|
|
|
tbl->it_indirect_levels);
|
|
|
}
|
|
|
|
|
|
+static unsigned long pnv_ioda_parse_tce_sizes(struct pnv_phb *phb)
|
|
|
+{
|
|
|
+ struct pci_controller *hose = phb->hose;
|
|
|
+ struct device_node *dn = hose->dn;
|
|
|
+ unsigned long mask = 0;
|
|
|
+ int i, rc, count;
|
|
|
+ u32 val;
|
|
|
+
|
|
|
+ count = of_property_count_u32_elems(dn, "ibm,supported-tce-sizes");
|
|
|
+ if (count <= 0) {
|
|
|
+ mask = SZ_4K | SZ_64K;
|
|
|
+ /* Add 16M for POWER8 by default */
|
|
|
+ if (cpu_has_feature(CPU_FTR_ARCH_207S) &&
|
|
|
+ !cpu_has_feature(CPU_FTR_ARCH_300))
|
|
|
+ mask |= SZ_16M;
|
|
|
+ return mask;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < count; i++) {
|
|
|
+ rc = of_property_read_u32_index(dn, "ibm,supported-tce-sizes",
|
|
|
+ i, &val);
|
|
|
+ if (rc == 0)
|
|
|
+ mask |= 1ULL << val;
|
|
|
+ }
|
|
|
+
|
|
|
+ return mask;
|
|
|
+}
|
|
|
+
|
|
|
static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb,
|
|
|
struct pnv_ioda_pe *pe)
|
|
|
{
|
|
@@ -2934,7 +2962,7 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb,
|
|
|
pe->table_group.max_dynamic_windows_supported =
|
|
|
IOMMU_TABLE_GROUP_MAX_TABLES;
|
|
|
pe->table_group.max_levels = POWERNV_IOMMU_MAX_LEVELS;
|
|
|
- pe->table_group.pgsizes = SZ_4K | SZ_64K | SZ_16M;
|
|
|
+ pe->table_group.pgsizes = pnv_ioda_parse_tce_sizes(phb);
|
|
|
#ifdef CONFIG_IOMMU_API
|
|
|
pe->table_group.ops = &pnv_pci_ioda2_ops;
|
|
|
#endif
|