summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScott Wood <oss@buserror.net>2016-08-26 01:38:25 -0500
committerScott Wood <oss@buserror.net>2016-09-25 02:38:54 -0500
commit63f1de882081919f2b548d04b6cf617398b8da12 (patch)
tree733c1382660c8c339d0cd65d508529be53602653
parent834e5a692120cc25c3935e8652a1989c2bc1c9e9 (diff)
downloadlinux-0-day-63f1de882081919f2b548d04b6cf617398b8da12.tar.gz
linux-0-day-63f1de882081919f2b548d04b6cf617398b8da12.tar.xz
powerpc/fsl_pci: Size upper inbound window based on RAM size
This allows PCI devices that can only address (e.g.) 36 or 40 bit DMA to use direct DMA, at the cost of not being able to DMA to non-RAM addresses (this doesn't affect MSIs as there is a separate dedicated window for that) which we wouldn't have been able to do anyway if the RAM size didn't trigger the creation of the second inbound window. It also fixes an off-by-one error that set dma_direct_ops on PCI devices whose dma mask could address all the space below the DMA offset (previously 40 bits), but not the window that starts at the DMA offset. Signed-off-by: Scott Wood <oss@buserror.net> Cc: Tillmann Heidsieck <theidsieck@leenox.de> Tested-by: Tillmann Heidsieck <theidsieck@leenox.de>
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 0ef9df49f0f2c..d3a597456b6e5 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -111,8 +111,7 @@ static struct pci_ops fsl_indirect_pcie_ops =
.write = indirect_write_config,
};
-#define MAX_PHYS_ADDR_BITS 40
-static u64 pci64_dma_offset = 1ull << MAX_PHYS_ADDR_BITS;
+static u64 pci64_dma_offset;
#ifdef CONFIG_SWIOTLB
static void setup_swiotlb_ops(struct pci_controller *hose)
@@ -132,12 +131,10 @@ static int fsl_pci_dma_set_mask(struct device *dev, u64 dma_mask)
return -EIO;
/*
- * Fixup PCI devices that are able to DMA to above the physical
- * address width of the SoC such that we can address any internal
- * SoC address from across PCI if needed
+ * Fix up PCI devices that are able to DMA to the large inbound
+ * mapping that allows addressing any RAM address from across PCI.
*/
- if ((dev_is_pci(dev)) &&
- dma_mask >= DMA_BIT_MASK(MAX_PHYS_ADDR_BITS)) {
+ if (dev_is_pci(dev) && dma_mask >= pci64_dma_offset * 2 - 1) {
set_dma_ops(dev, &dma_direct_ops);
set_dma_offset(dev, pci64_dma_offset);
}
@@ -387,6 +384,7 @@ static void setup_pci_atmu(struct pci_controller *hose)
mem_log++;
piwar = (piwar & ~PIWAR_SZ_MASK) | (mem_log - 1);
+ pci64_dma_offset = 1ULL << mem_log;
if (setup_inbound) {
/* Setup inbound memory window */