diff options
author | David Daney <ddaney@caviumnetworks.com> | 2010-08-05 01:53:57 +0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2010-08-05 16:26:31 +0400 |
commit | 2b5987abaf2dd6c3934e0376b7d9f64411cdcf03 (patch) | |
tree | 1d3609613faed623728eed98a83565f781201420 /arch/mips/cavium-octeon/dma-octeon.c | |
parent | 70dc6f045fce6907b5d10377850a78ada6837ffb (diff) | |
download | linux-2b5987abaf2dd6c3934e0376b7d9f64411cdcf03.tar.xz |
MIPS: Octeon: Allow more than 3.75GB of memory with PCIe
We reserve the 3.75GB - 4GB region of PCIe address space for device to
device transfers, making the corresponding physical memory under
direct mapping unavailable for DMA.
To allow for PCIe DMA to all physical memory we map this chunk of
physical memory with BAR1. Because of the resulting discontinuity in
the mapping function, we remove a page of memory at each end of the
range so multi-page DMA buffers can never be allocated that span the
range.
Signed-off-by: David Daney <ddaney@caviumnetworks.com>
To: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/1535/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/cavium-octeon/dma-octeon.c')
-rw-r--r-- | arch/mips/cavium-octeon/dma-octeon.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c index be531ec1f206..d22b5a2d64f4 100644 --- a/arch/mips/cavium-octeon/dma-octeon.c +++ b/arch/mips/cavium-octeon/dma-octeon.c @@ -99,13 +99,16 @@ dma_addr_t octeon_map_dma_mem(struct device *dev, void *ptr, size_t size) panic("dma_map_single: " "Attempt to map illegal memory address 0x%llx\n", physical); - else if ((physical + size >= - (4ull<<30) - (OCTEON_PCI_BAR1_HOLE_SIZE<<20)) - && physical < (4ull<<30)) - pr_warning("dma_map_single: Warning: " - "Mapping memory address that might " - "conflict with devices 0x%llx-0x%llx\n", - physical, physical+size-1); + else if (physical >= CVMX_PCIE_BAR1_PHYS_BASE && + physical + size < (CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_PHYS_SIZE)) { + result = physical - CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_RC_BASE; + + if (((result+size-1) & dma_mask) != result+size-1) + panic("dma_map_single: Attempt to map address 0x%llx-0x%llx, which can't be accessed according to the dma mask 0x%llx\n", + physical, physical+size-1, dma_mask); + goto done; + } + /* The 2nd 256MB is mapped at 256<<20 instead of 0x410000000 */ if ((physical >= 0x410000000ull) && physical < 0x420000000ull) result = physical - 0x400000000ull; |