aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 4ce547e00473..8f92446ff0ae 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -65,6 +65,30 @@ static int __init fsl_pcie_check_link(struct pci_controller *hose)
65} 65}
66 66
67#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx) 67#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
68
69#define MAX_PHYS_ADDR_BITS 40
70static u64 pci64_dma_offset = 1ull << MAX_PHYS_ADDR_BITS;
71
72static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
73{
74 if (!dev->dma_mask || !dma_supported(dev, dma_mask))
75 return -EIO;
76
77 /*
78 * Fixup PCI devices that are able to DMA to above the physical
79 * address width of the SoC such that we can address any internal
80 * SoC address from across PCI if needed
81 */
82 if ((dev->bus == &pci_bus_type) &&
83 dma_mask >= DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) {
84 set_dma_ops(dev, &dma_direct_ops);
85 set_dma_offset(dev, pci64_dma_offset);
86 }
87
88 *dev->dma_mask = dma_mask;
89 return 0;
90}
91
68static int __init setup_one_atmu(struct ccsr_pci __iomem *pci, 92static int __init setup_one_atmu(struct ccsr_pci __iomem *pci,
69 unsigned int index, const struct resource *res, 93 unsigned int index, const struct resource *res,
70 resource_size_t offset) 94 resource_size_t offset)
@@ -228,6 +252,37 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
228 252
229 hose->dma_window_base_cur = 0x00000000; 253 hose->dma_window_base_cur = 0x00000000;
230 hose->dma_window_size = (resource_size_t)sz; 254 hose->dma_window_size = (resource_size_t)sz;
255
256 /*
257 * if we have >4G of memory setup second PCI inbound window to
258 * let devices that are 64-bit address capable to work w/o
259 * SWIOTLB and access the full range of memory
260 */
261 if (sz != mem) {
262 mem_log = __ilog2_u64(mem);
263
264 /* Size window up if we dont fit in exact power-of-2 */
265 if ((1ull << mem_log) != mem)
266 mem_log++;
267
268 piwar = (piwar & ~PIWAR_SZ_MASK) | (mem_log - 1);
269
270 /* Setup inbound memory window */
271 out_be32(&pci->piw[win_idx].pitar, 0x00000000);
272 out_be32(&pci->piw[win_idx].piwbear,
273 pci64_dma_offset >> 44);
274 out_be32(&pci->piw[win_idx].piwbar,
275 pci64_dma_offset >> 12);
276 out_be32(&pci->piw[win_idx].piwar, piwar);
277
278 /*
279 * install our own dma_set_mask handler to fixup dma_ops
280 * and dma_offset
281 */
282 ppc_md.dma_set_mask = fsl_pci_dma_set_mask;
283
284 pr_info("%s: Setup 64-bit PCI DMA window\n", name);
285 }
231 } else { 286 } else {
232 u64 paddr = 0; 287 u64 paddr = 0;
233 288