ALSA on MIPS platform
Hi,
In
http://www.linux-mips.org/archives/linux-mips/2007-04/msg00114.html,
Atsushi Nemoto pointed out the problem is discussed before, the thread can be found at http://lkml.org/lkml/2006/1/25/117. Thanks Atsushi Nemoto:)
The problem is clear:
1. dma_alloc_noncoherent() return a non-cached address, and virt_to_page() need a cached logical addr (Have I named it right?)
2. mmaped dam buffer should be non-cached.
We have a ugly patch, but we want to solve the problem cleanly, so can anyone show me the way?
Regards,
Tian
sound/core/pcm_native.c +0 -0
@@ -3138,7 +3138,11 @@ static struct page
*snd_pcm_mmap_data_nopage(struct vm_area_struct *area,
return NOPAGE_OOM; /* XXX: is this really due to OOM? */
} else {
vaddr = runtime->dma_area + offset;
+#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT)
+ page = virt_to_page(CAC_ADDR(vaddr));
+#else
page = virt_to_page(vaddr);
+#endif
}
get_page(page);
if (type)
@@ -3254,6 +3258,11 @@ static int snd_pcm_mmap(struct file *file, struct
vm_area_struct *area)
substream = pcm_file->substream;
snd_assert(substream != NULL, return -ENXIO);+#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT)
+ /* all mmap using uncached mode */
+ area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
+#endif
+
offset = area->vm_pgoff << PAGE_SHIFT;
switch (offset) {
case SNDRV_PCM_MMAP_OFFSET_STATUS:sound/core/sgbuf.c +7 -0
@@ -91,12 +91,21 @@ void *snd_malloc_sgbuf_pages(struct device *device, } sgbuf->table[i].buf = tmpb.area; sgbuf->table[i].addr = tmpb.addr; +#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT ) + sgbuf->page_table[i] =virt_to_page (CAC_ADDR (tmpb.area)); +#else sgbuf->page_table[i] =virt_to_page (tmpb.area); +#endif sgbuf->pages++; } sgbuf->size = size; +#if defined(__mips__) && defined(CONFIG_DMA_NONCOHERENT ) +/* maybe we should use uncached accelerated mode */ + dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP,
pgprot_noncached(PAGE_KERNEL));
+#else
dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP,
PAGE_KERNEL);
+#endif
if (! dmab->area)
goto _failed;
return dmab->area;Quoted 7 lines · Songmao Tian
The problem is clear:
1.dma_alloc_noncoherent()return a non-cached address, andvirt_to_page()need a cached logical addr (Have I named it right?)
2. mmaped dam buffer should be non-cached.We have a ugly patch, but we want to solve the problem cleanly, so can anyone show me the way?
virt_to_page() is used in many place in mm so making it robust might affect performance. IMHO virt_to_page() seems too low-level as DMA API.
If something like dma_virt_to_page(dev, cpu_addr) which can take a cpu address returned by dma_xxx APIs was defined, MIPS can implement it appropriately.
And then pgprot_noncached issues still exist...
---
Atsushi Nemoto
Quoted 15 lines · Atsushi Nemoto
Quoted 8 lines · Songmao Tian
The problem is clear:
1.dma_alloc_noncoherent()return a non-cached address, andvirt_to_page()need a cached logical addr (Have I named it right?)
2. mmaped dam buffer should be non-cached.We have a ugly patch, but we want to solve the problem cleanly, so can anyone show me the way?
virt_to_page()is used in many place in mm so making it robust might affect performance. IMHOvirt_to_page()seems too low-level as DMA API.
Quoted 12 lines
If something like
dma_virt_to_page(dev, cpu_addr)which can take a cpu address returned bydma_xxxAPIs was defined, MIPS can implement it appropriately.And then
pgprot_noncachedissues still exist...---
Atsushi Nemoto
I agree, and I am investigating to implement a dma_map_coherent, but It seems dma_map_coherent doesn't solve all the problem and will change a lot of code:(
dma_virt_to_page can be something like this.
include/asm-mips/page.h +1 -0
@@ -181,6 +181,8 @@ typedef struct { unsigned long pgprot; } pgprot_t;#define virt_to_page (kaddr) pfn_to_page(PFN_DOWN(virt_to_phys(kaddr)))#define virt_addr_valid (kaddr) pfn_valid(PFN_DOWN(virt_to_phys(kaddr))) +#define dma_virt_to_page (dma_addr)
pfn_to_page(PFN_DOWN(virt_to_phys(CAC_ADDR(kaddr)))) +
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
include/linux/mm.h +4 -0
@@ -39,6 +39,10 @@ extern int sysctl_legacy_va_layout;#include <asm/pgtable.h> #include <asm/processor.h> +#ifndef dma_virt_to_page +#define dma_virt_to_page virt_to_page +#endif +#define nth_page (page,n) pfn_to_page(page_to_pfn((page)) + (n))/*
sound/core/sgbuf.c +1 -1
@@ -91,7 +91,7 @@ void *snd_malloc_sgbuf_pages(struct device *device, } sgbuf->table[i].buf = tmpb.area; sgbuf->table[i].addr = tmpb.addr; - sgbuf->page_table[i] =virt_to_page (tmpb.area); + sgbuf->page_table[i] =dma_virt_to_page (tmpb.area); sgbuf->pages++; }
At Fri, 03 Aug 2007 21:50:36 +0800,
Quoted 30 lines · Songmao Tian
Quoted 15 lines · Atsushi Nemoto
Quoted 8 lines · Songmao Tian
The problem is clear:
1.dma_alloc_noncoherent()return a non-cached address, andvirt_to_page()need a cached logical addr (Have I named it right?)
2. mmaped dam buffer should be non-cached.We have a ugly patch, but we want to solve the problem cleanly, so can anyone show me the way?
virt_to_page()is used in many place in mm so making it robust might affect performance. IMHOvirt_to_page()seems too low-level as DMA API.Quoted 12 lines
If something like
dma_virt_to_page(dev, cpu_addr)which can take a cpu address returned bydma_xxxAPIs was defined, MIPS can implement it appropriately.And then
pgprot_noncachedissues still exist...---
Atsushi Nemoto
Quoted 3 lines
I agree, and I am investigating to implement a
dma_map_coherent, but It seemsdma_map_coherentdoesn't solve all the problem and will change a lot of code:(
It won't be that much. You'll need to change snd_pcm_default_mmap() in sound/core/pcm_native.c to call dma_mmap_coherent() directly instead of nopage ops. But, this won't work with SG-buffers, which requires some more additional works.
Takashi
Quoted 45 lines · Takashi Iwai
At Fri, 03 Aug 2007 21:50:36 +0800,
Quoted 31 lines · Songmao Tian
Quoted 16 lines · Atsushi Nemoto
Quoted 9 lines · Songmao Tian
The problem is clear:
1.dma_alloc_noncoherent()return a non-cached address, andvirt_to_page()need a cached logical addr (Have I named it right?)
2. mmaped dam buffer should be non-cached.We have a ugly patch, but we want to solve the problem cleanly, so can anyone show me the way?
virt_to_page()is used in many place in mm so making it robust might affect performance. IMHOvirt_to_page()seems too low-level as DMA API.Quoted 13 lines
If something like
dma_virt_to_page(dev, cpu_addr)which can take a cpu address returned bydma_xxxAPIs was defined, MIPS can implement it appropriately.And then
pgprot_noncachedissues still exist...---
Atsushi NemotoQuoted 4 lines
I agree, and I am investigating to implement a
dma_map_coherent, but It seemsdma_map_coherentdoesn't solve all the problem and will change a lot of code:(It won't be that much. You'll need to change
snd_pcm_default_mmap()insound/core/pcm_native.cto calldma_mmap_coherent()directly instead of nopage ops. But, this won't work with SG-buffers, which requires some more additional works.
Quoted 8 lines
Takashi
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
I have no idea if the patch can work, the idea is not very clear now. And I use vt686b ac97 sound driver, the driver use sgbuf, so I will write a test program tomorrow. Good sleep...:)
And if any of you can take some time look into the patch, and give some review will be appreciated:)
arch/mips/mm/dma-default.c +0 -0
@@ -369,3 +369,23 @@ void dma_cache_sync(struct device *dev, void
*vaddr, size_t size,
}
EXPORT_SYMBOL(dma_cache_sync);
+
+static int dma_mmap(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size)
+{
+ if (remap_pfn_range(vma, vma->vm_start,
+ PFN_DOWN(virt_to_phys(CAC_ADDR(cpu_addr))) +vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot))
+ return -EAGAIN;
+ return 0;
+}
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size)
+{
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ return dma_mmap(dev, vma, cpu_addr, dma_addr, size);
+}
+EXPORT_SYMBOL(dma_mmap_coherent);
+
sound/core/pcm_native.c +0 -0
@@ -3152,6 +3152,8 @@ static struct vm_operations_struct
snd_pcm_vm_ops_data =
.close = snd_pcm_mmap_data_close,
.nopage = snd_pcm_mmap_data_nopage,
};
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size);
/*
* mmap the DMA buffer on RAM
@@ -3159,9 +3161,10 @@ static struct vm_operations_struct snd_pcm_vm_ops_data =
static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
struct vm_area_struct *area)
{
- area->vm_ops = &snd_pcm_vm_ops_data;
+ struct snd_pcm_runtime *runtime = substream->runtime;
area->vm_private_data = substream;
- area->vm_flags |= VM_RESERVED;
+ dma_mmap_coherent(NULL, area, runtime->dma_area,
+ runtime->dma_addr, runtime->dma_bytes);
atomic_inc(&substream->mmap_count);
return 0;}
At Fri, 03 Aug 2007 23:57:07 +0800,
Quoted 55 lines · Songmao Tian
Quoted 45 lines · Takashi Iwai
At Fri, 03 Aug 2007 21:50:36 +0800,
Quoted 31 lines · Songmao Tian
Quoted 16 lines · Atsushi Nemoto
Quoted 9 lines · Songmao Tian
The problem is clear:
1.dma_alloc_noncoherent()return a non-cached address, andvirt_to_page()need a cached logical addr (Have I named it right?)
2. mmaped dam buffer should be non-cached.We have a ugly patch, but we want to solve the problem cleanly, so can anyone show me the way?
virt_to_page()is used in many place in mm so making it robust might affect performance. IMHOvirt_to_page()seems too low-level as DMA API.Quoted 13 lines
If something like
dma_virt_to_page(dev, cpu_addr)which can take a cpu address returned bydma_xxxAPIs was defined, MIPS can implement it appropriately.And then
pgprot_noncachedissues still exist...---
Atsushi NemotoQuoted 4 lines
I agree, and I am investigating to implement a
dma_map_coherent, but It seemsdma_map_coherentdoesn't solve all the problem and will change a lot of code:(It won't be that much. You'll need to change
snd_pcm_default_mmap()insound/core/pcm_native.cto calldma_mmap_coherent()directly instead of nopage ops. But, this won't work with SG-buffers, which requires some more additional works.Quoted 8 lines
Takashi
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Quoted 3 lines
I have no idea if the patch can work, the idea is not very clear now. And I use vt686b ac97 sound driver, the driver use sgbuf, so I will write a test program tomorrow. Good sleep...:)
Ah, that's a bad luck. Then your patch won't work as it is. We'll need another function for SG-buffer, that calls dma_mmap_coherent() for each page found in the given buffer.
Takashi
Quoted 66 lines
And if any of you can take some time look into the patch, and give some review will be appreciated:)
arch/mips/mm/dma-default.c +6
-0@@ -369,3 +369,23 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size, }EXPORT_SYMBOL (dma_cache_sync); + +static int dma_mmap (struct device *dev,struct vm_area_struct *vma, +void *cpu_addr,dma_addr_t dma_addr,size_t size) +{ + if (remap_pfn_range(vma, vma->vm_start, + PFN_DOWN(virt_to_phys(CAC_ADDR(cpu_addr))) +
vma->vm_pgoff,arch/mips/mm/dma-default.c +14
-0+ vma->vm_end - vma->vm_start, + vma->vm_page_prot)) +return -EAGAIN ; +return 0 ; +} + +int dma_mmap_coherent (struct device *dev,struct vm_area_struct *vma, +void *cpu_addr,dma_addr_t dma_addr,size_t size) +{ + vma->vm_page_prot =pgprot_noncached (vma->vm_page_prot); +return dma_mmap (dev, vma, cpu_addr, dma_addr, size); +} +EXPORT_SYMBOL (dma_mmap_coherent); +sound/core/pcm_native.c +0
-0@@ -3152,6 +3152,8 @@ static struct vm_operations_struct
snd_pcm_vm_ops_data=
.close =snd_pcm_mmap_data_close,
.nopage =snd_pcm_mmap_data_nopage,
};sound/core/pcm_native.c +2
-0+int dma_mmap_coherent (struct device *dev,struct vm_area_struct *vma, +void *cpu_addr,dma_addr_t dma_addr,size_t size);/* * mmap the DMA buffer on RAM @@ -3159,9 +3161,10 @@ static struct vm_operations_struct
snd_pcm_vm_ops_data=
static int snd_pcm_default_mmap(structsnd_pcm_substream*substream,
structvm_area_struct*area)
{sound/core/pcm_native.c +3
-2- area->vm_ops = &snd_pcm_vm_ops_data; +struct snd_pcm_runtime *runtime = substream->runtime; area->vm_private_data = substream; - area->vm_flags |=VM_RESERVED ; +dma_mmap_coherent (NULL , area, runtime->dma_area, + runtime->dma_addr, runtime->dma_bytes);atomic_inc (&substream->mmap_count);return 0 ; }_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
I think this problem can be solved by revising the __pa macro like this:
include/asm-mips/page.h 2007-08-07 09:46:59.000000000 +0800 renamed from include/asm-mips/page.h 2007-08-07 09:45:00.000000000 +0800 +1 -1
@@ -150,7 +150,7 @@ }) #else #define __pa(x) \ - ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET) + (((unsigned long)(x) & 0x1fffffff) + PHYS_OFFSET) #endif
So, the virt_to_page can accept all cached or uncached address.
Tan
2007/8/3, Songmao Tian <[email protected]>:
Quoted 79 lines
Quoted 15 lines · Atsushi Nemoto
Quoted 8 lines · Songmao Tian
The problem is clear:
1.dma_alloc_noncoherent()return a non-cached address, andvirt_to_page()need a cached logical addr (Have I named it right?)
2. mmaped dam buffer should be non-cached.We have a ugly patch, but we want to solve the problem cleanly, so can anyone show me the way?
virt_to_page()is used in many place in mm so making it robust might affect performance. IMHOvirt_to_page()seems too low-level as DMA API.Quoted 12 lines
If something like
dma_virt_to_page(dev, cpu_addr)which can take a cpu address returned bydma_xxxAPIs was defined, MIPS can implement it appropriately.And then
pgprot_noncachedissues still exist...---
Atsushi NemotoI agree, and I am investigating to implement a
dma_map_coherent, but It seemsdma_map_coherentdoesn't solve all the problem and will change a lot of code:(
dma_virt_to_pagecan be something like this.include/asm-mips/page.h +2
-0@@ -181,6 +181,8 @@ typedef struct { unsigned long pgprot; } pgprot_t;#define virt_to_page (kaddr) pfn_to_page(PFN_DOWN(virt_to_phys(kaddr)))#define virt_addr_valid (kaddr) pfn_valid(PFN_DOWN(virt_to_phys(kaddr))) +#define dma_virt_to_page (dma_addr) pfn_to_page(PFN_DOWN(virt_to_phys(CAC_ADDR(kaddr)))) +#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)include/linux/mm.h +4
-0@@ -39,6 +39,10 @@ extern int sysctl_legacy_va_layout;#include <asm/pgtable.h> #include <asm/processor.h> +#ifndef dma_virt_to_page +#define dma_virt_to_page virt_to_page +#endif +#define nth_page (page,n) pfn_to_page(page_to_pfn((page)) + (n))/* sound/core/sgbuf.c +1
-1@@ -91,7 +91,7 @@ void *snd_malloc_sgbuf_pages(struct device *device, } sgbuf->table[i].buf = tmpb.area; sgbuf->table[i].addr = tmpb.addr; - sgbuf->page_table[i] =virt_to_page (tmpb.area); + sgbuf->page_table[i] =dma_virt_to_page (tmpb.area); sgbuf->pages++; }
Sorry, that aim at 2.6.18.
In the latest kernel:
include/asm-mips/io.h 2007-08-07 10:18:56.000000000 +0800 renamed from include/asm-mips/io.h 2007-08-07 10:18:03.000000000 +0800 +1 -1
@@ -116,7 +116,7 @@ */ static inline unsigned long virt_to_phys(volatile const void *address) { - return (unsigned long)address - PAGE_OFFSET + PHYS_OFFSET; + return ((unsigned long)address & 0x1fffffff) + PHYS_OFFSET; }
I think virt_to_phys or __pa should accept kseg1 address.
Tan
2007/8/7, Dajie Tan <[email protected]>:
Quoted 99 lines
I think this problem can be solved by revising the
__pamacro like this:include/asm-mips/page.h 2007-08-07 09:46:59.000000000 +0800 renamed from include/asm-mips/page.h 2007-08-07 09:45:00.000000000 +0800 +1
-1@@ -150,7 +150,7 @@ }) #else #define __pa(x) \ - ((unsigned long)(x) - PAGE_OFFSET + PHYS_OFFSET) + (((unsigned long)(x) & 0x1fffffff) + PHYS_OFFSET) #endifSo, the
virt_to_pagecan accept all cached or uncached address.Tan
2007/8/3, Songmao Tian <[email protected]>:
Quoted 79 lines
Quoted 15 lines · Atsushi Nemoto
Quoted 8 lines · Songmao Tian
The problem is clear:
1.dma_alloc_noncoherent()return a non-cached address, andvirt_to_page()need a cached logical addr (Have I named it right?)
2. mmaped dam buffer should be non-cached.We have a ugly patch, but we want to solve the problem cleanly, so can anyone show me the way?
virt_to_page()is used in many place in mm so making it robust might affect performance. IMHOvirt_to_page()seems too low-level as DMA API.Quoted 12 lines
If something like
dma_virt_to_page(dev, cpu_addr)which can take a cpu address returned bydma_xxxAPIs was defined, MIPS can implement it appropriately.And then
pgprot_noncachedissues still exist...---
Atsushi NemotoI agree, and I am investigating to implement a
dma_map_coherent, but It seemsdma_map_coherentdoesn't solve all the problem and will change a lot of code:(
dma_virt_to_pagecan be something like this.include/asm-mips/page.h +2
-0@@ -181,6 +181,8 @@ typedef struct { unsigned long pgprot; } pgprot_t;#define virt_to_page (kaddr) pfn_to_page(PFN_DOWN(virt_to_phys(kaddr)))#define virt_addr_valid (kaddr) pfn_valid(PFN_DOWN(virt_to_phys(kaddr))) +#define dma_virt_to_page (dma_addr) pfn_to_page(PFN_DOWN(virt_to_phys(CAC_ADDR(kaddr)))) +#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)include/linux/mm.h +4
-0@@ -39,6 +39,10 @@ extern int sysctl_legacy_va_layout;#include <asm/pgtable.h> #include <asm/processor.h> +#ifndef dma_virt_to_page +#define dma_virt_to_page virt_to_page +#endif +#define nth_page (page,n) pfn_to_page(page_to_pfn((page)) + (n))/* sound/core/sgbuf.c +1
-1@@ -91,7 +91,7 @@ void *snd_malloc_sgbuf_pages(struct device *device, } sgbuf->table[i].buf = tmpb.area; sgbuf->table[i].addr = tmpb.addr; - sgbuf->page_table[i] =virt_to_page (tmpb.area); + sgbuf->page_table[i] =dma_virt_to_page (tmpb.area); sgbuf->pages++; }
Signature · 4 lines
为天地立心 为生民立命 为往圣继绝学 为万世开太平
include/asm-mips/io.h 2007-08-07 10:18:56.000000000 +0800 line 120
Quoted 5 lines · Dajie Tan
static inline unsigned long
virt_to_phys(volatile const void *address){include/asm-mips/io.h 2007-08-07 10:18:56.000000000 +0800 renamed from include/asm-mips/io.h 2007-08-07 10:18:03.000000000 +0800 +1
-1- return (unsigned long)address - PAGE_OFFSET + PHYS_OFFSET; + return ((unsigned long)address & 0x1fffffff) + PHYS_OFFSET; }
This makes virt_to_phys() a bit slower, and more importantly, breaks 64-bit kernel.
---
Atsushi Nemoto
Quoted 9 lines · Atsushi Nemoto
include/asm-mips/io.h 2007-08-07 10:18:56.000000000 +0800 line 120
Quoted 5 lines · Dajie Tan
static inline unsigned long
virt_to_phys(volatile const void *address){include/asm-mips/io.h 2007-08-07 10:18:56.000000000 +0800 renamed from include/asm-mips/io.h 2007-08-07 10:18:03.000000000 +0800 +1
-1- return (unsigned long)address - PAGE_OFFSET + PHYS_OFFSET; + return ((unsigned long)address & 0x1fffffff) + PHYS_OFFSET; }This makes
virt_to_phys()a bit slower, and more importantly, breaks 64-bit kernel.
It's ALSA that is doing funny things here so there is no point in fixing the arch code to work for ALSA.
Ralf
At Tue, 7 Aug 2007 18:54:02 +0100,
Quoted 10 lines · Ralf Baechle
Quoted 7 lines · Atsushi Nemoto
Quoted 5 lines · Dajie Tan
static inline unsigned long
virt_to_phys(volatile const void *address){include/asm-mips/io.h 2007-08-07 10:18:56.000000000 +0800 renamed from include/asm-mips/io.h 2007-08-07 10:18:03.000000000 +0800 +1
-1- return (unsigned long)address - PAGE_OFFSET + PHYS_OFFSET; + return ((unsigned long)address & 0x1fffffff) + PHYS_OFFSET; }
Quoted 5 lines
Quoted 2 lines
This makes
virt_to_phys()a bit slower, and more importantly, breaks 64-bit kernel.It's ALSA that is doing funny things here so there is no point in fixing the arch code to work for ALSA.
Yep, but OTOH, the arch code doesn't provide a proper standard way to mmap the pages allocated via dma_alloc_coherent(). That's the missing piece, especially on mips and sparc. ARM has already one.
My wish is implementing dma_mmap_coherent() on all architectures, so that the driver can use it safely without messy ifdefs.
Takashi
Quoted 9 lines · Takashi Iwai
Quoted 2 lines
It's ALSA that is doing funny things here so there is no point in fixing the arch code to work for ALSA.
Yep, but OTOH, the arch code doesn't provide a proper standard way to mmap the pages allocated via
dma_alloc_coherent(). That's the missing piece, especially on mips and sparc. ARM has already one.My wish is implementing
dma_mmap_coherent()on all architectures, so that the driver can use it safely without messy ifdefs.
Adding dma_mmap_coherent has been proposed in 2004 but the discussion for some reason went nowhere because it apparently isn't implementable on PARISC due to cache synonyms - on MIPS we'd solve those issues where they exist by using uncached or writethrough mappings, as apropriate.
Ralf
Quoted 11 lines · Ralf Baechle
Quoted 6 lines
Yep, but OTOH, the arch code doesn't provide a proper standard way to mmap the pages allocated via
dma_alloc_coherent(). That's the missing piece, especially on mips and sparc. ARM has already one.My wish is implementing
dma_mmap_coherent()on all architectures, so that the driver can use it safely without messy ifdefs.Adding
dma_mmap_coherenthas been proposed in 2004 but the discussion for some reason went nowhere because it apparently isn't implementable on PARISC due to cache synonyms - on MIPS we'd solve those issues where they exist by using uncached or writethrough mappings, as apropriate.
Hmm, why should everybody suffer from some limitation of some peculiar
architecture? I would suggest to let them find an architecture-specific way of addressing the problem -- they surely have a good control over their own code and can implement a workaround that would not impede all the others.
Ralf, do you have an idea about what their issue exactly is?
Maciej
At Wed, 8 Aug 2007 12:58:52 +0100,
Quoted 10 lines · Ralf Baechle
Quoted 7 lines · Takashi Iwai
Quoted 2 lines
It's ALSA that is doing funny things here so there is no point in fixing the arch code to work for ALSA.
Yep, but OTOH, the arch code doesn't provide a proper standard way to mmap the pages allocated via
dma_alloc_coherent(). That's the missing piece, especially on mips and sparc. ARM has already one.
Quoted 7 lines
Quoted 2 lines
My wish is implementing
dma_mmap_coherent()on all architectures, so that the driver can use it safely without messy ifdefs.Adding
dma_mmap_coherenthas been proposed in 2004 but the discussion for some reason went nowhere because it apparently isn't implementable on PARISC due to cache synonyms - on MIPS we'd solve those issues where they exist by using uncached or writethrough mappings, as apropriate.
Actually, if it cannot be implemented (or not yet implemented properly) on some architectures, it's fine. Then we can simply drop the mmap support just for such an architecture. I suppose an inlined dma_mmap_coherent() that always returns an error, just like the earlier version of asm-generic/dma-mapping-broken.h, would work well.
But, currently, the driver has no idea which architecture is OK and which not, and which method to choose. That is where we got stuck.
Takashi
Quoted 11 lines · Ralf Baechle
Quoted 8 lines · Atsushi Nemoto
Quoted 6 lines · Dajie Tan
static inline unsigned long
virt_to_phys(volatile const void *address){include/asm-mips/io.h 2007-08-07 10:18:56.000000000 +0800 renamed from include/asm-mips/io.h 2007-08-07 10:18:03.000000000 +0800 +1
-1- return (unsigned long)address - PAGE_OFFSET + PHYS_OFFSET; + return ((unsigned long)address & 0x1fffffff) + PHYS_OFFSET; }
Quoted 11 lines
Quoted 3 lines
This makes
virt_to_phys()a bit slower, and more importantly, breaks 64-bit kernel.It's ALSA that is doing funny things here so there is no point in fixing the arch code to work for ALSA.
Ralf
arm has made a dma_mmap_coherent, but I don't quite understand the code and I am not sure the situation is the same.
Tian
Quoted 9 lines · Atsushi Nemoto
include/asm-mips/io.h 2007-08-07 10:18:56.000000000 +0800 line 120
Quoted 6 lines · Dajie Tan
static inline unsigned long
virt_to_phys(volatile const void *address){include/asm-mips/io.h 2007-08-07 10:18:56.000000000 +0800 renamed from include/asm-mips/io.h 2007-08-07 10:18:03.000000000 +0800 +1
-1- return (unsigned long)address - PAGE_OFFSET + PHYS_OFFSET; + return ((unsigned long)address & 0x1fffffff) + PHYS_OFFSET; }
Quoted 3 lines
This makes
virt_to_phys()a bit slower, and more importantly, breaks 64-bit kernel.
I have tried this way, and disassemble result show 32-bit kernel add only one instruction.
But I don't really insist on this patch, for it doesn't resolve some driver code requirement.
Quoted 9 lines
---
Atsushi Nemoto
_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel