diff mbox

usb: ehci: Enable support for 64bit EHCI host controllers in arm64

Message ID 20140516174009.GB11276@arm.com
State New
Headers show

Commit Message

Catalin Marinas May 16, 2014, 5:40 p.m. UTC
On Fri, May 16, 2014 at 06:08:45PM +0100, Jon Medhurst (Tixy) wrote:
> On Fri, 2014-05-16 at 13:55 +0100, Catalin Marinas wrote:
> [...]
> > > It could if arm64 would restrict the DMA addresses to 32-bit, but it doesn't
> > > and I end up on my platform with USB DMA buffers allocated >4GB address.
> > 
> > dma_alloc_coherent() on arm64 should return 32-bit addresses if the
> > coherent_dma_mask is set to 32-bit.
> 
> Not if you have CONFIG_DMA_CMA. Unless I have misread the code, enabling
> CMA means memory comes from a common pool carved out at boot with no way
> for drivers to specify it's restrictions [1]. It's what I've spent most
> of the week trying to work around in a clean way, and have finally given
> up.

The easiest "hack" would be to pass a limit dma_contiguous_reserve()
in arm64_memblock_init(), something like this:


probably with a check for IS_ENABLED(CONFIG_ZONE_DMA) (we do this for
swiotlb initialisation).

At some point, if we have some system topology description we could
decide whether we need to limit the above based on the dma coherent
masks.

Comments

Jon Medhurst (Tixy) May 19, 2014, 8:21 a.m. UTC | #1
On Fri, 2014-05-16 at 18:40 +0100, Catalin Marinas wrote:
> On Fri, May 16, 2014 at 06:08:45PM +0100, Jon Medhurst (Tixy) wrote:
> > On Fri, 2014-05-16 at 13:55 +0100, Catalin Marinas wrote:
> > [...]
> > > > It could if arm64 would restrict the DMA addresses to 32-bit, but it doesn't
> > > > and I end up on my platform with USB DMA buffers allocated >4GB address.
> > > 
> > > dma_alloc_coherent() on arm64 should return 32-bit addresses if the
> > > coherent_dma_mask is set to 32-bit.
> > 
> > Not if you have CONFIG_DMA_CMA. Unless I have misread the code, enabling
> > CMA means memory comes from a common pool carved out at boot with no way
> > for drivers to specify it's restrictions [1]. It's what I've spent most
> > of the week trying to work around in a clean way, and have finally given
> > up.
> 
> The easiest "hack" would be to pass a limit dma_contiguous_reserve()
> in arm64_memblock_init(), something like this:

That is by far the easiest but I dismissed it because it affects all
platforms built from that source tree; and if the hack were extended to
include a kernel config option, that still may not work on a single
kernel binary expected to work on multiple platforms. Basically, I've
tried various was to do it 'properly' and after failing am resorting to
truly hideous hacks to the (out-of-tree driver) code - so at least other
platforms won't be impacted.
Catalin Marinas May 22, 2014, 3:59 p.m. UTC | #2
On Mon, May 19, 2014 at 09:21:17AM +0100, Jon Medhurst (Tixy) wrote:
> On Fri, 2014-05-16 at 18:40 +0100, Catalin Marinas wrote:
> > On Fri, May 16, 2014 at 06:08:45PM +0100, Jon Medhurst (Tixy) wrote:
> > > On Fri, 2014-05-16 at 13:55 +0100, Catalin Marinas wrote:
> > > [...]
> > > > > It could if arm64 would restrict the DMA addresses to 32-bit, but it doesn't
> > > > > and I end up on my platform with USB DMA buffers allocated >4GB address.
> > > > 
> > > > dma_alloc_coherent() on arm64 should return 32-bit addresses if the
> > > > coherent_dma_mask is set to 32-bit.
> > > 
> > > Not if you have CONFIG_DMA_CMA. Unless I have misread the code, enabling
> > > CMA means memory comes from a common pool carved out at boot with no way
> > > for drivers to specify it's restrictions [1]. It's what I've spent most
> > > of the week trying to work around in a clean way, and have finally given
> > > up.
> > 
> > The easiest "hack" would be to pass a limit dma_contiguous_reserve()
> > in arm64_memblock_init(), something like this:
> 
> That is by far the easiest but I dismissed it because it affects all
> platforms built from that source tree; and if the hack were extended to
> include a kernel config option, that still may not work on a single
> kernel binary expected to work on multiple platforms. Basically, I've
> tried various was to do it 'properly' and after failing am resorting to
> truly hideous hacks to the (out-of-tree driver) code - so at least other
> platforms won't be impacted.

