[RFC v2 PATCH 1/3] ARM: NOMMU: introduce dma operations for noMMU
flat view
DORMANTno replies
From: Vladimir Murzin <hidden>
Date: 2017-01-09 13:54:27
On 06/01/17 13:58, Benjamin Gaignard wrote:
2017-01-04 11:33 GMT+01:00 Vladimir Murzin [off-list ref]:quoted
Hello Benjamin, On 02/01/17 15:26, Benjamin Gaignard wrote:quoted
Hello Vladimir, I have tested your patch on my setup (stm32f4: no MMU, no MPU) where I'm writing display driver. This driver use dma_alloc_wc() and dma_mmap_wc() for frame buffer allocation and mmapping. In dma-mapping-nommu.c you haven't implement dma_map_ops.mmap so obviously my driver doesn't work with your code. In current implementation it is buggy too but I submit a patch to fix that problem: http://www.armlinux.org.uk/developer/patches/viewpatch.php?id=8633/1 Could it be possible for you to include mmap support in dma-mapping-nommu.c ?IIRC, stm32f4 is Cortex-M4, so no cache support and it means that it uses dma_noop_ops. I offloaded mmap to common implementation, but completely forgot it has the same restriction as arm counterpart. Regardless, thanks for noticing that! It seems that I need to check that mapping is done from DMA coherent area (I'm moving to dma-coherent and here we have dma_mmap_from_coherent for that) and something like bellow for dma_noop_ops:diff --git a/lib/dma-noop.c b/lib/dma-noop.c index 3d766e7..d838b88 100644 --- a/lib/dma-noop.c +++ b/lib/dma-noop.c@@ -64,6 +64,25 @@ static int dma_noop_supported(struct device *dev, u64 mask) return 1; } +static int dma_noop_mmap(struct device *dev, struct vm_area_struct *vma, + void *cpu_addr, dma_addr_t dma_addr, size_t size) +{ + unsigned long user_count = vma_pages(vma); + unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT; + unsigned long pfn = page_to_pfn(virt_to_page(cpu_addr)); + unsigned long off = vma->vm_pgoff; + int ret = -ENXIO; + + if (off < count && user_count <= (count - off)) { + ret = remap_pfn_range(vma, vma->vm_start, + pfn + off, + user_count << PAGE_SHIFT, + vma->vm_page_prot); + } + + return ret; +} + struct dma_map_ops dma_noop_ops = { .alloc = dma_noop_alloc, .free = dma_noop_free,@@ -71,6 +90,7 @@ struct dma_map_ops dma_noop_ops = { .map_sg = dma_noop_map_sg, .mapping_error = dma_noop_mapping_error, .dma_supported = dma_noop_supported, + .mmap = dma_noop_mmap, }; EXPORT_SYMBOL(dma_noop_ops);I'd be glad to hear if it works for you.With your patch mmap() does return an address unfortunately framebuffer isn't displayed anymore, I have a black screen instead of the usual pattern. Without your patches my allocations dma_alloc_wc requests go to dma-mapping so I guess the problem is coming from dma noop implementation. I have try to use dma-mapping-nommu ops but the status is the same.
Thanks for giving it a go! I messed up function prototype above, it should be:
static int dma_noop_mmap(struct device *dev, struct vm_area_struct *vma,
void *cpu_addr, dma_addr_t dma_addr, size_t size,
unsigned long attrs)
I've just sent v3 and I tested mmap() there with amba-clcd driver + some hacks
to make mmap call work with framebuffer.
Cheers
Vladimir
quoted
Cheers Vladimirquoted
Regards, Benjamin