Browse Source

[ARM] Feroceon: L1 cache range operation support

This patch adds support for the L1 D cache range operations that
are supported by the Marvell Discovery Duo and Marvell Kirkwood
ARM SoCs.

Signed-off-by: Stanislav Samsonov <samsonov@marvell.com>
Acked-by: Saeed Bishara <saeed@marvell.com>
Reviewed-by: Nicolas Pitre <nico@marvell.com>
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Stanislav Samsonov 17 years ago
parent
commit
836a8051d5
2 changed files with 69 additions and 6 deletions
  1. 68 1
      arch/arm/mm/proc-feroceon.S
  2. 1 5
      include/asm-arm/cacheflush.h

+ 68 - 1
arch/arm/mm/proc-feroceon.S

@@ -237,6 +237,20 @@ ENTRY(feroceon_flush_kern_dcache_page)
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mov	pc, lr
 	mov	pc, lr
 
 
+	.align	5
+ENTRY(feroceon_range_flush_kern_dcache_page)
+	mrs	r2, cpsr
+	add	r1, r0, #PAGE_SZ - CACHE_DLINESIZE	@ top addr is inclusive
+	orr	r3, r2, #PSR_I_BIT
+	msr	cpsr_c, r3			@ disable interrupts
+	mcr	p15, 5, r0, c15, c15, 0		@ D clean/inv range start
+	mcr	p15, 5, r1, c15, c15, 1		@ D clean/inv range top
+	msr	cpsr_c, r2			@ restore interrupts
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c5, 0		@ invalidate I cache
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
 /*
 /*
  *	dma_inv_range(start, end)
  *	dma_inv_range(start, end)
  *
  *
@@ -253,10 +267,10 @@ ENTRY(feroceon_flush_kern_dcache_page)
 	.align	5
 	.align	5
 ENTRY(feroceon_dma_inv_range)
 ENTRY(feroceon_dma_inv_range)
 	tst	r0, #CACHE_DLINESIZE - 1
 	tst	r0, #CACHE_DLINESIZE - 1
+	bic	r0, r0, #CACHE_DLINESIZE - 1
 	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
 	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
 	tst	r1, #CACHE_DLINESIZE - 1
 	tst	r1, #CACHE_DLINESIZE - 1
 	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
 	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
-	bic	r0, r0, #CACHE_DLINESIZE - 1
 1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 1:	mcr	p15, 0, r0, c7, c6, 1		@ invalidate D entry
 	add	r0, r0, #CACHE_DLINESIZE
 	add	r0, r0, #CACHE_DLINESIZE
 	cmp	r0, r1
 	cmp	r0, r1
@@ -264,6 +278,22 @@ ENTRY(feroceon_dma_inv_range)
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mov	pc, lr
 	mov	pc, lr
 
 
+	.align	5
+ENTRY(feroceon_range_dma_inv_range)
+	mrs	r2, cpsr
+	tst	r0, #CACHE_DLINESIZE - 1
+	mcrne	p15, 0, r0, c7, c10, 1		@ clean D entry
+	tst	r1, #CACHE_DLINESIZE - 1
+	mcrne	p15, 0, r1, c7, c10, 1		@ clean D entry
+	cmp	r1, r0
+	subne	r1, r1, #1			@ top address is inclusive
+	orr	r3, r2, #PSR_I_BIT
+	msr	cpsr_c, r3			@ disable interrupts
+	mcr	p15, 5, r0, c15, c14, 0		@ D inv range start
+	mcr	p15, 5, r1, c15, c14, 1		@ D inv range top
+	msr	cpsr_c, r2			@ restore interrupts
+	mov	pc, lr
+
 /*
 /*
  *	dma_clean_range(start, end)
  *	dma_clean_range(start, end)
  *
  *
@@ -284,6 +314,19 @@ ENTRY(feroceon_dma_clean_range)
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mov	pc, lr
 	mov	pc, lr
 
 
+	.align	5
+ENTRY(feroceon_range_dma_clean_range)
+	mrs	r2, cpsr
+	cmp	r1, r0
+	subne	r1, r1, #1			@ top address is inclusive
+	orr	r3, r2, #PSR_I_BIT
+	msr	cpsr_c, r3			@ disable interrupts
+	mcr	p15, 5, r0, c15, c13, 0		@ D clean range start
+	mcr	p15, 5, r1, c15, c13, 1		@ D clean range top
+	msr	cpsr_c, r2			@ restore interrupts
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
 /*
 /*
  *	dma_flush_range(start, end)
  *	dma_flush_range(start, end)
  *
  *
@@ -302,6 +345,19 @@ ENTRY(feroceon_dma_flush_range)
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
 	mov	pc, lr
 	mov	pc, lr
 
 
+	.align	5
+ENTRY(feroceon_range_dma_flush_range)
+	mrs	r2, cpsr
+	cmp	r1, r0
+	subne	r1, r1, #1			@ top address is inclusive
+	orr	r3, r2, #PSR_I_BIT
+	msr	cpsr_c, r3			@ disable interrupts
+	mcr	p15, 5, r0, c15, c15, 0		@ D clean/inv range start
+	mcr	p15, 5, r1, c15, c15, 1		@ D clean/inv range top
+	msr	cpsr_c, r2			@ restore interrupts
+	mcr	p15, 0, r0, c7, c10, 4		@ drain WB
+	mov	pc, lr
+
 ENTRY(feroceon_cache_fns)
 ENTRY(feroceon_cache_fns)
 	.long	feroceon_flush_kern_cache_all
 	.long	feroceon_flush_kern_cache_all
 	.long	feroceon_flush_user_cache_all
 	.long	feroceon_flush_user_cache_all
@@ -313,6 +369,17 @@ ENTRY(feroceon_cache_fns)
 	.long	feroceon_dma_clean_range
 	.long	feroceon_dma_clean_range
 	.long	feroceon_dma_flush_range
 	.long	feroceon_dma_flush_range
 
 
+ENTRY(feroceon_range_cache_fns)
+	.long	feroceon_flush_kern_cache_all
+	.long	feroceon_flush_user_cache_all
+	.long	feroceon_flush_user_cache_range
+	.long	feroceon_coherent_kern_range
+	.long	feroceon_coherent_user_range
+	.long	feroceon_range_flush_kern_dcache_page
+	.long	feroceon_range_dma_inv_range
+	.long	feroceon_range_dma_clean_range
+	.long	feroceon_range_dma_flush_range
+
 	.align	5
 	.align	5
 ENTRY(cpu_feroceon_dcache_clean_area)
 ENTRY(cpu_feroceon_dcache_clean_area)
 1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry
 1:	mcr	p15, 0, r0, c7, c10, 1		@ clean D entry

+ 1 - 5
include/asm-arm/cacheflush.h

@@ -95,11 +95,7 @@
 #endif
 #endif
 
 
 #if defined(CONFIG_CPU_FEROCEON)
 #if defined(CONFIG_CPU_FEROCEON)
-# ifdef _CACHE
-#  define MULTI_CACHE 1
-# else
-#  define _CACHE feroceon
-# endif
+# define MULTI_CACHE 1
 #endif
 #endif
 
 
 #if defined(CONFIG_CPU_V6)
 #if defined(CONFIG_CPU_V6)