* [PATCH 1/4] Add linux/io.h to make it compile
@ 2012-10-15 12:54 Stany MARCEL
2012-10-15 12:54 ` [PATCH 2/4] Permit to read/write to shared page Stany MARCEL
` (4 more replies)
0 siblings, 5 replies; 21+ messages in thread
From: Stany MARCEL @ 2012-10-15 12:54 UTC (permalink / raw)
To: linux-m68k; +Cc: gerg, Stany MARCEL
Signed-off-by: Stany MARCEL <stany.marcel@novasys-ingenierie.com>
---
drivers/watchdog/m54xx_wdt.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/watchdog/m54xx_wdt.c b/drivers/watchdog/m54xx_wdt.c
index 173494a..7466b4b 100644
--- a/drivers/watchdog/m54xx_wdt.c
+++ b/drivers/watchdog/m54xx_wdt.c
@@ -29,6 +29,7 @@
#include <linux/bitops.h>
#include <linux/ioport.h>
#include <linux/uaccess.h>
+#include <linux/io.h>
#include <asm/coldfire.h>
#include <asm/m54xxsim.h>
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 2/4] Permit to read/write to shared page
2012-10-15 12:54 [PATCH 1/4] Add linux/io.h to make it compile Stany MARCEL
@ 2012-10-15 12:54 ` Stany MARCEL
2012-10-15 12:54 ` [PATCH 3/4] Add for MCF54xx a virtual non cached zone usable for data exchange with DMA Stany MARCEL
` (3 subsequent siblings)
4 siblings, 0 replies; 21+ messages in thread
From: Stany MARCEL @ 2012-10-15 12:54 UTC (permalink / raw)
To: linux-m68k; +Cc: gerg, Stany MARCEL
When flags are READ WRITE SHARED the page is now PAGE_SHARED defined as :
VALID | ACCESSED | DIRTY | READABLE | WRITABLE | ACCESSED
instead of
VALID | ACCESSED | SHARED
Signed-off-by: Stany MARCEL <stany.marcel@novasys-ingenierie.com>
---
arch/m68k/include/asm/mcf_pgtable.h | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/arch/m68k/include/asm/mcf_pgtable.h b/arch/m68k/include/asm/mcf_pgtable.h
index 3c79368..a7f53eb 100644
--- a/arch/m68k/include/asm/mcf_pgtable.h
+++ b/arch/m68k/include/asm/mcf_pgtable.h
@@ -64,8 +64,10 @@
| CF_PAGE_ACCESSED)
#define PAGE_SHARED __pgprot(CF_PAGE_VALID \
- | CF_PAGE_ACCESSED \
- | CF_PAGE_SHARED)
+ | CF_PAGE_DIRTY \
+ | CF_PAGE_READABLE \
+ | CF_PAGE_WRITABLE \
+ | CF_PAGE_ACCESSED)
#define PAGE_INIT __pgprot(CF_PAGE_VALID \
| CF_PAGE_READABLE \
@@ -124,10 +126,7 @@
| CF_PAGE_ACCESSED \
| CF_PAGE_READABLE)
#define __S010 PAGE_SHARED
-#define __S011 __pgprot(CF_PAGE_VALID \
- | CF_PAGE_ACCESSED \
- | CF_PAGE_SHARED \
- | CF_PAGE_READABLE)
+#define __S011 PAGE_SHARED
#define __S100 __pgprot(CF_PAGE_VALID \
| CF_PAGE_ACCESSED \
| CF_PAGE_EXEC)
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 3/4] Add for MCF54xx a virtual non cached zone usable for data exchange with DMA
2012-10-15 12:54 [PATCH 1/4] Add linux/io.h to make it compile Stany MARCEL
2012-10-15 12:54 ` [PATCH 2/4] Permit to read/write to shared page Stany MARCEL
@ 2012-10-15 12:54 ` Stany MARCEL
2012-10-15 13:22 ` [PATCH 3/4 V2] " Stany MARCEL
2012-10-15 12:54 ` [PATCH 4/4] Set ACR1 cache mode depending on kernel configuration Stany MARCEL
` (2 subsequent siblings)
4 siblings, 1 reply; 21+ messages in thread
From: Stany MARCEL @ 2012-10-15 12:54 UTC (permalink / raw)
To: linux-m68k; +Cc: gerg, Stany MARCEL
This permit to share data with DMA without caching issues. M54xx DMA bypass
cache so exchanged data must be flushed before DMA operation. But M54xx cache
opperation does not permit to easily flush concerned data. So this patch permit
to have a non cached zone used for GFP_DMA allocated data.
Signed-off-by: Stany MARCEL <stany.marcel@novasys-ingenierie.com>
---
arch/m68k/Kconfig.machine | 32 +++++++++++++++++
arch/m68k/include/asm/dma.h | 8 +++++
arch/m68k/include/asm/m54xxacr.h | 11 ++++++
arch/m68k/include/asm/mcf_pgalloc.h | 6 ++--
arch/m68k/include/asm/page_mm.h | 68 ++++++++++++++++++++++++++++++++++-
arch/m68k/kernel/dma.c | 14 ++++++++
arch/m68k/mm/mcfmmu.c | 38 ++++++++++++++++++++
arch/m68k/platform/coldfire/head.S | 31 ++++++++++++++++
arch/m68k/platform/coldfire/m54xx.c | 21 +++++++++++
9 files changed, 225 insertions(+), 4 deletions(-)
diff --git a/arch/m68k/Kconfig.machine b/arch/m68k/Kconfig.machine
index 7cdf6b0..f9a4d9d 100644
--- a/arch/m68k/Kconfig.machine
+++ b/arch/m68k/Kconfig.machine
@@ -512,6 +512,38 @@ config KERNELBASE
a system with the RAM based at address 0, and leaving enough room
for the theoretical maximum number of 256 vectors.
+config M54xx_DMA_ZONE
+ bool "M54xx non cached virtual zone for DMA"
+ depends on MMU
+ depends on M54xx
+ select SINGLE_MEMORY_CHUNK
+ help
+ Activate a virtual zone with tlb data entries initialized, in non
+ cached precise mode. This permit to share data with DMA without caching
+ issues. M54xx DMA bypass cache so exchanged data must be flushed
+ before DMA operation. But M54xx cache opperation does not permit to
+ easily flush concerned data. So this patch permit to have a non cached
+ zone used for GFP_DMA allocated data.
+
+config M54xx_DMA_ZONE_BASE
+ hex "Address of the base of a vitual non cached zone usable for DMA"
+ depends on M54xx_DMA_ZONE
+ default 0xC0000000
+ help
+ Define the address of a virtual zone, with tlb data entries
+ initialized, in non cached precise mode.
+ Addresse must be 1MB aligned, not already mapped and different than
+ KMAP and VM memory map
+
+config M54xx_DMA_ZONE_SIZE
+ hex "Size of the vitual non cached zone usable for DMA"
+ depends on M54xx_DMA_ZONE
+ default 0x800000
+ help
+ Define the size of a virtual zone, with tlb data entries
+ initialized, in non cached precise mode.
+ Size must be 1MB divisable.
+
comment "ROM configuration"
config ROM
diff --git a/arch/m68k/include/asm/dma.h b/arch/m68k/include/asm/dma.h
index 0ff3fc6..04e5d2c 100644
--- a/arch/m68k/include/asm/dma.h
+++ b/arch/m68k/include/asm/dma.h
@@ -479,10 +479,18 @@ static __inline__ int get_dma_residue(unsigned int dmanr)
#endif /* !defined(CONFIG_M5272) */
#endif /* CONFIG_COLDFIRE */
+#if defined(CONFIG_M54xx_DMA_ZONE)
+
+#define MAX_DMA_ADDRESS (CONFIG_M54xx_DMA_ZONE_BASE + \
+ CONFIG_M54xx_DMA_ZONE_SIZE - 1)
+
+#else
/* it's useless on the m68k, but unfortunately needed by the new
bootmem allocator (but this should do it for this) */
#define MAX_DMA_ADDRESS PAGE_OFFSET
+#endif
+
#define MAX_DMA_CHANNELS 8
extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
diff --git a/arch/m68k/include/asm/m54xxacr.h b/arch/m68k/include/asm/m54xxacr.h
index 192bbfe..cac5bcd 100644
--- a/arch/m68k/include/asm/m54xxacr.h
+++ b/arch/m68k/include/asm/m54xxacr.h
@@ -94,6 +94,8 @@
* register region as non-cacheable. And then we map all our RAM as
* cacheable and supervisor access only.
*/
+#ifndef CONFIG_M54xx_DMA_ZONE
+
#define ACR0_MODE (ACR_BA(CONFIG_MBAR)+ACR_ADMSK(0x1000000)+ \
ACR_ENABLE+ACR_SUPER+ACR_CM_OFF_PRE+ACR_SP)
#define ACR1_MODE (ACR_BA(CONFIG_RAMBASE)+ACR_ADMSK(CONFIG_RAMSIZE)+ \
@@ -104,6 +106,15 @@
#else
+#define ACR0_MODE 0xF00FA048
+#define ACR1_MODE 0x000FA028
+#define ACR2_MODE 0x00000000
+#define ACR3_MODE 0x000FA028
+
+#endif /* CONFIG_M54xx_DMA_ZONE */
+
+#else
+
/*
* For the non-MMU enabled case we map all of RAM as cacheable.
*/
diff --git a/arch/m68k/include/asm/mcf_pgalloc.h b/arch/m68k/include/asm/mcf_pgalloc.h
index 313f3dd..7fbb5ce 100644
--- a/arch/m68k/include/asm/mcf_pgalloc.h
+++ b/arch/m68k/include/asm/mcf_pgalloc.h
@@ -14,7 +14,7 @@ extern const char bad_pmd_string[];
extern inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
unsigned long address)
{
- unsigned long page = __get_free_page(GFP_DMA|__GFP_REPEAT);
+ unsigned long page = __get_free_page(GFP_KERNEL|__GFP_REPEAT);
if (!page)
return NULL;
@@ -51,7 +51,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page,
static inline struct page *pte_alloc_one(struct mm_struct *mm,
unsigned long address)
{
- struct page *page = alloc_pages(GFP_DMA|__GFP_REPEAT, 0);
+ struct page *page = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
pte_t *pte;
if (!page)
@@ -89,7 +89,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
{
pgd_t *new_pgd;
- new_pgd = (pgd_t *)__get_free_page(GFP_DMA | __GFP_NOWARN);
+ new_pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_NOWARN);
if (!new_pgd)
return NULL;
memcpy(new_pgd, swapper_pg_dir, PAGE_SIZE);
diff --git a/arch/m68k/include/asm/page_mm.h b/arch/m68k/include/asm/page_mm.h
index 89f2014..7985ffd 100644
--- a/arch/m68k/include/asm/page_mm.h
+++ b/arch/m68k/include/asm/page_mm.h
@@ -70,6 +70,8 @@ extern unsigned long m68k_memoffset;
#define WANT_PAGE_VIRTUAL
+#ifndef CONFIG_M54xx_DMA_ZONE
+
static inline unsigned long ___pa(void *vaddr)
{
unsigned long paddr;
@@ -91,6 +93,58 @@ static inline void *__va(unsigned long paddr)
: "0" (paddr), "i" (m68k_fixup_memoffset));
return vaddr;
}
+#else /* !CONFIG_M54xx_DMA_ZONE */
+
+extern unsigned long m54xx_dma_base;
+extern unsigned long m54xx_dma_end;
+
+/*
+ * Convert a virt to a phys
+ */
+static inline unsigned long ___pa(void *vaddr)
+{
+#if CONFIG_RAMBASE != PAGE_OFFSET
+ return ((unsigned long)vaddr & 0x0fffffff) + CONFIG_RAMBASE;
+#else
+ if ((unsigned long)vaddr >= CONFIG_M54xx_DMA_ZONE_BASE &&
+ (unsigned long)vaddr < (CONFIG_M54xx_DMA_ZONE_BASE +
+ CONFIG_M54xx_DMA_ZONE_SIZE)) {
+ /* address is in carved out DMA range */
+ return ((unsigned long)vaddr - CONFIG_M54xx_DMA_ZONE_BASE)
+ + CONFIG_RAMBASE;
+ } else if ((unsigned long)vaddr >= PAGE_OFFSET &&
+ (unsigned long)vaddr < (PAGE_OFFSET + CONFIG_RAMSIZE)) {
+ /* normal mapping */
+ return ((unsigned long)vaddr - PAGE_OFFSET) + CONFIG_RAMBASE;
+ }
+
+ return (unsigned long)vaddr;
+#endif
+}
+#define __pa(vaddr) ___pa((void *)(vaddr))
+
+/*
+ * Convert a phys to a virt
+ */
+static inline void *__va(unsigned long paddr)
+{
+#if CONFIG_RAMBASE != PAGE_OFFSET
+ return (void *)((paddr & 0x0fffffff) + PAGE_OFFSET);
+#else
+ if (paddr >= m54xx_dma_base && paddr <= m54xx_dma_end) {
+ /* mapped address for DMA */
+ return (void *)((paddr - CONFIG_RAMBASE)
+ + CONFIG_M54xx_DMA_ZONE_BASE);
+ } else if (paddr >= m54xx_dma_end &&
+ paddr < (CONFIG_RAMBASE + CONFIG_RAMSIZE)) {
+ /* normal mapping */
+ return (void *)((paddr - CONFIG_RAMBASE) + PAGE_OFFSET);
+ }
+ return (void *)paddr;
+#endif
+}
+
+#endif
#else /* !CONFIG_SUN3 */
/* This #define is a horrible hack to suppress lots of warnings. --m */
@@ -168,7 +222,19 @@ static inline __attribute_const__ int __virt_to_node_shift(void)
((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn; \
})
-#define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
+#ifndef CONFIG_M54xx_DMA_ZONE
+#define virt_addr_valid(kaddr) \
+ ((void *)(kaddr) >= (void *)PAGE_OFFSET && \
+ (void *)(kaddr) < high_memory)
+#else
+#define virt_addr_valid(kaddr) \
+ (((void *)(kaddr) >= (void *)PAGE_OFFSET && \
+ (void *)(kaddr) < high_memory) || \
+ ((void *)(kaddr) >= (void *)CONFIG_M54xx_DMA_ZONE_BASE && \
+ (void *)(kaddr) < (void *)(CONFIG_M54xx_DMA_ZONE_BASE \
+ + CONFIG_M54xx_DMA_ZONE_SIZE)))
+#endif
+
#define pfn_valid(pfn) virt_addr_valid(pfn_to_virt(pfn))
#endif /* __ASSEMBLY__ */
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index e546a55..57873d1 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -76,6 +76,15 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp)
{
void *ret;
+#ifdef CONFIG_M54xx_DMA_ZONE
+ /*
+ * On the M54xx platform with CONFIG_M54xx_DMA_ZONE the memory allocated
+ * with GFP_DMA is guaranteed to be DMA'able, and cache coherent.
+ */
+ size = PAGE_ALIGN(size);
+ ret = kmalloc(size, GFP_DMA);
+ *dma_handle = virt_to_phys(ret);
+#else
/* ignore region specifiers */
gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
@@ -87,13 +96,18 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
memset(ret, 0, size);
*dma_handle = virt_to_phys(ret);
}
+#endif
return ret;
}
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle)
{
+#ifdef CONFIG_M54xx_DMA_ZONE
+ kfree((void *)dma_handle);
+#else
free_pages((unsigned long)vaddr, get_order(size));
+#endif
}
#endif /* CONFIG_MMU && !CONFIG_COLDFIRE */
diff --git a/arch/m68k/mm/mcfmmu.c b/arch/m68k/mm/mcfmmu.c
index 875b800..932415b 100644
--- a/arch/m68k/mm/mcfmmu.c
+++ b/arch/m68k/mm/mcfmmu.c
@@ -77,11 +77,49 @@ void __init paging_init(void)
}
}
+#ifdef CONFIG_M54xx_DMA_ZONE
+ /* setup page tables for DMA area */
+ /* starting loc in page directory */
+ pg_dir = swapper_pg_dir + (CONFIG_M54xx_DMA_ZONE_BASE >> PGDIR_SHIFT);
+
+ size = (CONFIG_M54xx_DMA_ZONE_SIZE >> PAGE_SHIFT) * sizeof(pte_t);
+ size = (size + PAGE_SIZE) & ~(PAGE_SIZE-1);
+
+ next_pgtable = (unsigned long)alloc_bootmem_pages(size);
+
+ address = CONFIG_M54xx_DMA_ZONE_BASE;
+ while (address < (CONFIG_M54xx_DMA_ZONE_BASE +
+ CONFIG_M54xx_DMA_ZONE_SIZE)) {
+ pg_table = (pte_t *)next_pgtable;
+ next_pgtable += PTRS_PER_PTE * sizeof(pte_t);
+ pgd_val(*pg_dir) = (unsigned long)pg_table;
+ pg_dir++;
+
+ for (i = 0; i < PTRS_PER_PTE; ++i, ++pg_table) {
+ pte_t pte = pfn_pte(virt_to_pfn(address), PAGE_INIT);
+ if (address >= (CONFIG_M54xx_DMA_ZONE_BASE
+ + CONFIG_M54xx_DMA_ZONE_SIZE))
+ pte_val(pte) = 0;
+
+ set_pte(pg_table, pte);
+ address += PAGE_SIZE;
+ }
+ }
+#endif
current->mm = NULL;
for (zone = 0; zone < MAX_NR_ZONES; zone++)
zones_size[zone] = 0x0;
+
+#ifdef CONFIG_M54xx_DMA_ZONE
+ zones_size[ZONE_DMA] = CONFIG_M54xx_DMA_ZONE_SIZE >> PAGE_SHIFT;
+ zones_size[ZONE_NORMAL] =
+ (((unsigned long)high_memory
+ - PAGE_OFFSET) >> PAGE_SHIFT)
+ - zones_size[ZONE_DMA];
+#else
zones_size[ZONE_DMA] = num_pages;
+#endif
free_area_init(zones_size);
}
diff --git a/arch/m68k/platform/coldfire/head.S b/arch/m68k/platform/coldfire/head.S
index fa31be2..62b4f17 100644
--- a/arch/m68k/platform/coldfire/head.S
+++ b/arch/m68k/platform/coldfire/head.S
@@ -265,6 +265,37 @@ _clear_bss:
cmpl %a0,%a1 /* check if at end */
bne _clear_bss
+
+#ifdef CONFIG_M54xx_DMA_ZONE
+ clrl %d0
+__mmu_dma_map:
+ /* Set up search of TLB */
+ movel #CONFIG_M54xx_DMA_ZONE_BASE, %d1
+ addl %d0,%d1
+ addil #1,%d1
+ movel %d1, MMUAR
+ /* Search */
+ movel #(MMUOR_STLB+MMUOR_ADR), %d1
+ movel %d1, MMUOR
+ /* Set up tag value */
+ movel #CONFIG_M54xx_DMA_ZONE_BASE,%d1
+ addl %d0,%d1
+ addil #(MMUTR_SG+MMUTR_V),%d1
+ movel %d1, MMUTR
+ /* Set up data value */
+ movel #CONFIG_RAMBASE,%d1
+ addl %d0,%d1
+ addil #(MMUDR_SZ_1MB+MMUDR_CM_NCP+MMUDR_SP+MMUDR_R+MMUDR_W+MMUDR_LK),%d1
+ movel %d1, MMUDR
+ /* Save */
+ movel #(MMUOR_ACC+MMUOR_UAA), %d1
+ movel %d1, MMUOR
+
+ addil #0x100000,%d0
+ cmpil #CONFIG_M54xx_DMA_ZONE_SIZE,%d0
+ bnes __mmu_dma_map
+#endif
+
/*
* Load the current task pointer and stack.
*/
diff --git a/arch/m68k/platform/coldfire/m54xx.c b/arch/m68k/platform/coldfire/m54xx.c
index b587bf3..c207822 100644
--- a/arch/m68k/platform/coldfire/m54xx.c
+++ b/arch/m68k/platform/coldfire/m54xx.c
@@ -23,6 +23,9 @@
#include <asm/m54xxgpt.h>
#ifdef CONFIG_MMU
#include <asm/mmu_context.h>
+#ifdef CONFIG_M54xx_DMA_ZONE
+#include <asm/dma.h>
+#endif
#endif
/***************************************************************************/
@@ -56,6 +59,17 @@ static void mcf54xx_reset(void)
unsigned long num_pages;
+#ifdef CONFIG_M54xx_DMA_ZONE
+/* cf dma physical addresses */
+unsigned long m54xx_dma_base;
+EXPORT_SYMBOL(m54xx_dma_base);
+unsigned long m54xx_dma_end;
+EXPORT_SYMBOL(m54xx_dma_end);
+unsigned long m54xx_dma_size;
+EXPORT_SYMBOL(m54xx_dma_size);
+#endif
+
+
static void __init mcf54xx_bootmem_alloc(void)
{
unsigned long start_pfn;
@@ -83,6 +97,13 @@ static void __init mcf54xx_bootmem_alloc(void)
memstart += init_bootmem_node(NODE_DATA(0), start_pfn,
min_low_pfn, max_low_pfn);
free_bootmem_node(NODE_DATA(0), memstart, _ramend - memstart);
+
+#ifdef CONFIG_M54xx_DMA_ZONE
+ /* configure physical dma area */
+ m54xx_dma_base = __pa(PAGE_ALIGN(_ramstart));
+ m54xx_dma_size = CONFIG_M54xx_DMA_ZONE_SIZE;
+ m54xx_dma_end = CONFIG_RAMBASE + m54xx_dma_size - 1;
+#endif /* CONFIG_M54xx_DMA_ZONE */
}
#endif /* CONFIG_MMU */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 4/4] Set ACR1 cache mode depending on kernel configuration.
2012-10-15 12:54 [PATCH 1/4] Add linux/io.h to make it compile Stany MARCEL
2012-10-15 12:54 ` [PATCH 2/4] Permit to read/write to shared page Stany MARCEL
2012-10-15 12:54 ` [PATCH 3/4] Add for MCF54xx a virtual non cached zone usable for data exchange with DMA Stany MARCEL
@ 2012-10-15 12:54 ` Stany MARCEL
2012-10-15 13:22 ` [PATCH 4/4 V2] " Stany MARCEL
2012-10-15 13:58 ` [PATCH 1/4] Add linux/io.h to make it compile Philippe De Muyter
2012-10-15 14:08 ` [PATCH 1/4 V2] Add linux/io.h to make m54xx_wdt.c compile with MMU enabled Stany MARCEL
4 siblings, 1 reply; 21+ messages in thread
From: Stany MARCEL @ 2012-10-15 12:54 UTC (permalink / raw)
To: linux-m68k; +Cc: gerg, Stany MARCEL
For coldfire with MMU enabled, data cache did not follow the configuration but
was configured in writethrough mode.
Signed-off-by: Stany MARCEL <stany.marcel@novasys-ingenierie.com>
---
arch/m68k/include/asm/m54xxacr.h | 21 +++++++--------------
1 file changed, 7 insertions(+), 14 deletions(-)
diff --git a/arch/m68k/include/asm/m54xxacr.h b/arch/m68k/include/asm/m54xxacr.h
index cac5bcd..8f932be 100644
--- a/arch/m68k/include/asm/m54xxacr.h
+++ b/arch/m68k/include/asm/m54xxacr.h
@@ -94,25 +94,18 @@
* register region as non-cacheable. And then we map all our RAM as
* cacheable and supervisor access only.
*/
-#ifndef CONFIG_M54xx_DMA_ZONE
-
-#define ACR0_MODE (ACR_BA(CONFIG_MBAR)+ACR_ADMSK(0x1000000)+ \
+#define ACR0_MODE (ACR_BA(CONFIG_MBAR)+ACR_ADMSK(0x1000000)+ \
ACR_ENABLE+ACR_SUPER+ACR_CM_OFF_PRE+ACR_SP)
+#if defined(CONFIG_CACHE_COPYBACK)
#define ACR1_MODE (ACR_BA(CONFIG_RAMBASE)+ACR_ADMSK(CONFIG_RAMSIZE)+ \
- ACR_ENABLE+ACR_SUPER+ACR_SP)
+ ACR_ENABLE+ACR_SUPER+ACR_SP+ACR_CM_CP)
+#else
+#define ACR1_MODE (ACR_BA(CONFIG_RAMBASE)+ACR_ADMSK(CONFIG_RAMSIZE)+ \
+ ACR_ENABLE+ACR_SUPER+ACR_SP+ACR_CM_WT)
+#endif
#define ACR2_MODE 0
#define ACR3_MODE (ACR_BA(CONFIG_RAMBASE)+ACR_ADMSK(CONFIG_RAMSIZE)+ \
ACR_ENABLE+ACR_SUPER+ACR_SP)
-
-#else
-
-#define ACR0_MODE 0xF00FA048
-#define ACR1_MODE 0x000FA028
-#define ACR2_MODE 0x00000000
-#define ACR3_MODE 0x000FA028
-
-#endif /* CONFIG_M54xx_DMA_ZONE */
-
#else
/*
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 3/4 V2] Add for MCF54xx a virtual non cached zone usable for data exchange with DMA
2012-10-15 12:54 ` [PATCH 3/4] Add for MCF54xx a virtual non cached zone usable for data exchange with DMA Stany MARCEL
@ 2012-10-15 13:22 ` Stany MARCEL
2012-10-16 5:15 ` Greg Ungerer
0 siblings, 1 reply; 21+ messages in thread
From: Stany MARCEL @ 2012-10-15 13:22 UTC (permalink / raw)
To: linux-m68k; +Cc: gerg, Stany MARCEL
This permit to share data with DMA without caching issues. M54xx DMA bypass
cache so exchanged data must be flushed before DMA operation. But M54xx cache
opperation does not permit to easily flush concerned data. So this patch permit
to have a non cached zone used for GFP_DMA allocated data.
Signed-off-by: Stany MARCEL <stany.marcel@novasys-ingenierie.com>
---
Changes:
V2: This patch does not touch ACR anymore, ACR cache mode is only
modified by following patch that is now independant.
arch/m68k/Kconfig.machine | 32 +++++++++++++++++
arch/m68k/include/asm/dma.h | 8 +++++
arch/m68k/include/asm/mcf_pgalloc.h | 6 ++--
arch/m68k/include/asm/page_mm.h | 68 ++++++++++++++++++++++++++++++++++-
arch/m68k/kernel/dma.c | 14 ++++++++
arch/m68k/mm/mcfmmu.c | 38 ++++++++++++++++++++
arch/m68k/platform/coldfire/head.S | 31 ++++++++++++++++
arch/m68k/platform/coldfire/m54xx.c | 21 +++++++++++
8 files changed, 214 insertions(+), 4 deletions(-)
diff --git a/arch/m68k/Kconfig.machine b/arch/m68k/Kconfig.machine
index 7cdf6b0..f9a4d9d 100644
--- a/arch/m68k/Kconfig.machine
+++ b/arch/m68k/Kconfig.machine
@@ -512,6 +512,38 @@ config KERNELBASE
a system with the RAM based at address 0, and leaving enough room
for the theoretical maximum number of 256 vectors.
+config M54xx_DMA_ZONE
+ bool "M54xx non cached virtual zone for DMA"
+ depends on MMU
+ depends on M54xx
+ select SINGLE_MEMORY_CHUNK
+ help
+ Activate a virtual zone with tlb data entries initialized, in non
+ cached precise mode. This permit to share data with DMA without caching
+ issues. M54xx DMA bypass cache so exchanged data must be flushed
+ before DMA operation. But M54xx cache opperation does not permit to
+ easily flush concerned data. So this patch permit to have a non cached
+ zone used for GFP_DMA allocated data.
+
+config M54xx_DMA_ZONE_BASE
+ hex "Address of the base of a vitual non cached zone usable for DMA"
+ depends on M54xx_DMA_ZONE
+ default 0xC0000000
+ help
+ Define the address of a virtual zone, with tlb data entries
+ initialized, in non cached precise mode.
+ Addresse must be 1MB aligned, not already mapped and different than
+ KMAP and VM memory map
+
+config M54xx_DMA_ZONE_SIZE
+ hex "Size of the vitual non cached zone usable for DMA"
+ depends on M54xx_DMA_ZONE
+ default 0x800000
+ help
+ Define the size of a virtual zone, with tlb data entries
+ initialized, in non cached precise mode.
+ Size must be 1MB divisable.
+
comment "ROM configuration"
config ROM
diff --git a/arch/m68k/include/asm/dma.h b/arch/m68k/include/asm/dma.h
index 0ff3fc6..04e5d2c 100644
--- a/arch/m68k/include/asm/dma.h
+++ b/arch/m68k/include/asm/dma.h
@@ -479,10 +479,18 @@ static __inline__ int get_dma_residue(unsigned int dmanr)
#endif /* !defined(CONFIG_M5272) */
#endif /* CONFIG_COLDFIRE */
+#if defined(CONFIG_M54xx_DMA_ZONE)
+
+#define MAX_DMA_ADDRESS (CONFIG_M54xx_DMA_ZONE_BASE + \
+ CONFIG_M54xx_DMA_ZONE_SIZE - 1)
+
+#else
/* it's useless on the m68k, but unfortunately needed by the new
bootmem allocator (but this should do it for this) */
#define MAX_DMA_ADDRESS PAGE_OFFSET
+#endif
+
#define MAX_DMA_CHANNELS 8
extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
diff --git a/arch/m68k/include/asm/mcf_pgalloc.h b/arch/m68k/include/asm/mcf_pgalloc.h
index 313f3dd..7fbb5ce 100644
--- a/arch/m68k/include/asm/mcf_pgalloc.h
+++ b/arch/m68k/include/asm/mcf_pgalloc.h
@@ -14,7 +14,7 @@ extern const char bad_pmd_string[];
extern inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
unsigned long address)
{
- unsigned long page = __get_free_page(GFP_DMA|__GFP_REPEAT);
+ unsigned long page = __get_free_page(GFP_KERNEL|__GFP_REPEAT);
if (!page)
return NULL;
@@ -51,7 +51,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page,
static inline struct page *pte_alloc_one(struct mm_struct *mm,
unsigned long address)
{
- struct page *page = alloc_pages(GFP_DMA|__GFP_REPEAT, 0);
+ struct page *page = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
pte_t *pte;
if (!page)
@@ -89,7 +89,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
{
pgd_t *new_pgd;
- new_pgd = (pgd_t *)__get_free_page(GFP_DMA | __GFP_NOWARN);
+ new_pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_NOWARN);
if (!new_pgd)
return NULL;
memcpy(new_pgd, swapper_pg_dir, PAGE_SIZE);
diff --git a/arch/m68k/include/asm/page_mm.h b/arch/m68k/include/asm/page_mm.h
index 89f2014..7985ffd 100644
--- a/arch/m68k/include/asm/page_mm.h
+++ b/arch/m68k/include/asm/page_mm.h
@@ -70,6 +70,8 @@ extern unsigned long m68k_memoffset;
#define WANT_PAGE_VIRTUAL
+#ifndef CONFIG_M54xx_DMA_ZONE
+
static inline unsigned long ___pa(void *vaddr)
{
unsigned long paddr;
@@ -91,6 +93,58 @@ static inline void *__va(unsigned long paddr)
: "0" (paddr), "i" (m68k_fixup_memoffset));
return vaddr;
}
+#else /* !CONFIG_M54xx_DMA_ZONE */
+
+extern unsigned long m54xx_dma_base;
+extern unsigned long m54xx_dma_end;
+
+/*
+ * Convert a virt to a phys
+ */
+static inline unsigned long ___pa(void *vaddr)
+{
+#if CONFIG_RAMBASE != PAGE_OFFSET
+ return ((unsigned long)vaddr & 0x0fffffff) + CONFIG_RAMBASE;
+#else
+ if ((unsigned long)vaddr >= CONFIG_M54xx_DMA_ZONE_BASE &&
+ (unsigned long)vaddr < (CONFIG_M54xx_DMA_ZONE_BASE +
+ CONFIG_M54xx_DMA_ZONE_SIZE)) {
+ /* address is in carved out DMA range */
+ return ((unsigned long)vaddr - CONFIG_M54xx_DMA_ZONE_BASE)
+ + CONFIG_RAMBASE;
+ } else if ((unsigned long)vaddr >= PAGE_OFFSET &&
+ (unsigned long)vaddr < (PAGE_OFFSET + CONFIG_RAMSIZE)) {
+ /* normal mapping */
+ return ((unsigned long)vaddr - PAGE_OFFSET) + CONFIG_RAMBASE;
+ }
+
+ return (unsigned long)vaddr;
+#endif
+}
+#define __pa(vaddr) ___pa((void *)(vaddr))
+
+/*
+ * Convert a phys to a virt
+ */
+static inline void *__va(unsigned long paddr)
+{
+#if CONFIG_RAMBASE != PAGE_OFFSET
+ return (void *)((paddr & 0x0fffffff) + PAGE_OFFSET);
+#else
+ if (paddr >= m54xx_dma_base && paddr <= m54xx_dma_end) {
+ /* mapped address for DMA */
+ return (void *)((paddr - CONFIG_RAMBASE)
+ + CONFIG_M54xx_DMA_ZONE_BASE);
+ } else if (paddr >= m54xx_dma_end &&
+ paddr < (CONFIG_RAMBASE + CONFIG_RAMSIZE)) {
+ /* normal mapping */
+ return (void *)((paddr - CONFIG_RAMBASE) + PAGE_OFFSET);
+ }
+ return (void *)paddr;
+#endif
+}
+
+#endif
#else /* !CONFIG_SUN3 */
/* This #define is a horrible hack to suppress lots of warnings. --m */
@@ -168,7 +222,19 @@ static inline __attribute_const__ int __virt_to_node_shift(void)
((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn; \
})
-#define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
+#ifndef CONFIG_M54xx_DMA_ZONE
+#define virt_addr_valid(kaddr) \
+ ((void *)(kaddr) >= (void *)PAGE_OFFSET && \
+ (void *)(kaddr) < high_memory)
+#else
+#define virt_addr_valid(kaddr) \
+ (((void *)(kaddr) >= (void *)PAGE_OFFSET && \
+ (void *)(kaddr) < high_memory) || \
+ ((void *)(kaddr) >= (void *)CONFIG_M54xx_DMA_ZONE_BASE && \
+ (void *)(kaddr) < (void *)(CONFIG_M54xx_DMA_ZONE_BASE \
+ + CONFIG_M54xx_DMA_ZONE_SIZE)))
+#endif
+
#define pfn_valid(pfn) virt_addr_valid(pfn_to_virt(pfn))
#endif /* __ASSEMBLY__ */
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index e546a55..57873d1 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -76,6 +76,15 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp)
{
void *ret;
+#ifdef CONFIG_M54xx_DMA_ZONE
+ /*
+ * On the M54xx platform with CONFIG_M54xx_DMA_ZONE the memory allocated
+ * with GFP_DMA is guaranteed to be DMA'able, and cache coherent.
+ */
+ size = PAGE_ALIGN(size);
+ ret = kmalloc(size, GFP_DMA);
+ *dma_handle = virt_to_phys(ret);
+#else
/* ignore region specifiers */
gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
@@ -87,13 +96,18 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
memset(ret, 0, size);
*dma_handle = virt_to_phys(ret);
}
+#endif
return ret;
}
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle)
{
+#ifdef CONFIG_M54xx_DMA_ZONE
+ kfree((void *)dma_handle);
+#else
free_pages((unsigned long)vaddr, get_order(size));
+#endif
}
#endif /* CONFIG_MMU && !CONFIG_COLDFIRE */
diff --git a/arch/m68k/mm/mcfmmu.c b/arch/m68k/mm/mcfmmu.c
index 875b800..932415b 100644
--- a/arch/m68k/mm/mcfmmu.c
+++ b/arch/m68k/mm/mcfmmu.c
@@ -77,11 +77,49 @@ void __init paging_init(void)
}
}
+#ifdef CONFIG_M54xx_DMA_ZONE
+ /* setup page tables for DMA area */
+ /* starting loc in page directory */
+ pg_dir = swapper_pg_dir + (CONFIG_M54xx_DMA_ZONE_BASE >> PGDIR_SHIFT);
+
+ size = (CONFIG_M54xx_DMA_ZONE_SIZE >> PAGE_SHIFT) * sizeof(pte_t);
+ size = (size + PAGE_SIZE) & ~(PAGE_SIZE-1);
+
+ next_pgtable = (unsigned long)alloc_bootmem_pages(size);
+
+ address = CONFIG_M54xx_DMA_ZONE_BASE;
+ while (address < (CONFIG_M54xx_DMA_ZONE_BASE +
+ CONFIG_M54xx_DMA_ZONE_SIZE)) {
+ pg_table = (pte_t *)next_pgtable;
+ next_pgtable += PTRS_PER_PTE * sizeof(pte_t);
+ pgd_val(*pg_dir) = (unsigned long)pg_table;
+ pg_dir++;
+
+ for (i = 0; i < PTRS_PER_PTE; ++i, ++pg_table) {
+ pte_t pte = pfn_pte(virt_to_pfn(address), PAGE_INIT);
+ if (address >= (CONFIG_M54xx_DMA_ZONE_BASE
+ + CONFIG_M54xx_DMA_ZONE_SIZE))
+ pte_val(pte) = 0;
+
+ set_pte(pg_table, pte);
+ address += PAGE_SIZE;
+ }
+ }
+#endif
current->mm = NULL;
for (zone = 0; zone < MAX_NR_ZONES; zone++)
zones_size[zone] = 0x0;
+
+#ifdef CONFIG_M54xx_DMA_ZONE
+ zones_size[ZONE_DMA] = CONFIG_M54xx_DMA_ZONE_SIZE >> PAGE_SHIFT;
+ zones_size[ZONE_NORMAL] =
+ (((unsigned long)high_memory
+ - PAGE_OFFSET) >> PAGE_SHIFT)
+ - zones_size[ZONE_DMA];
+#else
zones_size[ZONE_DMA] = num_pages;
+#endif
free_area_init(zones_size);
}
diff --git a/arch/m68k/platform/coldfire/head.S b/arch/m68k/platform/coldfire/head.S
index fa31be2..62b4f17 100644
--- a/arch/m68k/platform/coldfire/head.S
+++ b/arch/m68k/platform/coldfire/head.S
@@ -265,6 +265,37 @@ _clear_bss:
cmpl %a0,%a1 /* check if at end */
bne _clear_bss
+
+#ifdef CONFIG_M54xx_DMA_ZONE
+ clrl %d0
+__mmu_dma_map:
+ /* Set up search of TLB */
+ movel #CONFIG_M54xx_DMA_ZONE_BASE, %d1
+ addl %d0,%d1
+ addil #1,%d1
+ movel %d1, MMUAR
+ /* Search */
+ movel #(MMUOR_STLB+MMUOR_ADR), %d1
+ movel %d1, MMUOR
+ /* Set up tag value */
+ movel #CONFIG_M54xx_DMA_ZONE_BASE,%d1
+ addl %d0,%d1
+ addil #(MMUTR_SG+MMUTR_V),%d1
+ movel %d1, MMUTR
+ /* Set up data value */
+ movel #CONFIG_RAMBASE,%d1
+ addl %d0,%d1
+ addil #(MMUDR_SZ_1MB+MMUDR_CM_NCP+MMUDR_SP+MMUDR_R+MMUDR_W+MMUDR_LK),%d1
+ movel %d1, MMUDR
+ /* Save */
+ movel #(MMUOR_ACC+MMUOR_UAA), %d1
+ movel %d1, MMUOR
+
+ addil #0x100000,%d0
+ cmpil #CONFIG_M54xx_DMA_ZONE_SIZE,%d0
+ bnes __mmu_dma_map
+#endif
+
/*
* Load the current task pointer and stack.
*/
diff --git a/arch/m68k/platform/coldfire/m54xx.c b/arch/m68k/platform/coldfire/m54xx.c
index b587bf3..c207822 100644
--- a/arch/m68k/platform/coldfire/m54xx.c
+++ b/arch/m68k/platform/coldfire/m54xx.c
@@ -23,6 +23,9 @@
#include <asm/m54xxgpt.h>
#ifdef CONFIG_MMU
#include <asm/mmu_context.h>
+#ifdef CONFIG_M54xx_DMA_ZONE
+#include <asm/dma.h>
+#endif
#endif
/***************************************************************************/
@@ -56,6 +59,17 @@ static void mcf54xx_reset(void)
unsigned long num_pages;
+#ifdef CONFIG_M54xx_DMA_ZONE
+/* cf dma physical addresses */
+unsigned long m54xx_dma_base;
+EXPORT_SYMBOL(m54xx_dma_base);
+unsigned long m54xx_dma_end;
+EXPORT_SYMBOL(m54xx_dma_end);
+unsigned long m54xx_dma_size;
+EXPORT_SYMBOL(m54xx_dma_size);
+#endif
+
+
static void __init mcf54xx_bootmem_alloc(void)
{
unsigned long start_pfn;
@@ -83,6 +97,13 @@ static void __init mcf54xx_bootmem_alloc(void)
memstart += init_bootmem_node(NODE_DATA(0), start_pfn,
min_low_pfn, max_low_pfn);
free_bootmem_node(NODE_DATA(0), memstart, _ramend - memstart);
+
+#ifdef CONFIG_M54xx_DMA_ZONE
+ /* configure physical dma area */
+ m54xx_dma_base = __pa(PAGE_ALIGN(_ramstart));
+ m54xx_dma_size = CONFIG_M54xx_DMA_ZONE_SIZE;
+ m54xx_dma_end = CONFIG_RAMBASE + m54xx_dma_size - 1;
+#endif /* CONFIG_M54xx_DMA_ZONE */
}
#endif /* CONFIG_MMU */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 4/4 V2] Set ACR1 cache mode depending on kernel configuration.
2012-10-15 12:54 ` [PATCH 4/4] Set ACR1 cache mode depending on kernel configuration Stany MARCEL
@ 2012-10-15 13:22 ` Stany MARCEL
2012-10-16 5:27 ` Greg Ungerer
0 siblings, 1 reply; 21+ messages in thread
From: Stany MARCEL @ 2012-10-15 13:22 UTC (permalink / raw)
To: linux-m68k; +Cc: gerg, Stany MARCEL
For coldfire with MMU enabled, data cache did not follow the configuration but
was configured in writethrough mode.
Signed-off-by: Stany MARCEL <stany.marcel@novasys-ingenierie.com>
---
Changes:
V2: This patch is now independant from the previous one
arch/m68k/include/asm/m54xxacr.h | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/arch/m68k/include/asm/m54xxacr.h b/arch/m68k/include/asm/m54xxacr.h
index 192bbfe..8f932be 100644
--- a/arch/m68k/include/asm/m54xxacr.h
+++ b/arch/m68k/include/asm/m54xxacr.h
@@ -94,14 +94,18 @@
* register region as non-cacheable. And then we map all our RAM as
* cacheable and supervisor access only.
*/
-#define ACR0_MODE (ACR_BA(CONFIG_MBAR)+ACR_ADMSK(0x1000000)+ \
+#define ACR0_MODE (ACR_BA(CONFIG_MBAR)+ACR_ADMSK(0x1000000)+ \
ACR_ENABLE+ACR_SUPER+ACR_CM_OFF_PRE+ACR_SP)
+#if defined(CONFIG_CACHE_COPYBACK)
#define ACR1_MODE (ACR_BA(CONFIG_RAMBASE)+ACR_ADMSK(CONFIG_RAMSIZE)+ \
- ACR_ENABLE+ACR_SUPER+ACR_SP)
+ ACR_ENABLE+ACR_SUPER+ACR_SP+ACR_CM_CP)
+#else
+#define ACR1_MODE (ACR_BA(CONFIG_RAMBASE)+ACR_ADMSK(CONFIG_RAMSIZE)+ \
+ ACR_ENABLE+ACR_SUPER+ACR_SP+ACR_CM_WT)
+#endif
#define ACR2_MODE 0
#define ACR3_MODE (ACR_BA(CONFIG_RAMBASE)+ACR_ADMSK(CONFIG_RAMSIZE)+ \
ACR_ENABLE+ACR_SUPER+ACR_SP)
-
#else
/*
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 1/4] Add linux/io.h to make it compile
2012-10-15 12:54 [PATCH 1/4] Add linux/io.h to make it compile Stany MARCEL
` (2 preceding siblings ...)
2012-10-15 12:54 ` [PATCH 4/4] Set ACR1 cache mode depending on kernel configuration Stany MARCEL
@ 2012-10-15 13:58 ` Philippe De Muyter
2012-10-15 14:06 ` Stany MARCEL
2012-10-15 14:08 ` [PATCH 1/4 V2] Add linux/io.h to make m54xx_wdt.c compile with MMU enabled Stany MARCEL
4 siblings, 1 reply; 21+ messages in thread
From: Philippe De Muyter @ 2012-10-15 13:58 UTC (permalink / raw)
To: Stany MARCEL; +Cc: linux-m68k, gerg
Hello Stany,
On Mon, Oct 15, 2012 at 02:54:37PM +0200, Stany MARCEL wrote:
> [PATCH 1/4] Add linux/io.h to make it compile
You could probably be more precise in your patch title :)
What error message did you get without your patch ?
I compile m54xx_wdt.c without CONFIG_MMU without error.
Best regards
Philippe
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH 1/4] Add linux/io.h to make it compile
2012-10-15 13:58 ` [PATCH 1/4] Add linux/io.h to make it compile Philippe De Muyter
@ 2012-10-15 14:06 ` Stany MARCEL
2012-10-15 14:39 ` Philippe De Muyter
0 siblings, 1 reply; 21+ messages in thread
From: Stany MARCEL @ 2012-10-15 14:06 UTC (permalink / raw)
To: Philippe De Muyter; +Cc: linux-m68k, gerg
Hello Philippe,
It does not compile with my config (MMU on), io.h header is missing for __raw_* operations.
But it might compile with MMU disabled.
Regards
-----Message d'origine-----
De : Philippe De Muyter [mailto:phdm@macqel.be]
Envoyé : lundi 15 octobre 2012 15:58
À : Stany MARCEL
Cc : linux-m68k@vger.kernel.org; gerg@uclinux.org
Objet : Re: [PATCH 1/4] Add linux/io.h to make it compile
Hello Stany,
On Mon, Oct 15, 2012 at 02:54:37PM +0200, Stany MARCEL wrote:
> [PATCH 1/4] Add linux/io.h to make it compile
You could probably be more precise in your patch title :)
What error message did you get without your patch ?
I compile m54xx_wdt.c without CONFIG_MMU without error.
Best regards
Philippe
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 1/4 V2] Add linux/io.h to make m54xx_wdt.c compile with MMU enabled.
2012-10-15 12:54 [PATCH 1/4] Add linux/io.h to make it compile Stany MARCEL
` (3 preceding siblings ...)
2012-10-15 13:58 ` [PATCH 1/4] Add linux/io.h to make it compile Philippe De Muyter
@ 2012-10-15 14:08 ` Stany MARCEL
2012-10-16 5:04 ` Greg Ungerer
4 siblings, 1 reply; 21+ messages in thread
From: Stany MARCEL @ 2012-10-15 14:08 UTC (permalink / raw)
To: linux-m68k; +Cc: gerg, Stany MARCEL
Signed-off-by: Stany MARCEL <stany.marcel@novasys-ingenierie.com>
---
Changes:
- V2: reword commit message.
drivers/watchdog/m54xx_wdt.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/watchdog/m54xx_wdt.c b/drivers/watchdog/m54xx_wdt.c
index 173494a..7466b4b 100644
--- a/drivers/watchdog/m54xx_wdt.c
+++ b/drivers/watchdog/m54xx_wdt.c
@@ -29,6 +29,7 @@
#include <linux/bitops.h>
#include <linux/ioport.h>
#include <linux/uaccess.h>
+#include <linux/io.h>
#include <asm/coldfire.h>
#include <asm/m54xxsim.h>
--
1.7.9.5
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 1/4] Add linux/io.h to make it compile
2012-10-15 14:06 ` Stany MARCEL
@ 2012-10-15 14:39 ` Philippe De Muyter
2012-10-16 4:58 ` Greg Ungerer
0 siblings, 1 reply; 21+ messages in thread
From: Philippe De Muyter @ 2012-10-15 14:39 UTC (permalink / raw)
To: Stany MARCEL; +Cc: linux-m68k, gerg
Hello Stany,
On Mon, Oct 15, 2012 at 04:06:47PM +0200, Stany MARCEL wrote:
> Hello Philippe,
>
> It does not compile with my config (MMU on), io.h header is missing for __raw_* operations.
Actually, the problem seems to be more in the .h files, that should
provide the same set of macros/functions regardless of CONFIG_MMU
or not.
I have a similar problem with out_be32 available from asm/io.h in
CONFIG_MMU mode, but not without CONFIG_MMU.
Greg, Geert ?
Best regards
Philippe
>
> But it might compile with MMU disabled.
>
> Regards
>
> -----Message d'origine-----
> De : Philippe De Muyter [mailto:phdm@macqel.be]
> Envoyé : lundi 15 octobre 2012 15:58
> À : Stany MARCEL
> Cc : linux-m68k@vger.kernel.org; gerg@uclinux.org
> Objet : Re: [PATCH 1/4] Add linux/io.h to make it compile
>
> Hello Stany,
>
> On Mon, Oct 15, 2012 at 02:54:37PM +0200, Stany MARCEL wrote:
>
> > [PATCH 1/4] Add linux/io.h to make it compile
>
> You could probably be more precise in your patch title :)
>
> What error message did you get without your patch ?
>
> I compile m54xx_wdt.c without CONFIG_MMU without error.
>
> Best regards
>
> Philippe
--
Philippe De Muyter +32 2 6101532 Macq SA rue de l'Aeronef 2 B-1140 Bruxelles
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 1/4] Add linux/io.h to make it compile
2012-10-15 14:39 ` Philippe De Muyter
@ 2012-10-16 4:58 ` Greg Ungerer
0 siblings, 0 replies; 21+ messages in thread
From: Greg Ungerer @ 2012-10-16 4:58 UTC (permalink / raw)
To: Philippe De Muyter; +Cc: Stany MARCEL, linux-m68k, gerg
Hi Philippe,
On 16/10/12 00:39, Philippe De Muyter wrote:
> On Mon, Oct 15, 2012 at 04:06:47PM +0200, Stany MARCEL wrote:
>> Hello Philippe,
>>
>> It does not compile with my config (MMU on), io.h header is missing for __raw_* operations.
>
> Actually, the problem seems to be more in the .h files, that should
> provide the same set of macros/functions regardless of CONFIG_MMU
> or not.
>
> I have a similar problem with out_be32 available from asm/io.h in
> CONFIG_MMU mode, but not without CONFIG_MMU.
>
> Greg, Geert ?
Yeah, the m68k io.h family of headers is all a bit messy.
It is on my list of things to merge and clean up. It is intended
that they should supply the same set of definitions.
But in this case any driver that uses any of the read/write family
of functions should include linux/io.h. The m54xx_wdt.c code
doesn't, it is just getting definitions by accident. (As it turns
out it is getting it because asm/pgtable.h includes asm/pgtable_no.h
which includes asm/io.h -- asm/pgtable_mm.h doesn't).
Regards
Greg
>>
>> But it might compile with MMU disabled.
>>
>> Regards
>>
>> -----Message d'origine-----
>> Deá: Philippe De Muyter [mailto:phdm@macqel.be]
>> EnvoyÚá: lundi 15 octobre 2012 15:58
>> └á: Stany MARCEL
>> Ccá: linux-m68k@vger.kernel.org; gerg@uclinux.org
>> Objetá: Re: [PATCH 1/4] Add linux/io.h to make it compile
>>
>> Hello Stany,
>>
>> On Mon, Oct 15, 2012 at 02:54:37PM +0200, Stany MARCEL wrote:
>>
>>> [PATCH 1/4] Add linux/io.h to make it compile
>>
>> You could probably be more precise in your patch title :)
>>
>> What error message did you get without your patch ?
>>
>> I compile m54xx_wdt.c without CONFIG_MMU without error.
>>
>> Best regards
>>
>> Philippe
>
--
------------------------------------------------------------------------
Greg Ungerer -- Principal Engineer EMAIL: gerg@snapgear.com
SnapGear Group, McAfee PHONE: +61 7 3435 2888
8 Gardner Close FAX: +61 7 3217 5323
Milton, QLD, 4064, Australia WEB: http://www.SnapGear.com
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 1/4 V2] Add linux/io.h to make m54xx_wdt.c compile with MMU enabled.
2012-10-15 14:08 ` [PATCH 1/4 V2] Add linux/io.h to make m54xx_wdt.c compile with MMU enabled Stany MARCEL
@ 2012-10-16 5:04 ` Greg Ungerer
2012-10-16 10:47 ` Stany MARCEL
0 siblings, 1 reply; 21+ messages in thread
From: Greg Ungerer @ 2012-10-16 5:04 UTC (permalink / raw)
To: Stany MARCEL; +Cc: linux-m68k, gerg
Hi Stany,
On 16/10/12 00:08, Stany MARCEL wrote:
> Signed-off-by: Stany MARCEL <stany.marcel@novasys-ingenierie.com>
I am fine with it. Though I think you should also include the
actual compile error you get in the commit message.
Acked-by: Greg Ungerer <gerg@uclinux.org>
Being a watchdog driver fix though it needs to also be sent to
the appropriate list and maintainer. get_mainatiner lists:
Wim Van Sebroeck <wim@iguana.be> (maintainer:WATCHDOG DEVICE D...)
linux-watchdog@vger.kernel.org (open list:WATCHDOG DEVICE D...)
linux-kernel@vger.kernel.org (open list)
Regards
Greg
> ---
>
> Changes:
> - V2: reword commit message.
>
> drivers/watchdog/m54xx_wdt.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/watchdog/m54xx_wdt.c b/drivers/watchdog/m54xx_wdt.c
> index 173494a..7466b4b 100644
> --- a/drivers/watchdog/m54xx_wdt.c
> +++ b/drivers/watchdog/m54xx_wdt.c
> @@ -29,6 +29,7 @@
> #include <linux/bitops.h>
> #include <linux/ioport.h>
> #include <linux/uaccess.h>
> +#include <linux/io.h>
>
> #include <asm/coldfire.h>
> #include <asm/m54xxsim.h>
> --
> 1.7.9.5
>
>
>
>
--
------------------------------------------------------------------------
Greg Ungerer -- Principal Engineer EMAIL: gerg@snapgear.com
SnapGear Group, McAfee PHONE: +61 7 3435 2888
8 Gardner Close FAX: +61 7 3217 5323
Milton, QLD, 4064, Australia WEB: http://www.SnapGear.com
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/4 V2] Add for MCF54xx a virtual non cached zone usable for data exchange with DMA
2012-10-15 13:22 ` [PATCH 3/4 V2] " Stany MARCEL
@ 2012-10-16 5:15 ` Greg Ungerer
2012-10-16 10:46 ` Stany MARCEL
0 siblings, 1 reply; 21+ messages in thread
From: Greg Ungerer @ 2012-10-16 5:15 UTC (permalink / raw)
To: Stany MARCEL; +Cc: linux-m68k, gerg
Hi Stany,
On 15/10/12 23:22, Stany MARCEL wrote:
> This permit to share data with DMA without caching issues. M54xx DMA bypass
> cache so exchanged data must be flushed before DMA operation. But M54xx cache
> opperation does not permit to easily flush concerned data. So this patch permit
> to have a non cached zone used for GFP_DMA allocated data.
Interesting, but I think this is the wrong approach.
We don't want to bypass the cache. Admittedly the current cache support
code we have for ColdFire is not great, it could be improved a lot. So
lets do that, not work around it.
Regards
Greg
> Signed-off-by: Stany MARCEL <stany.marcel@novasys-ingenierie.com>
> ---
>
> Changes:
> V2: This patch does not touch ACR anymore, ACR cache mode is only
> modified by following patch that is now independant.
>
> arch/m68k/Kconfig.machine | 32 +++++++++++++++++
> arch/m68k/include/asm/dma.h | 8 +++++
> arch/m68k/include/asm/mcf_pgalloc.h | 6 ++--
> arch/m68k/include/asm/page_mm.h | 68 ++++++++++++++++++++++++++++++++++-
> arch/m68k/kernel/dma.c | 14 ++++++++
> arch/m68k/mm/mcfmmu.c | 38 ++++++++++++++++++++
> arch/m68k/platform/coldfire/head.S | 31 ++++++++++++++++
> arch/m68k/platform/coldfire/m54xx.c | 21 +++++++++++
> 8 files changed, 214 insertions(+), 4 deletions(-)
>
> diff --git a/arch/m68k/Kconfig.machine b/arch/m68k/Kconfig.machine
> index 7cdf6b0..f9a4d9d 100644
> --- a/arch/m68k/Kconfig.machine
> +++ b/arch/m68k/Kconfig.machine
> @@ -512,6 +512,38 @@ config KERNELBASE
> a system with the RAM based at address 0, and leaving enough room
> for the theoretical maximum number of 256 vectors.
>
> +config M54xx_DMA_ZONE
> + bool "M54xx non cached virtual zone for DMA"
> + depends on MMU
> + depends on M54xx
> + select SINGLE_MEMORY_CHUNK
> + help
> + Activate a virtual zone with tlb data entries initialized, in non
> + cached precise mode. This permit to share data with DMA without caching
> + issues. M54xx DMA bypass cache so exchanged data must be flushed
> + before DMA operation. But M54xx cache opperation does not permit to
> + easily flush concerned data. So this patch permit to have a non cached
> + zone used for GFP_DMA allocated data.
> +
> +config M54xx_DMA_ZONE_BASE
> + hex "Address of the base of a vitual non cached zone usable for DMA"
> + depends on M54xx_DMA_ZONE
> + default 0xC0000000
> + help
> + Define the address of a virtual zone, with tlb data entries
> + initialized, in non cached precise mode.
> + Addresse must be 1MB aligned, not already mapped and different than
> + KMAP and VM memory map
> +
> +config M54xx_DMA_ZONE_SIZE
> + hex "Size of the vitual non cached zone usable for DMA"
> + depends on M54xx_DMA_ZONE
> + default 0x800000
> + help
> + Define the size of a virtual zone, with tlb data entries
> + initialized, in non cached precise mode.
> + Size must be 1MB divisable.
> +
> comment "ROM configuration"
>
> config ROM
> diff --git a/arch/m68k/include/asm/dma.h b/arch/m68k/include/asm/dma.h
> index 0ff3fc6..04e5d2c 100644
> --- a/arch/m68k/include/asm/dma.h
> +++ b/arch/m68k/include/asm/dma.h
> @@ -479,10 +479,18 @@ static __inline__ int get_dma_residue(unsigned int dmanr)
> #endif /* !defined(CONFIG_M5272) */
> #endif /* CONFIG_COLDFIRE */
>
> +#if defined(CONFIG_M54xx_DMA_ZONE)
> +
> +#define MAX_DMA_ADDRESS (CONFIG_M54xx_DMA_ZONE_BASE + \
> + CONFIG_M54xx_DMA_ZONE_SIZE - 1)
> +
> +#else
> /* it's useless on the m68k, but unfortunately needed by the new
> bootmem allocator (but this should do it for this) */
> #define MAX_DMA_ADDRESS PAGE_OFFSET
>
> +#endif
> +
> #define MAX_DMA_CHANNELS 8
>
> extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
> diff --git a/arch/m68k/include/asm/mcf_pgalloc.h b/arch/m68k/include/asm/mcf_pgalloc.h
> index 313f3dd..7fbb5ce 100644
> --- a/arch/m68k/include/asm/mcf_pgalloc.h
> +++ b/arch/m68k/include/asm/mcf_pgalloc.h
> @@ -14,7 +14,7 @@ extern const char bad_pmd_string[];
> extern inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
> unsigned long address)
> {
> - unsigned long page = __get_free_page(GFP_DMA|__GFP_REPEAT);
> + unsigned long page = __get_free_page(GFP_KERNEL|__GFP_REPEAT);
>
> if (!page)
> return NULL;
> @@ -51,7 +51,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page,
> static inline struct page *pte_alloc_one(struct mm_struct *mm,
> unsigned long address)
> {
> - struct page *page = alloc_pages(GFP_DMA|__GFP_REPEAT, 0);
> + struct page *page = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
> pte_t *pte;
>
> if (!page)
> @@ -89,7 +89,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
> {
> pgd_t *new_pgd;
>
> - new_pgd = (pgd_t *)__get_free_page(GFP_DMA | __GFP_NOWARN);
> + new_pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_NOWARN);
> if (!new_pgd)
> return NULL;
> memcpy(new_pgd, swapper_pg_dir, PAGE_SIZE);
> diff --git a/arch/m68k/include/asm/page_mm.h b/arch/m68k/include/asm/page_mm.h
> index 89f2014..7985ffd 100644
> --- a/arch/m68k/include/asm/page_mm.h
> +++ b/arch/m68k/include/asm/page_mm.h
> @@ -70,6 +70,8 @@ extern unsigned long m68k_memoffset;
>
> #define WANT_PAGE_VIRTUAL
>
> +#ifndef CONFIG_M54xx_DMA_ZONE
> +
> static inline unsigned long ___pa(void *vaddr)
> {
> unsigned long paddr;
> @@ -91,6 +93,58 @@ static inline void *__va(unsigned long paddr)
> : "0" (paddr), "i" (m68k_fixup_memoffset));
> return vaddr;
> }
> +#else /* !CONFIG_M54xx_DMA_ZONE */
> +
> +extern unsigned long m54xx_dma_base;
> +extern unsigned long m54xx_dma_end;
> +
> +/*
> + * Convert a virt to a phys
> + */
> +static inline unsigned long ___pa(void *vaddr)
> +{
> +#if CONFIG_RAMBASE != PAGE_OFFSET
> + return ((unsigned long)vaddr & 0x0fffffff) + CONFIG_RAMBASE;
> +#else
> + if ((unsigned long)vaddr >= CONFIG_M54xx_DMA_ZONE_BASE &&
> + (unsigned long)vaddr < (CONFIG_M54xx_DMA_ZONE_BASE +
> + CONFIG_M54xx_DMA_ZONE_SIZE)) {
> + /* address is in carved out DMA range */
> + return ((unsigned long)vaddr - CONFIG_M54xx_DMA_ZONE_BASE)
> + + CONFIG_RAMBASE;
> + } else if ((unsigned long)vaddr >= PAGE_OFFSET &&
> + (unsigned long)vaddr < (PAGE_OFFSET + CONFIG_RAMSIZE)) {
> + /* normal mapping */
> + return ((unsigned long)vaddr - PAGE_OFFSET) + CONFIG_RAMBASE;
> + }
> +
> + return (unsigned long)vaddr;
> +#endif
> +}
> +#define __pa(vaddr) ___pa((void *)(vaddr))
> +
> +/*
> + * Convert a phys to a virt
> + */
> +static inline void *__va(unsigned long paddr)
> +{
> +#if CONFIG_RAMBASE != PAGE_OFFSET
> + return (void *)((paddr & 0x0fffffff) + PAGE_OFFSET);
> +#else
> + if (paddr >= m54xx_dma_base && paddr <= m54xx_dma_end) {
> + /* mapped address for DMA */
> + return (void *)((paddr - CONFIG_RAMBASE)
> + + CONFIG_M54xx_DMA_ZONE_BASE);
> + } else if (paddr >= m54xx_dma_end &&
> + paddr < (CONFIG_RAMBASE + CONFIG_RAMSIZE)) {
> + /* normal mapping */
> + return (void *)((paddr - CONFIG_RAMBASE) + PAGE_OFFSET);
> + }
> + return (void *)paddr;
> +#endif
> +}
> +
> +#endif
>
> #else /* !CONFIG_SUN3 */
> /* This #define is a horrible hack to suppress lots of warnings. --m */
> @@ -168,7 +222,19 @@ static inline __attribute_const__ int __virt_to_node_shift(void)
> ((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn; \
> })
>
> -#define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
> +#ifndef CONFIG_M54xx_DMA_ZONE
> +#define virt_addr_valid(kaddr) \
> + ((void *)(kaddr) >= (void *)PAGE_OFFSET && \
> + (void *)(kaddr) < high_memory)
> +#else
> +#define virt_addr_valid(kaddr) \
> + (((void *)(kaddr) >= (void *)PAGE_OFFSET && \
> + (void *)(kaddr) < high_memory) || \
> + ((void *)(kaddr) >= (void *)CONFIG_M54xx_DMA_ZONE_BASE && \
> + (void *)(kaddr) < (void *)(CONFIG_M54xx_DMA_ZONE_BASE \
> + + CONFIG_M54xx_DMA_ZONE_SIZE)))
> +#endif
> +
> #define pfn_valid(pfn) virt_addr_valid(pfn_to_virt(pfn))
>
> #endif /* __ASSEMBLY__ */
> diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
> index e546a55..57873d1 100644
> --- a/arch/m68k/kernel/dma.c
> +++ b/arch/m68k/kernel/dma.c
> @@ -76,6 +76,15 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
> dma_addr_t *dma_handle, gfp_t gfp)
> {
> void *ret;
> +#ifdef CONFIG_M54xx_DMA_ZONE
> + /*
> + * On the M54xx platform with CONFIG_M54xx_DMA_ZONE the memory allocated
> + * with GFP_DMA is guaranteed to be DMA'able, and cache coherent.
> + */
> + size = PAGE_ALIGN(size);
> + ret = kmalloc(size, GFP_DMA);
> + *dma_handle = virt_to_phys(ret);
> +#else
> /* ignore region specifiers */
> gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
>
> @@ -87,13 +96,18 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
> memset(ret, 0, size);
> *dma_handle = virt_to_phys(ret);
> }
> +#endif
> return ret;
> }
>
> void dma_free_coherent(struct device *dev, size_t size,
> void *vaddr, dma_addr_t dma_handle)
> {
> +#ifdef CONFIG_M54xx_DMA_ZONE
> + kfree((void *)dma_handle);
> +#else
> free_pages((unsigned long)vaddr, get_order(size));
> +#endif
> }
>
> #endif /* CONFIG_MMU && !CONFIG_COLDFIRE */
> diff --git a/arch/m68k/mm/mcfmmu.c b/arch/m68k/mm/mcfmmu.c
> index 875b800..932415b 100644
> --- a/arch/m68k/mm/mcfmmu.c
> +++ b/arch/m68k/mm/mcfmmu.c
> @@ -77,11 +77,49 @@ void __init paging_init(void)
> }
> }
>
> +#ifdef CONFIG_M54xx_DMA_ZONE
> + /* setup page tables for DMA area */
> + /* starting loc in page directory */
> + pg_dir = swapper_pg_dir + (CONFIG_M54xx_DMA_ZONE_BASE >> PGDIR_SHIFT);
> +
> + size = (CONFIG_M54xx_DMA_ZONE_SIZE >> PAGE_SHIFT) * sizeof(pte_t);
> + size = (size + PAGE_SIZE) & ~(PAGE_SIZE-1);
> +
> + next_pgtable = (unsigned long)alloc_bootmem_pages(size);
> +
> + address = CONFIG_M54xx_DMA_ZONE_BASE;
> + while (address < (CONFIG_M54xx_DMA_ZONE_BASE +
> + CONFIG_M54xx_DMA_ZONE_SIZE)) {
> + pg_table = (pte_t *)next_pgtable;
> + next_pgtable += PTRS_PER_PTE * sizeof(pte_t);
> + pgd_val(*pg_dir) = (unsigned long)pg_table;
> + pg_dir++;
> +
> + for (i = 0; i < PTRS_PER_PTE; ++i, ++pg_table) {
> + pte_t pte = pfn_pte(virt_to_pfn(address), PAGE_INIT);
> + if (address >= (CONFIG_M54xx_DMA_ZONE_BASE
> + + CONFIG_M54xx_DMA_ZONE_SIZE))
> + pte_val(pte) = 0;
> +
> + set_pte(pg_table, pte);
> + address += PAGE_SIZE;
> + }
> + }
> +#endif
> current->mm = NULL;
>
> for (zone = 0; zone < MAX_NR_ZONES; zone++)
> zones_size[zone] = 0x0;
> +
> +#ifdef CONFIG_M54xx_DMA_ZONE
> + zones_size[ZONE_DMA] = CONFIG_M54xx_DMA_ZONE_SIZE >> PAGE_SHIFT;
> + zones_size[ZONE_NORMAL] =
> + (((unsigned long)high_memory
> + - PAGE_OFFSET) >> PAGE_SHIFT)
> + - zones_size[ZONE_DMA];
> +#else
> zones_size[ZONE_DMA] = num_pages;
> +#endif
> free_area_init(zones_size);
> }
>
> diff --git a/arch/m68k/platform/coldfire/head.S b/arch/m68k/platform/coldfire/head.S
> index fa31be2..62b4f17 100644
> --- a/arch/m68k/platform/coldfire/head.S
> +++ b/arch/m68k/platform/coldfire/head.S
> @@ -265,6 +265,37 @@ _clear_bss:
> cmpl %a0,%a1 /* check if at end */
> bne _clear_bss
>
> +
> +#ifdef CONFIG_M54xx_DMA_ZONE
> + clrl %d0
> +__mmu_dma_map:
> + /* Set up search of TLB */
> + movel #CONFIG_M54xx_DMA_ZONE_BASE, %d1
> + addl %d0,%d1
> + addil #1,%d1
> + movel %d1, MMUAR
> + /* Search */
> + movel #(MMUOR_STLB+MMUOR_ADR), %d1
> + movel %d1, MMUOR
> + /* Set up tag value */
> + movel #CONFIG_M54xx_DMA_ZONE_BASE,%d1
> + addl %d0,%d1
> + addil #(MMUTR_SG+MMUTR_V),%d1
> + movel %d1, MMUTR
> + /* Set up data value */
> + movel #CONFIG_RAMBASE,%d1
> + addl %d0,%d1
> + addil #(MMUDR_SZ_1MB+MMUDR_CM_NCP+MMUDR_SP+MMUDR_R+MMUDR_W+MMUDR_LK),%d1
> + movel %d1, MMUDR
> + /* Save */
> + movel #(MMUOR_ACC+MMUOR_UAA), %d1
> + movel %d1, MMUOR
> +
> + addil #0x100000,%d0
> + cmpil #CONFIG_M54xx_DMA_ZONE_SIZE,%d0
> + bnes __mmu_dma_map
> +#endif
> +
> /*
> * Load the current task pointer and stack.
> */
> diff --git a/arch/m68k/platform/coldfire/m54xx.c b/arch/m68k/platform/coldfire/m54xx.c
> index b587bf3..c207822 100644
> --- a/arch/m68k/platform/coldfire/m54xx.c
> +++ b/arch/m68k/platform/coldfire/m54xx.c
> @@ -23,6 +23,9 @@
> #include <asm/m54xxgpt.h>
> #ifdef CONFIG_MMU
> #include <asm/mmu_context.h>
> +#ifdef CONFIG_M54xx_DMA_ZONE
> +#include <asm/dma.h>
> +#endif
> #endif
>
> /***************************************************************************/
> @@ -56,6 +59,17 @@ static void mcf54xx_reset(void)
>
> unsigned long num_pages;
>
> +#ifdef CONFIG_M54xx_DMA_ZONE
> +/* cf dma physical addresses */
> +unsigned long m54xx_dma_base;
> +EXPORT_SYMBOL(m54xx_dma_base);
> +unsigned long m54xx_dma_end;
> +EXPORT_SYMBOL(m54xx_dma_end);
> +unsigned long m54xx_dma_size;
> +EXPORT_SYMBOL(m54xx_dma_size);
> +#endif
> +
> +
> static void __init mcf54xx_bootmem_alloc(void)
> {
> unsigned long start_pfn;
> @@ -83,6 +97,13 @@ static void __init mcf54xx_bootmem_alloc(void)
> memstart += init_bootmem_node(NODE_DATA(0), start_pfn,
> min_low_pfn, max_low_pfn);
> free_bootmem_node(NODE_DATA(0), memstart, _ramend - memstart);
> +
> +#ifdef CONFIG_M54xx_DMA_ZONE
> + /* configure physical dma area */
> + m54xx_dma_base = __pa(PAGE_ALIGN(_ramstart));
> + m54xx_dma_size = CONFIG_M54xx_DMA_ZONE_SIZE;
> + m54xx_dma_end = CONFIG_RAMBASE + m54xx_dma_size - 1;
> +#endif /* CONFIG_M54xx_DMA_ZONE */
> }
>
> #endif /* CONFIG_MMU */
> --
> 1.7.9.5
>
>
>
>
--
------------------------------------------------------------------------
Greg Ungerer -- Principal Engineer EMAIL: gerg@snapgear.com
SnapGear Group, McAfee PHONE: +61 7 3435 2888
8 Gardner Close FAX: +61 7 3217 5323
Milton, QLD, 4064, Australia WEB: http://www.SnapGear.com
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 4/4 V2] Set ACR1 cache mode depending on kernel configuration.
2012-10-15 13:22 ` [PATCH 4/4 V2] " Stany MARCEL
@ 2012-10-16 5:27 ` Greg Ungerer
2012-10-16 8:12 ` Philippe De Muyter
0 siblings, 1 reply; 21+ messages in thread
From: Greg Ungerer @ 2012-10-16 5:27 UTC (permalink / raw)
To: Stany MARCEL; +Cc: linux-m68k, gerg
Hi Stany,
On 15/10/12 23:22, Stany MARCEL wrote:
> For coldfire with MMU enabled, data cache did not follow the configuration but
> was configured in writethrough mode.
>
> Signed-off-by: Stany MARCEL <stany.marcel@novasys-ingenierie.com>
Looks good, thanks. Applied without the white space changes.
Regards
Greg
> ---
>
> Changes:
> V2: This patch is now independant from the previous one
>
> arch/m68k/include/asm/m54xxacr.h | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/arch/m68k/include/asm/m54xxacr.h b/arch/m68k/include/asm/m54xxacr.h
> index 192bbfe..8f932be 100644
> --- a/arch/m68k/include/asm/m54xxacr.h
> +++ b/arch/m68k/include/asm/m54xxacr.h
> @@ -94,14 +94,18 @@
> * register region as non-cacheable. And then we map all our RAM as
> * cacheable and supervisor access only.
> */
> -#define ACR0_MODE (ACR_BA(CONFIG_MBAR)+ACR_ADMSK(0x1000000)+ \
> +#define ACR0_MODE (ACR_BA(CONFIG_MBAR)+ACR_ADMSK(0x1000000)+ \
> ACR_ENABLE+ACR_SUPER+ACR_CM_OFF_PRE+ACR_SP)
> +#if defined(CONFIG_CACHE_COPYBACK)
> #define ACR1_MODE (ACR_BA(CONFIG_RAMBASE)+ACR_ADMSK(CONFIG_RAMSIZE)+ \
> - ACR_ENABLE+ACR_SUPER+ACR_SP)
> + ACR_ENABLE+ACR_SUPER+ACR_SP+ACR_CM_CP)
> +#else
> +#define ACR1_MODE (ACR_BA(CONFIG_RAMBASE)+ACR_ADMSK(CONFIG_RAMSIZE)+ \
> + ACR_ENABLE+ACR_SUPER+ACR_SP+ACR_CM_WT)
> +#endif
> #define ACR2_MODE 0
> #define ACR3_MODE (ACR_BA(CONFIG_RAMBASE)+ACR_ADMSK(CONFIG_RAMSIZE)+ \
> ACR_ENABLE+ACR_SUPER+ACR_SP)
> -
> #else
>
> /*
> --
> 1.7.9.5
>
>
>
>
--
------------------------------------------------------------------------
Greg Ungerer -- Principal Engineer EMAIL: gerg@snapgear.com
SnapGear Group, McAfee PHONE: +61 7 3435 2888
8 Gardner Close FAX: +61 7 3217 5323
Milton, QLD, 4064, Australia WEB: http://www.SnapGear.com
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 4/4 V2] Set ACR1 cache mode depending on kernel configuration.
2012-10-16 5:27 ` Greg Ungerer
@ 2012-10-16 8:12 ` Philippe De Muyter
2012-10-16 12:06 ` Greg Ungerer
0 siblings, 1 reply; 21+ messages in thread
From: Philippe De Muyter @ 2012-10-16 8:12 UTC (permalink / raw)
To: Greg Ungerer; +Cc: Stany MARCEL, linux-m68k, gerg
Hi Stany and Greg,
On Tue, Oct 16, 2012 at 03:27:26PM +1000, Greg Ungerer wrote:
> Hi Stany,
>
> On 15/10/12 23:22, Stany MARCEL wrote:
>> For coldfire with MMU enabled, data cache did not follow the configuration
>> but
>> was configured in writethrough mode.
>>
>> Signed-off-by: Stany MARCEL <stany.marcel@novasys-ingenierie.com>
>
> Looks good, thanks. Applied without the white space changes.
Wouldn't it be better to move the test on CONFIG_CACHE_COPYBACK outside
of the test on CONFIG_MMU instead of duplicating it ?
Philippe
>
> Regards
> Greg
>
>
>> ---
>>
>> Changes:
>> V2: This patch is now independant from the previous one
>>
>> arch/m68k/include/asm/m54xxacr.h | 10 +++++++---
>> 1 file changed, 7 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/m68k/include/asm/m54xxacr.h
>> b/arch/m68k/include/asm/m54xxacr.h
>> index 192bbfe..8f932be 100644
>> --- a/arch/m68k/include/asm/m54xxacr.h
>> +++ b/arch/m68k/include/asm/m54xxacr.h
>> @@ -94,14 +94,18 @@
>> * register region as non-cacheable. And then we map all our RAM as
>> * cacheable and supervisor access only.
>> */
>> -#define ACR0_MODE (ACR_BA(CONFIG_MBAR)+ACR_ADMSK(0x1000000)+ \
>> +#define ACR0_MODE (ACR_BA(CONFIG_MBAR)+ACR_ADMSK(0x1000000)+ \
>> ACR_ENABLE+ACR_SUPER+ACR_CM_OFF_PRE+ACR_SP)
>> +#if defined(CONFIG_CACHE_COPYBACK)
>> #define ACR1_MODE (ACR_BA(CONFIG_RAMBASE)+ACR_ADMSK(CONFIG_RAMSIZE)+ \
>> - ACR_ENABLE+ACR_SUPER+ACR_SP)
>> + ACR_ENABLE+ACR_SUPER+ACR_SP+ACR_CM_CP)
>> +#else
>> +#define ACR1_MODE (ACR_BA(CONFIG_RAMBASE)+ACR_ADMSK(CONFIG_RAMSIZE)+ \
>> + ACR_ENABLE+ACR_SUPER+ACR_SP+ACR_CM_WT)
>> +#endif
>> #define ACR2_MODE 0
>> #define ACR3_MODE (ACR_BA(CONFIG_RAMBASE)+ACR_ADMSK(CONFIG_RAMSIZE)+ \
>> ACR_ENABLE+ACR_SUPER+ACR_SP)
>> -
>> #else
>>
>> /*
>> --
>> 1.7.9.5
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH 3/4 V2] Add for MCF54xx a virtual non cached zone usable for data exchange with DMA
2012-10-16 5:15 ` Greg Ungerer
@ 2012-10-16 10:46 ` Stany MARCEL
2012-10-16 11:23 ` Philippe De Muyter
2012-10-16 12:29 ` Greg Ungerer
0 siblings, 2 replies; 21+ messages in thread
From: Stany MARCEL @ 2012-10-16 10:46 UTC (permalink / raw)
To: Greg Ungerer; +Cc: linux-m68k, gerg
Hi Greg,
It might not be the usual approach in Linux, but after reading the MCF548x Reference Manual,
I think that is the best approach for this family of MCU.
Regards,
Stany
-----Original Message-----
From: Greg Ungerer [mailto:gerg@snapgear.com]
Sent: Tue 10/16/2012 7:15 AM
To: Stany MARCEL
Cc: linux-m68k@vger.kernel.org; gerg@uclinux.org
Subject: Re: [PATCH 3/4 V2] Add for MCF54xx a virtual non cached zone usable for data exchange with DMA
Hi Stany,
On 15/10/12 23:22, Stany MARCEL wrote:
> This permit to share data with DMA without caching issues. M54xx DMA bypass
> cache so exchanged data must be flushed before DMA operation. But M54xx cache
> opperation does not permit to easily flush concerned data. So this patch permit
> to have a non cached zone used for GFP_DMA allocated data.
Interesting, but I think this is the wrong approach.
We don't want to bypass the cache. Admittedly the current cache support
code we have for ColdFire is not great, it could be improved a lot. So
lets do that, not work around it.
Regards
Greg
> Signed-off-by: Stany MARCEL <stany.marcel@novasys-ingenierie.com>
> ---
>
> Changes:
> V2: This patch does not touch ACR anymore, ACR cache mode is only
> modified by following patch that is now independant.
>
> arch/m68k/Kconfig.machine | 32 +++++++++++++++++
> arch/m68k/include/asm/dma.h | 8 +++++
> arch/m68k/include/asm/mcf_pgalloc.h | 6 ++--
> arch/m68k/include/asm/page_mm.h | 68 ++++++++++++++++++++++++++++++++++-
> arch/m68k/kernel/dma.c | 14 ++++++++
> arch/m68k/mm/mcfmmu.c | 38 ++++++++++++++++++++
> arch/m68k/platform/coldfire/head.S | 31 ++++++++++++++++
> arch/m68k/platform/coldfire/m54xx.c | 21 +++++++++++
> 8 files changed, 214 insertions(+), 4 deletions(-)
>
> diff --git a/arch/m68k/Kconfig.machine b/arch/m68k/Kconfig.machine
> index 7cdf6b0..f9a4d9d 100644
> --- a/arch/m68k/Kconfig.machine
> +++ b/arch/m68k/Kconfig.machine
> @@ -512,6 +512,38 @@ config KERNELBASE
> a system with the RAM based at address 0, and leaving enough room
> for the theoretical maximum number of 256 vectors.
>
> +config M54xx_DMA_ZONE
> + bool "M54xx non cached virtual zone for DMA"
> + depends on MMU
> + depends on M54xx
> + select SINGLE_MEMORY_CHUNK
> + help
> + Activate a virtual zone with tlb data entries initialized, in non
> + cached precise mode. This permit to share data with DMA without caching
> + issues. M54xx DMA bypass cache so exchanged data must be flushed
> + before DMA operation. But M54xx cache opperation does not permit to
> + easily flush concerned data. So this patch permit to have a non cached
> + zone used for GFP_DMA allocated data.
> +
> +config M54xx_DMA_ZONE_BASE
> + hex "Address of the base of a vitual non cached zone usable for DMA"
> + depends on M54xx_DMA_ZONE
> + default 0xC0000000
> + help
> + Define the address of a virtual zone, with tlb data entries
> + initialized, in non cached precise mode.
> + Addresse must be 1MB aligned, not already mapped and different than
> + KMAP and VM memory map
> +
> +config M54xx_DMA_ZONE_SIZE
> + hex "Size of the vitual non cached zone usable for DMA"
> + depends on M54xx_DMA_ZONE
> + default 0x800000
> + help
> + Define the size of a virtual zone, with tlb data entries
> + initialized, in non cached precise mode.
> + Size must be 1MB divisable.
> +
> comment "ROM configuration"
>
> config ROM
> diff --git a/arch/m68k/include/asm/dma.h b/arch/m68k/include/asm/dma.h
> index 0ff3fc6..04e5d2c 100644
> --- a/arch/m68k/include/asm/dma.h
> +++ b/arch/m68k/include/asm/dma.h
> @@ -479,10 +479,18 @@ static __inline__ int get_dma_residue(unsigned int dmanr)
> #endif /* !defined(CONFIG_M5272) */
> #endif /* CONFIG_COLDFIRE */
>
> +#if defined(CONFIG_M54xx_DMA_ZONE)
> +
> +#define MAX_DMA_ADDRESS (CONFIG_M54xx_DMA_ZONE_BASE + \
> + CONFIG_M54xx_DMA_ZONE_SIZE - 1)
> +
> +#else
> /* it's useless on the m68k, but unfortunately needed by the new
> bootmem allocator (but this should do it for this) */
> #define MAX_DMA_ADDRESS PAGE_OFFSET
>
> +#endif
> +
> #define MAX_DMA_CHANNELS 8
>
> extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
> diff --git a/arch/m68k/include/asm/mcf_pgalloc.h b/arch/m68k/include/asm/mcf_pgalloc.h
> index 313f3dd..7fbb5ce 100644
> --- a/arch/m68k/include/asm/mcf_pgalloc.h
> +++ b/arch/m68k/include/asm/mcf_pgalloc.h
> @@ -14,7 +14,7 @@ extern const char bad_pmd_string[];
> extern inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
> unsigned long address)
> {
> - unsigned long page = __get_free_page(GFP_DMA|__GFP_REPEAT);
> + unsigned long page = __get_free_page(GFP_KERNEL|__GFP_REPEAT);
>
> if (!page)
> return NULL;
> @@ -51,7 +51,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page,
> static inline struct page *pte_alloc_one(struct mm_struct *mm,
> unsigned long address)
> {
> - struct page *page = alloc_pages(GFP_DMA|__GFP_REPEAT, 0);
> + struct page *page = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
> pte_t *pte;
>
> if (!page)
> @@ -89,7 +89,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
> {
> pgd_t *new_pgd;
>
> - new_pgd = (pgd_t *)__get_free_page(GFP_DMA | __GFP_NOWARN);
> + new_pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_NOWARN);
> if (!new_pgd)
> return NULL;
> memcpy(new_pgd, swapper_pg_dir, PAGE_SIZE);
> diff --git a/arch/m68k/include/asm/page_mm.h b/arch/m68k/include/asm/page_mm.h
> index 89f2014..7985ffd 100644
> --- a/arch/m68k/include/asm/page_mm.h
> +++ b/arch/m68k/include/asm/page_mm.h
> @@ -70,6 +70,8 @@ extern unsigned long m68k_memoffset;
>
> #define WANT_PAGE_VIRTUAL
>
> +#ifndef CONFIG_M54xx_DMA_ZONE
> +
> static inline unsigned long ___pa(void *vaddr)
> {
> unsigned long paddr;
> @@ -91,6 +93,58 @@ static inline void *__va(unsigned long paddr)
> : "0" (paddr), "i" (m68k_fixup_memoffset));
> return vaddr;
> }
> +#else /* !CONFIG_M54xx_DMA_ZONE */
> +
> +extern unsigned long m54xx_dma_base;
> +extern unsigned long m54xx_dma_end;
> +
> +/*
> + * Convert a virt to a phys
> + */
> +static inline unsigned long ___pa(void *vaddr)
> +{
> +#if CONFIG_RAMBASE != PAGE_OFFSET
> + return ((unsigned long)vaddr & 0x0fffffff) + CONFIG_RAMBASE;
> +#else
> + if ((unsigned long)vaddr >= CONFIG_M54xx_DMA_ZONE_BASE &&
> + (unsigned long)vaddr < (CONFIG_M54xx_DMA_ZONE_BASE +
> + CONFIG_M54xx_DMA_ZONE_SIZE)) {
> + /* address is in carved out DMA range */
> + return ((unsigned long)vaddr - CONFIG_M54xx_DMA_ZONE_BASE)
> + + CONFIG_RAMBASE;
> + } else if ((unsigned long)vaddr >= PAGE_OFFSET &&
> + (unsigned long)vaddr < (PAGE_OFFSET + CONFIG_RAMSIZE)) {
> + /* normal mapping */
> + return ((unsigned long)vaddr - PAGE_OFFSET) + CONFIG_RAMBASE;
> + }
> +
> + return (unsigned long)vaddr;
> +#endif
> +}
> +#define __pa(vaddr) ___pa((void *)(vaddr))
> +
> +/*
> + * Convert a phys to a virt
> + */
> +static inline void *__va(unsigned long paddr)
> +{
> +#if CONFIG_RAMBASE != PAGE_OFFSET
> + return (void *)((paddr & 0x0fffffff) + PAGE_OFFSET);
> +#else
> + if (paddr >= m54xx_dma_base && paddr <= m54xx_dma_end) {
> + /* mapped address for DMA */
> + return (void *)((paddr - CONFIG_RAMBASE)
> + + CONFIG_M54xx_DMA_ZONE_BASE);
> + } else if (paddr >= m54xx_dma_end &&
> + paddr < (CONFIG_RAMBASE + CONFIG_RAMSIZE)) {
> + /* normal mapping */
> + return (void *)((paddr - CONFIG_RAMBASE) + PAGE_OFFSET);
> + }
> + return (void *)paddr;
> +#endif
> +}
> +
> +#endif
>
> #else /* !CONFIG_SUN3 */
> /* This #define is a horrible hack to suppress lots of warnings. --m */
> @@ -168,7 +222,19 @@ static inline __attribute_const__ int __virt_to_node_shift(void)
> ((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn; \
> })
>
> -#define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
> +#ifndef CONFIG_M54xx_DMA_ZONE
> +#define virt_addr_valid(kaddr) \
> + ((void *)(kaddr) >= (void *)PAGE_OFFSET && \
> + (void *)(kaddr) < high_memory)
> +#else
> +#define virt_addr_valid(kaddr) \
> + (((void *)(kaddr) >= (void *)PAGE_OFFSET && \
> + (void *)(kaddr) < high_memory) || \
> + ((void *)(kaddr) >= (void *)CONFIG_M54xx_DMA_ZONE_BASE && \
> + (void *)(kaddr) < (void *)(CONFIG_M54xx_DMA_ZONE_BASE \
> + + CONFIG_M54xx_DMA_ZONE_SIZE)))
> +#endif
> +
> #define pfn_valid(pfn) virt_addr_valid(pfn_to_virt(pfn))
>
> #endif /* __ASSEMBLY__ */
> diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
> index e546a55..57873d1 100644
> --- a/arch/m68k/kernel/dma.c
> +++ b/arch/m68k/kernel/dma.c
> @@ -76,6 +76,15 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
> dma_addr_t *dma_handle, gfp_t gfp)
> {
> void *ret;
> +#ifdef CONFIG_M54xx_DMA_ZONE
> + /*
> + * On the M54xx platform with CONFIG_M54xx_DMA_ZONE the memory allocated
> + * with GFP_DMA is guaranteed to be DMA'able, and cache coherent.
> + */
> + size = PAGE_ALIGN(size);
> + ret = kmalloc(size, GFP_DMA);
> + *dma_handle = virt_to_phys(ret);
> +#else
> /* ignore region specifiers */
> gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
>
> @@ -87,13 +96,18 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
> memset(ret, 0, size);
> *dma_handle = virt_to_phys(ret);
> }
> +#endif
> return ret;
> }
>
> void dma_free_coherent(struct device *dev, size_t size,
> void *vaddr, dma_addr_t dma_handle)
> {
> +#ifdef CONFIG_M54xx_DMA_ZONE
> + kfree((void *)dma_handle);
> +#else
> free_pages((unsigned long)vaddr, get_order(size));
> +#endif
> }
>
> #endif /* CONFIG_MMU && !CONFIG_COLDFIRE */
> diff --git a/arch/m68k/mm/mcfmmu.c b/arch/m68k/mm/mcfmmu.c
> index 875b800..932415b 100644
> --- a/arch/m68k/mm/mcfmmu.c
> +++ b/arch/m68k/mm/mcfmmu.c
> @@ -77,11 +77,49 @@ void __init paging_init(void)
> }
> }
>
> +#ifdef CONFIG_M54xx_DMA_ZONE
> + /* setup page tables for DMA area */
> + /* starting loc in page directory */
> + pg_dir = swapper_pg_dir + (CONFIG_M54xx_DMA_ZONE_BASE >> PGDIR_SHIFT);
> +
> + size = (CONFIG_M54xx_DMA_ZONE_SIZE >> PAGE_SHIFT) * sizeof(pte_t);
> + size = (size + PAGE_SIZE) & ~(PAGE_SIZE-1);
> +
> + next_pgtable = (unsigned long)alloc_bootmem_pages(size);
> +
> + address = CONFIG_M54xx_DMA_ZONE_BASE;
> + while (address < (CONFIG_M54xx_DMA_ZONE_BASE +
> + CONFIG_M54xx_DMA_ZONE_SIZE)) {
> + pg_table = (pte_t *)next_pgtable;
> + next_pgtable += PTRS_PER_PTE * sizeof(pte_t);
> + pgd_val(*pg_dir) = (unsigned long)pg_table;
> + pg_dir++;
> +
> + for (i = 0; i < PTRS_PER_PTE; ++i, ++pg_table) {
> + pte_t pte = pfn_pte(virt_to_pfn(address), PAGE_INIT);
> + if (address >= (CONFIG_M54xx_DMA_ZONE_BASE
> + + CONFIG_M54xx_DMA_ZONE_SIZE))
> + pte_val(pte) = 0;
> +
> + set_pte(pg_table, pte);
> + address += PAGE_SIZE;
> + }
> + }
> +#endif
> current->mm = NULL;
>
> for (zone = 0; zone < MAX_NR_ZONES; zone++)
> zones_size[zone] = 0x0;
> +
> +#ifdef CONFIG_M54xx_DMA_ZONE
> + zones_size[ZONE_DMA] = CONFIG_M54xx_DMA_ZONE_SIZE >> PAGE_SHIFT;
> + zones_size[ZONE_NORMAL] =
> + (((unsigned long)high_memory
> + - PAGE_OFFSET) >> PAGE_SHIFT)
> + - zones_size[ZONE_DMA];
> +#else
> zones_size[ZONE_DMA] = num_pages;
> +#endif
> free_area_init(zones_size);
> }
>
> diff --git a/arch/m68k/platform/coldfire/head.S b/arch/m68k/platform/coldfire/head.S
> index fa31be2..62b4f17 100644
> --- a/arch/m68k/platform/coldfire/head.S
> +++ b/arch/m68k/platform/coldfire/head.S
> @@ -265,6 +265,37 @@ _clear_bss:
> cmpl %a0,%a1 /* check if at end */
> bne _clear_bss
>
> +
> +#ifdef CONFIG_M54xx_DMA_ZONE
> + clrl %d0
> +__mmu_dma_map:
> + /* Set up search of TLB */
> + movel #CONFIG_M54xx_DMA_ZONE_BASE, %d1
> + addl %d0,%d1
> + addil #1,%d1
> + movel %d1, MMUAR
> + /* Search */
> + movel #(MMUOR_STLB+MMUOR_ADR), %d1
> + movel %d1, MMUOR
> + /* Set up tag value */
> + movel #CONFIG_M54xx_DMA_ZONE_BASE,%d1
> + addl %d0,%d1
> + addil #(MMUTR_SG+MMUTR_V),%d1
> + movel %d1, MMUTR
> + /* Set up data value */
> + movel #CONFIG_RAMBASE,%d1
> + addl %d0,%d1
> + addil #(MMUDR_SZ_1MB+MMUDR_CM_NCP+MMUDR_SP+MMUDR_R+MMUDR_W+MMUDR_LK),%d1
> + movel %d1, MMUDR
> + /* Save */
> + movel #(MMUOR_ACC+MMUOR_UAA), %d1
> + movel %d1, MMUOR
> +
> + addil #0x100000,%d0
> + cmpil #CONFIG_M54xx_DMA_ZONE_SIZE,%d0
> + bnes __mmu_dma_map
> +#endif
> +
> /*
> * Load the current task pointer and stack.
> */
> diff --git a/arch/m68k/platform/coldfire/m54xx.c b/arch/m68k/platform/coldfire/m54xx.c
> index b587bf3..c207822 100644
> --- a/arch/m68k/platform/coldfire/m54xx.c
> +++ b/arch/m68k/platform/coldfire/m54xx.c
> @@ -23,6 +23,9 @@
> #include <asm/m54xxgpt.h>
> #ifdef CONFIG_MMU
> #include <asm/mmu_context.h>
> +#ifdef CONFIG_M54xx_DMA_ZONE
> +#include <asm/dma.h>
> +#endif
> #endif
>
> /***************************************************************************/
> @@ -56,6 +59,17 @@ static void mcf54xx_reset(void)
>
> unsigned long num_pages;
>
> +#ifdef CONFIG_M54xx_DMA_ZONE
> +/* cf dma physical addresses */
> +unsigned long m54xx_dma_base;
> +EXPORT_SYMBOL(m54xx_dma_base);
> +unsigned long m54xx_dma_end;
> +EXPORT_SYMBOL(m54xx_dma_end);
> +unsigned long m54xx_dma_size;
> +EXPORT_SYMBOL(m54xx_dma_size);
> +#endif
> +
> +
> static void __init mcf54xx_bootmem_alloc(void)
> {
> unsigned long start_pfn;
> @@ -83,6 +97,13 @@ static void __init mcf54xx_bootmem_alloc(void)
> memstart += init_bootmem_node(NODE_DATA(0), start_pfn,
> min_low_pfn, max_low_pfn);
> free_bootmem_node(NODE_DATA(0), memstart, _ramend - memstart);
> +
> +#ifdef CONFIG_M54xx_DMA_ZONE
> + /* configure physical dma area */
> + m54xx_dma_base = __pa(PAGE_ALIGN(_ramstart));
> + m54xx_dma_size = CONFIG_M54xx_DMA_ZONE_SIZE;
> + m54xx_dma_end = CONFIG_RAMBASE + m54xx_dma_size - 1;
> +#endif /* CONFIG_M54xx_DMA_ZONE */
> }
>
> #endif /* CONFIG_MMU */
> --
> 1.7.9.5
>
>
>
>
--
------------------------------------------------------------------------
Greg Ungerer -- Principal Engineer EMAIL: gerg@snapgear.com
SnapGear Group, McAfee PHONE: +61 7 3435 2888
8 Gardner Close FAX: +61 7 3217 5323
Milton, QLD, 4064, Australia WEB: http://www.SnapGear.com
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE: [PATCH 1/4 V2] Add linux/io.h to make m54xx_wdt.c compile with MMU enabled.
2012-10-16 5:04 ` Greg Ungerer
@ 2012-10-16 10:47 ` Stany MARCEL
0 siblings, 0 replies; 21+ messages in thread
From: Stany MARCEL @ 2012-10-16 10:47 UTC (permalink / raw)
To: Greg Ungerer; +Cc: linux-m68k, gerg
Hi,
Ok I'll do a V3 soon.
Regards,
-----Original Message-----
From: Greg Ungerer [mailto:gerg@snapgear.com]
Sent: Tue 10/16/2012 7:04 AM
To: Stany MARCEL
Cc: linux-m68k@vger.kernel.org; gerg@uclinux.org
Subject: Re: [PATCH 1/4 V2] Add linux/io.h to make m54xx_wdt.c compile with MMU enabled.
Hi Stany,
On 16/10/12 00:08, Stany MARCEL wrote:
> Signed-off-by: Stany MARCEL <stany.marcel@novasys-ingenierie.com>
I am fine with it. Though I think you should also include the
actual compile error you get in the commit message.
Acked-by: Greg Ungerer <gerg@uclinux.org>
Being a watchdog driver fix though it needs to also be sent to
the appropriate list and maintainer. get_mainatiner lists:
Wim Van Sebroeck <wim@iguana.be> (maintainer:WATCHDOG DEVICE D...)
linux-watchdog@vger.kernel.org (open list:WATCHDOG DEVICE D...)
linux-kernel@vger.kernel.org (open list)
Regards
Greg
> ---
>
> Changes:
> - V2: reword commit message.
>
> drivers/watchdog/m54xx_wdt.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/watchdog/m54xx_wdt.c b/drivers/watchdog/m54xx_wdt.c
> index 173494a..7466b4b 100644
> --- a/drivers/watchdog/m54xx_wdt.c
> +++ b/drivers/watchdog/m54xx_wdt.c
> @@ -29,6 +29,7 @@
> #include <linux/bitops.h>
> #include <linux/ioport.h>
> #include <linux/uaccess.h>
> +#include <linux/io.h>
>
> #include <asm/coldfire.h>
> #include <asm/m54xxsim.h>
> --
> 1.7.9.5
>
>
>
>
--
------------------------------------------------------------------------
Greg Ungerer -- Principal Engineer EMAIL: gerg@snapgear.com
SnapGear Group, McAfee PHONE: +61 7 3435 2888
8 Gardner Close FAX: +61 7 3217 5323
Milton, QLD, 4064, Australia WEB: http://www.SnapGear.com
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/4 V2] Add for MCF54xx a virtual non cached zone usable for data exchange with DMA
2012-10-16 10:46 ` Stany MARCEL
@ 2012-10-16 11:23 ` Philippe De Muyter
2012-10-16 12:29 ` Greg Ungerer
1 sibling, 0 replies; 21+ messages in thread
From: Philippe De Muyter @ 2012-10-16 11:23 UTC (permalink / raw)
To: Stany MARCEL; +Cc: Greg Ungerer, linux-m68k, gerg
Hi Stany and Greg,
On Tue, Oct 16, 2012 at 12:46:02PM +0200, Stany MARCEL wrote:
>
> It might not be the usual approach in Linux, but after reading the MCF548x Reference Manual,
> I think that is the best approach for this family of MCU.
Maybe we should keep Stany's approach of reserving part of the memory
as uncached and use dma_alloc_coherent() or dma_pool_create().
Have a look at Documentation/DMA-API.txt
Best regards
Philippe
>
> Regards,
>
> Stany
>
>
> -----Original Message-----
> From: Greg Ungerer [mailto:gerg@snapgear.com]
> Sent: Tue 10/16/2012 7:15 AM
> To: Stany MARCEL
> Cc: linux-m68k@vger.kernel.org; gerg@uclinux.org
> Subject: Re: [PATCH 3/4 V2] Add for MCF54xx a virtual non cached zone usable for data exchange with DMA
>
> Hi Stany,
>
> On 15/10/12 23:22, Stany MARCEL wrote:
> > This permit to share data with DMA without caching issues. M54xx DMA bypass
> > cache so exchanged data must be flushed before DMA operation. But M54xx cache
> > opperation does not permit to easily flush concerned data. So this patch permit
> > to have a non cached zone used for GFP_DMA allocated data.
>
> Interesting, but I think this is the wrong approach.
>
> We don't want to bypass the cache. Admittedly the current cache support
> code we have for ColdFire is not great, it could be improved a lot. So
> lets do that, not work around it.
>
> Regards
> Greg
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 4/4 V2] Set ACR1 cache mode depending on kernel configuration.
2012-10-16 8:12 ` Philippe De Muyter
@ 2012-10-16 12:06 ` Greg Ungerer
0 siblings, 0 replies; 21+ messages in thread
From: Greg Ungerer @ 2012-10-16 12:06 UTC (permalink / raw)
To: Philippe De Muyter; +Cc: Stany MARCEL, linux-m68k, gerg
Hi Philippe,
On 10/16/2012 06:12 PM, Philippe De Muyter wrote:
> Hi Stany and Greg,
>
> On Tue, Oct 16, 2012 at 03:27:26PM +1000, Greg Ungerer wrote:
>> Hi Stany,
>>
>> On 15/10/12 23:22, Stany MARCEL wrote:
>>> For coldfire with MMU enabled, data cache did not follow the configuration
>>> but
>>> was configured in writethrough mode.
>>>
>>> Signed-off-by: Stany MARCEL <stany.marcel@novasys-ingenierie.com>
>>
>> Looks good, thanks. Applied without the white space changes.
>
> Wouldn't it be better to move the test on CONFIG_CACHE_COPYBACK outside
> of the test on CONFIG_MMU instead of duplicating it ?
Sure that would be cleaner. If someone updates it and send me a
new patch I will apply that.
Regards
Greg
>>> ---
>>>
>>> Changes:
>>> V2: This patch is now independant from the previous one
>>>
>>> arch/m68k/include/asm/m54xxacr.h | 10 +++++++---
>>> 1 file changed, 7 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/arch/m68k/include/asm/m54xxacr.h
>>> b/arch/m68k/include/asm/m54xxacr.h
>>> index 192bbfe..8f932be 100644
>>> --- a/arch/m68k/include/asm/m54xxacr.h
>>> +++ b/arch/m68k/include/asm/m54xxacr.h
>>> @@ -94,14 +94,18 @@
>>> * register region as non-cacheable. And then we map all our RAM as
>>> * cacheable and supervisor access only.
>>> */
>>> -#define ACR0_MODE (ACR_BA(CONFIG_MBAR)+ACR_ADMSK(0x1000000)+ \
>>> +#define ACR0_MODE (ACR_BA(CONFIG_MBAR)+ACR_ADMSK(0x1000000)+ \
>>> ACR_ENABLE+ACR_SUPER+ACR_CM_OFF_PRE+ACR_SP)
>>> +#if defined(CONFIG_CACHE_COPYBACK)
>>> #define ACR1_MODE (ACR_BA(CONFIG_RAMBASE)+ACR_ADMSK(CONFIG_RAMSIZE)+ \
>>> - ACR_ENABLE+ACR_SUPER+ACR_SP)
>>> + ACR_ENABLE+ACR_SUPER+ACR_SP+ACR_CM_CP)
>>> +#else
>>> +#define ACR1_MODE (ACR_BA(CONFIG_RAMBASE)+ACR_ADMSK(CONFIG_RAMSIZE)+ \
>>> + ACR_ENABLE+ACR_SUPER+ACR_SP+ACR_CM_WT)
>>> +#endif
>>> #define ACR2_MODE 0
>>> #define ACR3_MODE (ACR_BA(CONFIG_RAMBASE)+ACR_ADMSK(CONFIG_RAMSIZE)+ \
>>> ACR_ENABLE+ACR_SUPER+ACR_SP)
>>> -
>>> #else
>>>
>>> /*
>>> --
>>> 1.7.9.5
>
>
>
--
------------------------------------------------------------------------
Greg Ungerer -- Principal Engineer EMAIL: gerg@snapgear.com
SnapGear Group, McAfee PHONE: +61 7 3435 2888
8 Gardner Close, FAX: +61 7 3891 3630
Milton, QLD, 4064, Australia WEB: http://www.SnapGear.com
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/4 V2] Add for MCF54xx a virtual non cached zone usable for data exchange with DMA
2012-10-16 10:46 ` Stany MARCEL
2012-10-16 11:23 ` Philippe De Muyter
@ 2012-10-16 12:29 ` Greg Ungerer
2012-10-16 13:57 ` RE : " Stany MARCEL
1 sibling, 1 reply; 21+ messages in thread
From: Greg Ungerer @ 2012-10-16 12:29 UTC (permalink / raw)
To: Stany MARCEL; +Cc: linux-m68k, gerg
Hi Stany,
On 10/16/2012 08:46 PM, Stany MARCEL wrote:
> It might not be the usual approach in Linux, but after reading the MCF548x Reference Manual,
> I think that is the best approach for this family of MCU.
I have concerns on a number of fronts:
. partitioning memory in this way is always tricky to get the
right balance
. it uses precious TLB entries permanently
. accesses to the region will be uncached and slow
What performance impact will these have?
Does it perform any better, or is it actually worse?
We still need to fix the caching functions if we have problems
there, so this doesn't resolve that issue in any way for us.
Regards
Greg
> -----Original Message-----
> From: Greg Ungerer [mailto:gerg@snapgear.com]
> Sent: Tue 10/16/2012 7:15 AM
> To: Stany MARCEL
> Cc: linux-m68k@vger.kernel.org; gerg@uclinux.org
> Subject: Re: [PATCH 3/4 V2] Add for MCF54xx a virtual non cached zone usable for data exchange with DMA
>
> Hi Stany,
>
> On 15/10/12 23:22, Stany MARCEL wrote:
>> This permit to share data with DMA without caching issues. M54xx DMA bypass
>> cache so exchanged data must be flushed before DMA operation. But M54xx cache
>> opperation does not permit to easily flush concerned data. So this patch permit
>> to have a non cached zone used for GFP_DMA allocated data.
>
> Interesting, but I think this is the wrong approach.
>
> We don't want to bypass the cache. Admittedly the current cache support
> code we have for ColdFire is not great, it could be improved a lot. So
> lets do that, not work around it.
>
> Regards
> Greg
>
>
>
>> Signed-off-by: Stany MARCEL <stany.marcel@novasys-ingenierie.com>
>> ---
>>
>> Changes:
>> V2: This patch does not touch ACR anymore, ACR cache mode is only
>> modified by following patch that is now independant.
>>
>> arch/m68k/Kconfig.machine | 32 +++++++++++++++++
>> arch/m68k/include/asm/dma.h | 8 +++++
>> arch/m68k/include/asm/mcf_pgalloc.h | 6 ++--
>> arch/m68k/include/asm/page_mm.h | 68 ++++++++++++++++++++++++++++++++++-
>> arch/m68k/kernel/dma.c | 14 ++++++++
>> arch/m68k/mm/mcfmmu.c | 38 ++++++++++++++++++++
>> arch/m68k/platform/coldfire/head.S | 31 ++++++++++++++++
>> arch/m68k/platform/coldfire/m54xx.c | 21 +++++++++++
>> 8 files changed, 214 insertions(+), 4 deletions(-)
>>
>> diff --git a/arch/m68k/Kconfig.machine b/arch/m68k/Kconfig.machine
>> index 7cdf6b0..f9a4d9d 100644
>> --- a/arch/m68k/Kconfig.machine
>> +++ b/arch/m68k/Kconfig.machine
>> @@ -512,6 +512,38 @@ config KERNELBASE
>> a system with the RAM based at address 0, and leaving enough room
>> for the theoretical maximum number of 256 vectors.
>>
>> +config M54xx_DMA_ZONE
>> + bool "M54xx non cached virtual zone for DMA"
>> + depends on MMU
>> + depends on M54xx
>> + select SINGLE_MEMORY_CHUNK
>> + help
>> + Activate a virtual zone with tlb data entries initialized, in non
>> + cached precise mode. This permit to share data with DMA without caching
>> + issues. M54xx DMA bypass cache so exchanged data must be flushed
>> + before DMA operation. But M54xx cache opperation does not permit to
>> + easily flush concerned data. So this patch permit to have a non cached
>> + zone used for GFP_DMA allocated data.
>> +
>> +config M54xx_DMA_ZONE_BASE
>> + hex "Address of the base of a vitual non cached zone usable for DMA"
>> + depends on M54xx_DMA_ZONE
>> + default 0xC0000000
>> + help
>> + Define the address of a virtual zone, with tlb data entries
>> + initialized, in non cached precise mode.
>> + Addresse must be 1MB aligned, not already mapped and different than
>> + KMAP and VM memory map
>> +
>> +config M54xx_DMA_ZONE_SIZE
>> + hex "Size of the vitual non cached zone usable for DMA"
>> + depends on M54xx_DMA_ZONE
>> + default 0x800000
>> + help
>> + Define the size of a virtual zone, with tlb data entries
>> + initialized, in non cached precise mode.
>> + Size must be 1MB divisable.
>> +
>> comment "ROM configuration"
>>
>> config ROM
>> diff --git a/arch/m68k/include/asm/dma.h b/arch/m68k/include/asm/dma.h
>> index 0ff3fc6..04e5d2c 100644
>> --- a/arch/m68k/include/asm/dma.h
>> +++ b/arch/m68k/include/asm/dma.h
>> @@ -479,10 +479,18 @@ static __inline__ int get_dma_residue(unsigned int dmanr)
>> #endif /* !defined(CONFIG_M5272) */
>> #endif /* CONFIG_COLDFIRE */
>>
>> +#if defined(CONFIG_M54xx_DMA_ZONE)
>> +
>> +#define MAX_DMA_ADDRESS (CONFIG_M54xx_DMA_ZONE_BASE + \
>> + CONFIG_M54xx_DMA_ZONE_SIZE - 1)
>> +
>> +#else
>> /* it's useless on the m68k, but unfortunately needed by the new
>> bootmem allocator (but this should do it for this) */
>> #define MAX_DMA_ADDRESS PAGE_OFFSET
>>
>> +#endif
>> +
>> #define MAX_DMA_CHANNELS 8
>>
>> extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */
>> diff --git a/arch/m68k/include/asm/mcf_pgalloc.h b/arch/m68k/include/asm/mcf_pgalloc.h
>> index 313f3dd..7fbb5ce 100644
>> --- a/arch/m68k/include/asm/mcf_pgalloc.h
>> +++ b/arch/m68k/include/asm/mcf_pgalloc.h
>> @@ -14,7 +14,7 @@ extern const char bad_pmd_string[];
>> extern inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
>> unsigned long address)
>> {
>> - unsigned long page = __get_free_page(GFP_DMA|__GFP_REPEAT);
>> + unsigned long page = __get_free_page(GFP_KERNEL|__GFP_REPEAT);
>>
>> if (!page)
>> return NULL;
>> @@ -51,7 +51,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page,
>> static inline struct page *pte_alloc_one(struct mm_struct *mm,
>> unsigned long address)
>> {
>> - struct page *page = alloc_pages(GFP_DMA|__GFP_REPEAT, 0);
>> + struct page *page = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
>> pte_t *pte;
>>
>> if (!page)
>> @@ -89,7 +89,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm)
>> {
>> pgd_t *new_pgd;
>>
>> - new_pgd = (pgd_t *)__get_free_page(GFP_DMA | __GFP_NOWARN);
>> + new_pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_NOWARN);
>> if (!new_pgd)
>> return NULL;
>> memcpy(new_pgd, swapper_pg_dir, PAGE_SIZE);
>> diff --git a/arch/m68k/include/asm/page_mm.h b/arch/m68k/include/asm/page_mm.h
>> index 89f2014..7985ffd 100644
>> --- a/arch/m68k/include/asm/page_mm.h
>> +++ b/arch/m68k/include/asm/page_mm.h
>> @@ -70,6 +70,8 @@ extern unsigned long m68k_memoffset;
>>
>> #define WANT_PAGE_VIRTUAL
>>
>> +#ifndef CONFIG_M54xx_DMA_ZONE
>> +
>> static inline unsigned long ___pa(void *vaddr)
>> {
>> unsigned long paddr;
>> @@ -91,6 +93,58 @@ static inline void *__va(unsigned long paddr)
>> : "0" (paddr), "i" (m68k_fixup_memoffset));
>> return vaddr;
>> }
>> +#else /* !CONFIG_M54xx_DMA_ZONE */
>> +
>> +extern unsigned long m54xx_dma_base;
>> +extern unsigned long m54xx_dma_end;
>> +
>> +/*
>> + * Convert a virt to a phys
>> + */
>> +static inline unsigned long ___pa(void *vaddr)
>> +{
>> +#if CONFIG_RAMBASE != PAGE_OFFSET
>> + return ((unsigned long)vaddr & 0x0fffffff) + CONFIG_RAMBASE;
>> +#else
>> + if ((unsigned long)vaddr >= CONFIG_M54xx_DMA_ZONE_BASE &&
>> + (unsigned long)vaddr < (CONFIG_M54xx_DMA_ZONE_BASE +
>> + CONFIG_M54xx_DMA_ZONE_SIZE)) {
>> + /* address is in carved out DMA range */
>> + return ((unsigned long)vaddr - CONFIG_M54xx_DMA_ZONE_BASE)
>> + + CONFIG_RAMBASE;
>> + } else if ((unsigned long)vaddr >= PAGE_OFFSET &&
>> + (unsigned long)vaddr < (PAGE_OFFSET + CONFIG_RAMSIZE)) {
>> + /* normal mapping */
>> + return ((unsigned long)vaddr - PAGE_OFFSET) + CONFIG_RAMBASE;
>> + }
>> +
>> + return (unsigned long)vaddr;
>> +#endif
>> +}
>> +#define __pa(vaddr) ___pa((void *)(vaddr))
>> +
>> +/*
>> + * Convert a phys to a virt
>> + */
>> +static inline void *__va(unsigned long paddr)
>> +{
>> +#if CONFIG_RAMBASE != PAGE_OFFSET
>> + return (void *)((paddr & 0x0fffffff) + PAGE_OFFSET);
>> +#else
>> + if (paddr >= m54xx_dma_base && paddr <= m54xx_dma_end) {
>> + /* mapped address for DMA */
>> + return (void *)((paddr - CONFIG_RAMBASE)
>> + + CONFIG_M54xx_DMA_ZONE_BASE);
>> + } else if (paddr >= m54xx_dma_end &&
>> + paddr < (CONFIG_RAMBASE + CONFIG_RAMSIZE)) {
>> + /* normal mapping */
>> + return (void *)((paddr - CONFIG_RAMBASE) + PAGE_OFFSET);
>> + }
>> + return (void *)paddr;
>> +#endif
>> +}
>> +
>> +#endif
>>
>> #else /* !CONFIG_SUN3 */
>> /* This #define is a horrible hack to suppress lots of warnings. --m */
>> @@ -168,7 +222,19 @@ static inline __attribute_const__ int __virt_to_node_shift(void)
>> ((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn; \
>> })
>>
>> -#define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
>> +#ifndef CONFIG_M54xx_DMA_ZONE
>> +#define virt_addr_valid(kaddr) \
>> + ((void *)(kaddr) >= (void *)PAGE_OFFSET && \
>> + (void *)(kaddr) < high_memory)
>> +#else
>> +#define virt_addr_valid(kaddr) \
>> + (((void *)(kaddr) >= (void *)PAGE_OFFSET && \
>> + (void *)(kaddr) < high_memory) || \
>> + ((void *)(kaddr) >= (void *)CONFIG_M54xx_DMA_ZONE_BASE && \
>> + (void *)(kaddr) < (void *)(CONFIG_M54xx_DMA_ZONE_BASE \
>> + + CONFIG_M54xx_DMA_ZONE_SIZE)))
>> +#endif
>> +
>> #define pfn_valid(pfn) virt_addr_valid(pfn_to_virt(pfn))
>>
>> #endif /* __ASSEMBLY__ */
>> diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
>> index e546a55..57873d1 100644
>> --- a/arch/m68k/kernel/dma.c
>> +++ b/arch/m68k/kernel/dma.c
>> @@ -76,6 +76,15 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
>> dma_addr_t *dma_handle, gfp_t gfp)
>> {
>> void *ret;
>> +#ifdef CONFIG_M54xx_DMA_ZONE
>> + /*
>> + * On the M54xx platform with CONFIG_M54xx_DMA_ZONE the memory allocated
>> + * with GFP_DMA is guaranteed to be DMA'able, and cache coherent.
>> + */
>> + size = PAGE_ALIGN(size);
>> + ret = kmalloc(size, GFP_DMA);
>> + *dma_handle = virt_to_phys(ret);
>> +#else
>> /* ignore region specifiers */
>> gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
>>
>> @@ -87,13 +96,18 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
>> memset(ret, 0, size);
>> *dma_handle = virt_to_phys(ret);
>> }
>> +#endif
>> return ret;
>> }
>>
>> void dma_free_coherent(struct device *dev, size_t size,
>> void *vaddr, dma_addr_t dma_handle)
>> {
>> +#ifdef CONFIG_M54xx_DMA_ZONE
>> + kfree((void *)dma_handle);
>> +#else
>> free_pages((unsigned long)vaddr, get_order(size));
>> +#endif
>> }
>>
>> #endif /* CONFIG_MMU && !CONFIG_COLDFIRE */
>> diff --git a/arch/m68k/mm/mcfmmu.c b/arch/m68k/mm/mcfmmu.c
>> index 875b800..932415b 100644
>> --- a/arch/m68k/mm/mcfmmu.c
>> +++ b/arch/m68k/mm/mcfmmu.c
>> @@ -77,11 +77,49 @@ void __init paging_init(void)
>> }
>> }
>>
>> +#ifdef CONFIG_M54xx_DMA_ZONE
>> + /* setup page tables for DMA area */
>> + /* starting loc in page directory */
>> + pg_dir = swapper_pg_dir + (CONFIG_M54xx_DMA_ZONE_BASE >> PGDIR_SHIFT);
>> +
>> + size = (CONFIG_M54xx_DMA_ZONE_SIZE >> PAGE_SHIFT) * sizeof(pte_t);
>> + size = (size + PAGE_SIZE) & ~(PAGE_SIZE-1);
>> +
>> + next_pgtable = (unsigned long)alloc_bootmem_pages(size);
>> +
>> + address = CONFIG_M54xx_DMA_ZONE_BASE;
>> + while (address < (CONFIG_M54xx_DMA_ZONE_BASE +
>> + CONFIG_M54xx_DMA_ZONE_SIZE)) {
>> + pg_table = (pte_t *)next_pgtable;
>> + next_pgtable += PTRS_PER_PTE * sizeof(pte_t);
>> + pgd_val(*pg_dir) = (unsigned long)pg_table;
>> + pg_dir++;
>> +
>> + for (i = 0; i < PTRS_PER_PTE; ++i, ++pg_table) {
>> + pte_t pte = pfn_pte(virt_to_pfn(address), PAGE_INIT);
>> + if (address >= (CONFIG_M54xx_DMA_ZONE_BASE
>> + + CONFIG_M54xx_DMA_ZONE_SIZE))
>> + pte_val(pte) = 0;
>> +
>> + set_pte(pg_table, pte);
>> + address += PAGE_SIZE;
>> + }
>> + }
>> +#endif
>> current->mm = NULL;
>>
>> for (zone = 0; zone < MAX_NR_ZONES; zone++)
>> zones_size[zone] = 0x0;
>> +
>> +#ifdef CONFIG_M54xx_DMA_ZONE
>> + zones_size[ZONE_DMA] = CONFIG_M54xx_DMA_ZONE_SIZE >> PAGE_SHIFT;
>> + zones_size[ZONE_NORMAL] =
>> + (((unsigned long)high_memory
>> + - PAGE_OFFSET) >> PAGE_SHIFT)
>> + - zones_size[ZONE_DMA];
>> +#else
>> zones_size[ZONE_DMA] = num_pages;
>> +#endif
>> free_area_init(zones_size);
>> }
>>
>> diff --git a/arch/m68k/platform/coldfire/head.S b/arch/m68k/platform/coldfire/head.S
>> index fa31be2..62b4f17 100644
>> --- a/arch/m68k/platform/coldfire/head.S
>> +++ b/arch/m68k/platform/coldfire/head.S
>> @@ -265,6 +265,37 @@ _clear_bss:
>> cmpl %a0,%a1 /* check if at end */
>> bne _clear_bss
>>
>> +
>> +#ifdef CONFIG_M54xx_DMA_ZONE
>> + clrl %d0
>> +__mmu_dma_map:
>> + /* Set up search of TLB */
>> + movel #CONFIG_M54xx_DMA_ZONE_BASE, %d1
>> + addl %d0,%d1
>> + addil #1,%d1
>> + movel %d1, MMUAR
>> + /* Search */
>> + movel #(MMUOR_STLB+MMUOR_ADR), %d1
>> + movel %d1, MMUOR
>> + /* Set up tag value */
>> + movel #CONFIG_M54xx_DMA_ZONE_BASE,%d1
>> + addl %d0,%d1
>> + addil #(MMUTR_SG+MMUTR_V),%d1
>> + movel %d1, MMUTR
>> + /* Set up data value */
>> + movel #CONFIG_RAMBASE,%d1
>> + addl %d0,%d1
>> + addil #(MMUDR_SZ_1MB+MMUDR_CM_NCP+MMUDR_SP+MMUDR_R+MMUDR_W+MMUDR_LK),%d1
>> + movel %d1, MMUDR
>> + /* Save */
>> + movel #(MMUOR_ACC+MMUOR_UAA), %d1
>> + movel %d1, MMUOR
>> +
>> + addil #0x100000,%d0
>> + cmpil #CONFIG_M54xx_DMA_ZONE_SIZE,%d0
>> + bnes __mmu_dma_map
>> +#endif
>> +
>> /*
>> * Load the current task pointer and stack.
>> */
>> diff --git a/arch/m68k/platform/coldfire/m54xx.c b/arch/m68k/platform/coldfire/m54xx.c
>> index b587bf3..c207822 100644
>> --- a/arch/m68k/platform/coldfire/m54xx.c
>> +++ b/arch/m68k/platform/coldfire/m54xx.c
>> @@ -23,6 +23,9 @@
>> #include <asm/m54xxgpt.h>
>> #ifdef CONFIG_MMU
>> #include <asm/mmu_context.h>
>> +#ifdef CONFIG_M54xx_DMA_ZONE
>> +#include <asm/dma.h>
>> +#endif
>> #endif
>>
>> /***************************************************************************/
>> @@ -56,6 +59,17 @@ static void mcf54xx_reset(void)
>>
>> unsigned long num_pages;
>>
>> +#ifdef CONFIG_M54xx_DMA_ZONE
>> +/* cf dma physical addresses */
>> +unsigned long m54xx_dma_base;
>> +EXPORT_SYMBOL(m54xx_dma_base);
>> +unsigned long m54xx_dma_end;
>> +EXPORT_SYMBOL(m54xx_dma_end);
>> +unsigned long m54xx_dma_size;
>> +EXPORT_SYMBOL(m54xx_dma_size);
>> +#endif
>> +
>> +
>> static void __init mcf54xx_bootmem_alloc(void)
>> {
>> unsigned long start_pfn;
>> @@ -83,6 +97,13 @@ static void __init mcf54xx_bootmem_alloc(void)
>> memstart += init_bootmem_node(NODE_DATA(0), start_pfn,
>> min_low_pfn, max_low_pfn);
>> free_bootmem_node(NODE_DATA(0), memstart, _ramend - memstart);
>> +
>> +#ifdef CONFIG_M54xx_DMA_ZONE
>> + /* configure physical dma area */
>> + m54xx_dma_base = __pa(PAGE_ALIGN(_ramstart));
>> + m54xx_dma_size = CONFIG_M54xx_DMA_ZONE_SIZE;
>> + m54xx_dma_end = CONFIG_RAMBASE + m54xx_dma_size - 1;
>> +#endif /* CONFIG_M54xx_DMA_ZONE */
>> }
>>
>> #endif /* CONFIG_MMU */
>> --
>> 1.7.9.5
>>
>>
>>
>>
>
>
--
------------------------------------------------------------------------
Greg Ungerer -- Principal Engineer EMAIL: gerg@snapgear.com
SnapGear Group, McAfee PHONE: +61 7 3435 2888
8 Gardner Close, FAX: +61 7 3891 3630
Milton, QLD, 4064, Australia WEB: http://www.SnapGear.com
^ permalink raw reply [flat|nested] 21+ messages in thread
* RE : [PATCH 3/4 V2] Add for MCF54xx a virtual non cached zone usable for data exchange with DMA
2012-10-16 12:29 ` Greg Ungerer
@ 2012-10-16 13:57 ` Stany MARCEL
0 siblings, 0 replies; 21+ messages in thread
From: Stany MARCEL @ 2012-10-16 13:57 UTC (permalink / raw)
To: Greg Ungerer; +Cc: linux-m68k, gerg
Hi Greg,
For Informations, here are some measurements I can remember of
different solutions I have tested, measurements where done with iperf
in TCP and UDP :
- Copyback cache without flush: ~40Mbits/sec in TCP but UDP tests
shows a lot of lost frames.
- Copyback cache with full data flush : ~9Mbits/sec in TCP, don't
remember in UDP.
- DMA_ZONE : ~32Mbits/sec, UDP ok.
These results are very approximative, if I can I'll try to give you
more precise tests results.
For the partitioning and used TLB entries, with default settings I map
8MiB with 8TLB entry (on 32).
I choose this path as it is recommended by the documentation and I
also saw that it was the solution used by Freescale, on their old
Linux patch.
I agree that cache managing functions should also be improved. But
with available cache management possibility on mcf54xx mcu, I don't
see how to perform effectively the operations needed to exchange data
with built-in DMA.
So for my project I will live with this solution for the moment.
Regards,
--
Stany
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2012-10-16 13:52 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-15 12:54 [PATCH 1/4] Add linux/io.h to make it compile Stany MARCEL
2012-10-15 12:54 ` [PATCH 2/4] Permit to read/write to shared page Stany MARCEL
2012-10-15 12:54 ` [PATCH 3/4] Add for MCF54xx a virtual non cached zone usable for data exchange with DMA Stany MARCEL
2012-10-15 13:22 ` [PATCH 3/4 V2] " Stany MARCEL
2012-10-16 5:15 ` Greg Ungerer
2012-10-16 10:46 ` Stany MARCEL
2012-10-16 11:23 ` Philippe De Muyter
2012-10-16 12:29 ` Greg Ungerer
2012-10-16 13:57 ` RE : " Stany MARCEL
2012-10-15 12:54 ` [PATCH 4/4] Set ACR1 cache mode depending on kernel configuration Stany MARCEL
2012-10-15 13:22 ` [PATCH 4/4 V2] " Stany MARCEL
2012-10-16 5:27 ` Greg Ungerer
2012-10-16 8:12 ` Philippe De Muyter
2012-10-16 12:06 ` Greg Ungerer
2012-10-15 13:58 ` [PATCH 1/4] Add linux/io.h to make it compile Philippe De Muyter
2012-10-15 14:06 ` Stany MARCEL
2012-10-15 14:39 ` Philippe De Muyter
2012-10-16 4:58 ` Greg Ungerer
2012-10-15 14:08 ` [PATCH 1/4 V2] Add linux/io.h to make m54xx_wdt.c compile with MMU enabled Stany MARCEL
2012-10-16 5:04 ` Greg Ungerer
2012-10-16 10:47 ` Stany MARCEL
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).