diff options
| -rw-r--r-- | arch/powerpc/include/asm/iommu.h | 3 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powernv/pci-ioda.c | 26 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powernv/pci.h | 2 |
3 files changed, 18 insertions, 13 deletions
diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h index f1ea5972f6ec..e2abbe8a1f4d 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h | |||
| @@ -78,6 +78,9 @@ struct iommu_table { | |||
| 78 | struct iommu_group *it_group; | 78 | struct iommu_group *it_group; |
| 79 | #endif | 79 | #endif |
| 80 | void (*set_bypass)(struct iommu_table *tbl, bool enable); | 80 | void (*set_bypass)(struct iommu_table *tbl, bool enable); |
| 81 | #ifdef CONFIG_PPC_POWERNV | ||
| 82 | void *data; | ||
| 83 | #endif | ||
| 81 | }; | 84 | }; |
| 82 | 85 | ||
| 83 | /* Pure 2^n version of get_order */ | 86 | /* Pure 2^n version of get_order */ |
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 7f58f199f2c1..9447ee9b4aa3 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c | |||
| @@ -916,6 +916,10 @@ static void pnv_ioda_setup_bus_PE(struct pci_bus *bus, int all) | |||
| 916 | return; | 916 | return; |
| 917 | } | 917 | } |
| 918 | 918 | ||
| 919 | pe->tce32_table = kzalloc_node(sizeof(struct iommu_table), | ||
| 920 | GFP_KERNEL, hose->node); | ||
| 921 | pe->tce32_table->data = pe; | ||
| 922 | |||
| 919 | /* Associate it with all child devices */ | 923 | /* Associate it with all child devices */ |
| 920 | pnv_ioda_setup_same_PE(bus, pe); | 924 | pnv_ioda_setup_same_PE(bus, pe); |
| 921 | 925 | ||
| @@ -1005,7 +1009,7 @@ static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev | |||
| 1005 | 1009 | ||
| 1006 | pe = &phb->ioda.pe_array[pdn->pe_number]; | 1010 | pe = &phb->ioda.pe_array[pdn->pe_number]; |
| 1007 | WARN_ON(get_dma_ops(&pdev->dev) != &dma_iommu_ops); | 1011 | WARN_ON(get_dma_ops(&pdev->dev) != &dma_iommu_ops); |
| 1008 | set_iommu_table_base_and_group(&pdev->dev, &pe->tce32_table); | 1012 | set_iommu_table_base_and_group(&pdev->dev, pe->tce32_table); |
| 1009 | } | 1013 | } |
| 1010 | 1014 | ||
| 1011 | static int pnv_pci_ioda_dma_set_mask(struct pnv_phb *phb, | 1015 | static int pnv_pci_ioda_dma_set_mask(struct pnv_phb *phb, |
| @@ -1032,7 +1036,7 @@ static int pnv_pci_ioda_dma_set_mask(struct pnv_phb *phb, | |||
| 1032 | } else { | 1036 | } else { |
| 1033 | dev_info(&pdev->dev, "Using 32-bit DMA via iommu\n"); | 1037 | dev_info(&pdev->dev, "Using 32-bit DMA via iommu\n"); |
| 1034 | set_dma_ops(&pdev->dev, &dma_iommu_ops); | 1038 | set_dma_ops(&pdev->dev, &dma_iommu_ops); |
| 1035 | set_iommu_table_base(&pdev->dev, &pe->tce32_table); | 1039 | set_iommu_table_base(&pdev->dev, pe->tce32_table); |
| 1036 | } | 1040 | } |
| 1037 | *pdev->dev.dma_mask = dma_mask; | 1041 | *pdev->dev.dma_mask = dma_mask; |
| 1038 | return 0; | 1042 | return 0; |
| @@ -1069,9 +1073,9 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, | |||
| 1069 | list_for_each_entry(dev, &bus->devices, bus_list) { | 1073 | list_for_each_entry(dev, &bus->devices, bus_list) { |
| 1070 | if (add_to_iommu_group) | 1074 | if (add_to_iommu_group) |
| 1071 | set_iommu_table_base_and_group(&dev->dev, | 1075 | set_iommu_table_base_and_group(&dev->dev, |
| 1072 | &pe->tce32_table); | 1076 | pe->tce32_table); |
| 1073 | else | 1077 | else |
| 1074 | set_iommu_table_base(&dev->dev, &pe->tce32_table); | 1078 | set_iommu_table_base(&dev->dev, pe->tce32_table); |
| 1075 | 1079 | ||
| 1076 | if (dev->subordinate) | 1080 | if (dev->subordinate) |
| 1077 | pnv_ioda_setup_bus_dma(pe, dev->subordinate, | 1081 | pnv_ioda_setup_bus_dma(pe, dev->subordinate, |
| @@ -1161,8 +1165,7 @@ static void pnv_pci_ioda2_tce_invalidate(struct pnv_ioda_pe *pe, | |||
| 1161 | void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl, | 1165 | void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl, |
| 1162 | __be64 *startp, __be64 *endp, bool rm) | 1166 | __be64 *startp, __be64 *endp, bool rm) |
| 1163 | { | 1167 | { |
| 1164 | struct pnv_ioda_pe *pe = container_of(tbl, struct pnv_ioda_pe, | 1168 | struct pnv_ioda_pe *pe = tbl->data; |
| 1165 | tce32_table); | ||
| 1166 | struct pnv_phb *phb = pe->phb; | 1169 | struct pnv_phb *phb = pe->phb; |
| 1167 | 1170 | ||
| 1168 | if (phb->type == PNV_PHB_IODA1) | 1171 | if (phb->type == PNV_PHB_IODA1) |
| @@ -1228,7 +1231,7 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb, | |||
| 1228 | } | 1231 | } |
| 1229 | 1232 | ||
| 1230 | /* Setup linux iommu table */ | 1233 | /* Setup linux iommu table */ |
| 1231 | tbl = &pe->tce32_table; | 1234 | tbl = pe->tce32_table; |
| 1232 | pnv_pci_setup_iommu_table(tbl, addr, TCE32_TABLE_SIZE * segs, | 1235 | pnv_pci_setup_iommu_table(tbl, addr, TCE32_TABLE_SIZE * segs, |
| 1233 | base << 28, IOMMU_PAGE_SHIFT_4K); | 1236 | base << 28, IOMMU_PAGE_SHIFT_4K); |
| 1234 | 1237 | ||
| @@ -1266,8 +1269,7 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb, | |||
| 1266 | 1269 | ||
| 1267 | static void pnv_pci_ioda2_set_bypass(struct iommu_table *tbl, bool enable) | 1270 | static void pnv_pci_ioda2_set_bypass(struct iommu_table *tbl, bool enable) |
| 1268 | { | 1271 | { |
| 1269 | struct pnv_ioda_pe *pe = container_of(tbl, struct pnv_ioda_pe, | 1272 | struct pnv_ioda_pe *pe = tbl->data; |
| 1270 | tce32_table); | ||
| 1271 | uint16_t window_id = (pe->pe_number << 1 ) + 1; | 1273 | uint16_t window_id = (pe->pe_number << 1 ) + 1; |
| 1272 | int64_t rc; | 1274 | int64_t rc; |
| 1273 | 1275 | ||
| @@ -1312,10 +1314,10 @@ static void pnv_pci_ioda2_setup_bypass_pe(struct pnv_phb *phb, | |||
| 1312 | pe->tce_bypass_base = 1ull << 59; | 1314 | pe->tce_bypass_base = 1ull << 59; |
| 1313 | 1315 | ||
| 1314 | /* Install set_bypass callback for VFIO */ | 1316 | /* Install set_bypass callback for VFIO */ |
| 1315 | pe->tce32_table.set_bypass = pnv_pci_ioda2_set_bypass; | 1317 | pe->tce32_table->set_bypass = pnv_pci_ioda2_set_bypass; |
| 1316 | 1318 | ||
| 1317 | /* Enable bypass by default */ | 1319 | /* Enable bypass by default */ |
| 1318 | pnv_pci_ioda2_set_bypass(&pe->tce32_table, true); | 1320 | pnv_pci_ioda2_set_bypass(pe->tce32_table, true); |
| 1319 | } | 1321 | } |
| 1320 | 1322 | ||
| 1321 | static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb, | 1323 | static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb, |
| @@ -1363,7 +1365,7 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb, | |||
| 1363 | } | 1365 | } |
| 1364 | 1366 | ||
| 1365 | /* Setup linux iommu table */ | 1367 | /* Setup linux iommu table */ |
| 1366 | tbl = &pe->tce32_table; | 1368 | tbl = pe->tce32_table; |
| 1367 | pnv_pci_setup_iommu_table(tbl, addr, tce_table_size, 0, | 1369 | pnv_pci_setup_iommu_table(tbl, addr, tce_table_size, 0, |
| 1368 | IOMMU_PAGE_SHIFT_4K); | 1370 | IOMMU_PAGE_SHIFT_4K); |
| 1369 | 1371 | ||
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 1f0cb66133a1..84280474e18f 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h | |||
| @@ -53,7 +53,7 @@ struct pnv_ioda_pe { | |||
| 53 | /* "Base" iommu table, ie, 4K TCEs, 32-bit DMA */ | 53 | /* "Base" iommu table, ie, 4K TCEs, 32-bit DMA */ |
| 54 | int tce32_seg; | 54 | int tce32_seg; |
| 55 | int tce32_segcount; | 55 | int tce32_segcount; |
| 56 | struct iommu_table tce32_table; | 56 | struct iommu_table *tce32_table; |
| 57 | phys_addr_t tce_inval_reg_phys; | 57 | phys_addr_t tce_inval_reg_phys; |
| 58 | 58 | ||
| 59 | /* 64-bit TCE bypass region */ | 59 | /* 64-bit TCE bypass region */ |
