aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/pci-bridge.h2
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c33
2 files changed, 32 insertions, 3 deletions
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 8716db48e946..415df8509f52 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -182,6 +182,8 @@ struct pci_dn {
182 u16 vfs_expanded; /* number of VFs IOV BAR expanded */ 182 u16 vfs_expanded; /* number of VFs IOV BAR expanded */
183 u16 num_vfs; /* number of VFs enabled*/ 183 u16 num_vfs; /* number of VFs enabled*/
184 int offset; /* PE# for the first VF PE */ 184 int offset; /* PE# for the first VF PE */
185#define M64_PER_IOV 4
186 int m64_per_iov;
185#define IODA_INVALID_M64 (-1) 187#define IODA_INVALID_M64 (-1)
186 int m64_wins[PCI_SRIOV_NUM_BARS]; 188 int m64_wins[PCI_SRIOV_NUM_BARS];
187#endif /* CONFIG_PCI_IOV */ 189#endif /* CONFIG_PCI_IOV */
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 5187d164cfe1..b63925f483fc 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -2250,6 +2250,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
2250 int i; 2250 int i;
2251 resource_size_t size; 2251 resource_size_t size;
2252 struct pci_dn *pdn; 2252 struct pci_dn *pdn;
2253 int mul, total_vfs;
2253 2254
2254 if (!pdev->is_physfn || pdev->is_added) 2255 if (!pdev->is_physfn || pdev->is_added)
2255 return; 2256 return;
@@ -2260,6 +2261,32 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
2260 pdn = pci_get_pdn(pdev); 2261 pdn = pci_get_pdn(pdev);
2261 pdn->vfs_expanded = 0; 2262 pdn->vfs_expanded = 0;
2262 2263
2264 total_vfs = pci_sriov_get_totalvfs(pdev);
2265 pdn->m64_per_iov = 1;
2266 mul = phb->ioda.total_pe;
2267
2268 for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
2269 res = &pdev->resource[i + PCI_IOV_RESOURCES];
2270 if (!res->flags || res->parent)
2271 continue;
2272 if (!pnv_pci_is_mem_pref_64(res->flags)) {
2273 dev_warn(&pdev->dev, " non M64 VF BAR%d: %pR\n",
2274 i, res);
2275 continue;
2276 }
2277
2278 size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
2279
2280 /* bigger than 64M */
2281 if (size > (1 << 26)) {
2282 dev_info(&pdev->dev, "PowerNV: VF BAR%d: %pR IOV size is bigger than 64M, roundup power2\n",
2283 i, res);
2284 pdn->m64_per_iov = M64_PER_IOV;
2285 mul = roundup_pow_of_two(total_vfs);
2286 break;
2287 }
2288 }
2289
2263 for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { 2290 for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
2264 res = &pdev->resource[i + PCI_IOV_RESOURCES]; 2291 res = &pdev->resource[i + PCI_IOV_RESOURCES];
2265 if (!res->flags || res->parent) 2292 if (!res->flags || res->parent)
@@ -2272,12 +2299,12 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
2272 2299
2273 dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res); 2300 dev_dbg(&pdev->dev, " Fixing VF BAR%d: %pR to\n", i, res);
2274 size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES); 2301 size = pci_iov_resource_size(pdev, i + PCI_IOV_RESOURCES);
2275 res->end = res->start + size * phb->ioda.total_pe - 1; 2302 res->end = res->start + size * mul - 1;
2276 dev_dbg(&pdev->dev, " %pR\n", res); 2303 dev_dbg(&pdev->dev, " %pR\n", res);
2277 dev_info(&pdev->dev, "VF BAR%d: %pR (expanded to %d VFs for PE alignment)", 2304 dev_info(&pdev->dev, "VF BAR%d: %pR (expanded to %d VFs for PE alignment)",
2278 i, res, phb->ioda.total_pe); 2305 i, res, mul);
2279 } 2306 }
2280 pdn->vfs_expanded = phb->ioda.total_pe; 2307 pdn->vfs_expanded = mul;
2281} 2308}
2282#endif /* CONFIG_PCI_IOV */ 2309#endif /* CONFIG_PCI_IOV */
2283 2310