Can you set a specific reserved memory region in the DT to be used by
CMA (via linux,cma-default), or it's just for the default size?

On arm64 we enabled CONFIG_DMA_CMA by default but compared to swiotlb it
doesn't honour GFP_DMA. The arm32 port sets the CMA limit to
arm_dma_limit which is 32-bit or a SoC-define one. So I'm tempted to
default to 32-bit as well if it can be overridden via DT.
Jon Medhurst (Tixy) May 22, 2014, 4:49 p.m. UTC | #3
On Thu, 2014-05-22 at 16:59 +0100, Catalin Marinas wrote:
> On Mon, May 19, 2014 at 09:21:17AM +0100, Jon Medhurst (Tixy) wrote:
> > On Fri, 2014-05-16 at 18:40 +0100, Catalin Marinas wrote:
> > > On Fri, May 16, 2014 at 06:08:45PM +0100, Jon Medhurst (Tixy) wrote:
> > > > On Fri, 2014-05-16 at 13:55 +0100, Catalin Marinas wrote:
> > > > [...]
> > > > > > It could if arm64 would restrict the DMA addresses to 32-bit, but it doesn't
> > > > > > and I end up on my platform with USB DMA buffers allocated >4GB address.
> > > > > 
> > > > > dma_alloc_coherent() on arm64 should return 32-bit addresses if the
> > > > > coherent_dma_mask is set to 32-bit.
> > > > 
> > > > Not if you have CONFIG_DMA_CMA. Unless I have misread the code, enabling
> > > > CMA means memory comes from a common pool carved out at boot with no way
> > > > for drivers to specify it's restrictions [1]. It's what I've spent most
> > > > of the week trying to work around in a clean way, and have finally given
> > > > up.
> > > 
> > > The easiest "hack" would be to pass a limit dma_contiguous_reserve()
> > > in arm64_memblock_init(), something like this:
> > 
> > That is by far the easiest but I dismissed it because it affects all
> > platforms built from that source tree; and if the hack were extended to
> > include a kernel config option, that still may not work on a single
> > kernel binary expected to work on multiple platforms. Basically, I've
> > tried various was to do it 'properly' and after failing am resorting to
> > truly hideous hacks to the (out-of-tree driver) code - so at least other
> > platforms won't be impacted.
> 
> Can you set a specific reserved memory region in the DT to be used by
> CMA (via linux,cma-default), or it's just for the default size?

The bindings and infrastructure got half merged in 3.15 but the patches
to actually make this usable in drivers are stalled...
http://lkml.org/lkml/2014/5/14/201

> On arm64 we enabled CONFIG_DMA_CMA by default but compared to swiotlb it
> doesn't honour GFP_DMA. The arm32 port sets the CMA limit to
> arm_dma_limit which is 32-bit or a SoC-define one. So I'm tempted to
> default to 32-bit as well if it can be overridden via DT.

I believe the CMA pool could have been over-ridden if the stalled
patches been accepted. I believe the specific patch for that is
http://lkml.org/lkml/2014/2/28/278

The bindings for all this CMA stuf is in
Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
diff mbox

Patch

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 51d5352e6ad5..558434c69612 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -162,7 +162,7 @@  void __init arm64_memblock_init(void)
 	}
 
 	early_init_fdt_scan_reserved_mem();
-	dma_contiguous_reserve(0);
+	dma_contiguous_reserve(dma_to_phys(NULL, DMA_BIT_MASK(32)) + 1);
 
 	memblock_allow_resize();
 	memblock_dump_all();