aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaulius Zaleckas <paulius.zaleckas@teltonika.lt>2009-03-25 07:10:01 -0400
committerPaulius Zaleckas <paulius.zaleckas@teltonika.lt>2009-03-25 07:10:01 -0400
commit28853ac8fe5221de74a14f1182d7b2b383dfd85c (patch)
treedcfd9b20028e5a3a9504e26d2c9060f4746fc83a
parentbba7d0b9ba0f04d25145de8170a17a3a07bbfdde (diff)
ARM: Add support for FA526 v2
Adds support for Faraday FA526 core. This core is used at least by: Cortina Systems Gemini and Centroid family Cavium Networks ECONA family Grain Media GM8120 Pixelplus ImageARM Prolific PL-1029 Faraday IP evaluation boards v2: - move TLB_BTB to separate patch - update copyrights Signed-off-by: Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/boot/compressed/head.S26
-rw-r--r--arch/arm/include/asm/cacheflush.h8
-rw-r--r--arch/arm/include/asm/page.h8
-rw-r--r--arch/arm/include/asm/proc-fns.h8
-rw-r--r--arch/arm/include/asm/system.h6
-rw-r--r--arch/arm/include/asm/tlbflush.h19
-rw-r--r--arch/arm/mm/Kconfig35
-rw-r--r--arch/arm/mm/Makefile4
-rw-r--r--arch/arm/mm/cache-fa.S220
-rw-r--r--arch/arm/mm/copypage-fa.c86
-rw-r--r--arch/arm/mm/proc-fa526.S248
-rw-r--r--arch/arm/mm/tlb-fa.S75
13 files changed, 742 insertions, 2 deletions
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 24e0f0187697..d29f9260fb1c 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -72,6 +72,7 @@ tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi
72tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi 72tune-$(CONFIG_CPU_ARM922T) :=-mtune=arm9tdmi
73tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi 73tune-$(CONFIG_CPU_ARM925T) :=-mtune=arm9tdmi
74tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi 74tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi
75tune-$(CONFIG_CPU_FA526) :=-mtune=arm9tdmi
75tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110 76tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110
76tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100 77tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100
77tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale 78tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 77d614232d81..def02483286a 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -459,6 +459,20 @@ __armv7_mmu_cache_on:
459 mcr p15, 0, r0, c7, c5, 4 @ ISB 459 mcr p15, 0, r0, c7, c5, 4 @ ISB
460 mov pc, r12 460 mov pc, r12
461 461
462__fa526_cache_on:
463 mov r12, lr
464 bl __setup_mmu
465 mov r0, #0
466 mcr p15, 0, r0, c7, c7, 0 @ Invalidate whole cache
467 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
468 mcr p15, 0, r0, c8, c7, 0 @ flush UTLB
469 mrc p15, 0, r0, c1, c0, 0 @ read control reg
470 orr r0, r0, #0x1000 @ I-cache enable
471 bl __common_mmu_cache_on
472 mov r0, #0
473 mcr p15, 0, r0, c8, c7, 0 @ flush UTLB
474 mov pc, r12
475
462__arm6_mmu_cache_on: 476__arm6_mmu_cache_on:
463 mov r12, lr 477 mov r12, lr
464 bl __setup_mmu 478 bl __setup_mmu
@@ -636,6 +650,12 @@ proc_types:
636 b __armv4_mmu_cache_off 650 b __armv4_mmu_cache_off
637 b __armv5tej_mmu_cache_flush 651 b __armv5tej_mmu_cache_flush
638 652
653 .word 0x66015261 @ FA526
654 .word 0xff01fff1
655 b __fa526_cache_on
656 b __armv4_mmu_cache_off
657 b __fa526_cache_flush
658
639 @ These match on the architecture ID 659 @ These match on the architecture ID
640 660
641 .word 0x00020000 @ ARMv4T 661 .word 0x00020000 @ ARMv4T
@@ -775,6 +795,12 @@ __armv4_mpu_cache_flush:
775 mcr p15, 0, ip, c7, c10, 4 @ drain WB 795 mcr p15, 0, ip, c7, c10, 4 @ drain WB
776 mov pc, lr 796 mov pc, lr
777 797
798__fa526_cache_flush:
799 mov r1, #0
800 mcr p15, 0, r1, c7, c14, 0 @ clean and invalidate D cache
801 mcr p15, 0, r1, c7, c5, 0 @ flush I cache
802 mcr p15, 0, r1, c7, c10, 4 @ drain WB
803 mov pc, lr
778 804
779__armv6_mmu_cache_flush: 805__armv6_mmu_cache_flush:
780 mov r1, #0 806 mov r1, #0
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index 6cbd8fdc9f1f..a6b8b90ed57f 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -46,6 +46,14 @@
46# define MULTI_CACHE 1 46# define MULTI_CACHE 1
47#endif 47#endif
48 48
49#if defined(CONFIG_CPU_FA526)
50# ifdef _CACHE
51# define MULTI_CACHE 1
52# else
53# define _CACHE fa
54# endif
55#endif
56
49#if defined(CONFIG_CPU_ARM926T) 57#if defined(CONFIG_CPU_ARM926T)
50# ifdef _CACHE 58# ifdef _CACHE
51# define MULTI_CACHE 1 59# define MULTI_CACHE 1
diff --git a/arch/arm/include/asm/page.h b/arch/arm/include/asm/page.h
index f341c9dbd662..e6eb8a67b807 100644
--- a/arch/arm/include/asm/page.h
+++ b/arch/arm/include/asm/page.h
@@ -76,6 +76,14 @@
76# endif 76# endif
77#endif 77#endif
78 78
79#ifdef CONFIG_CPU_COPY_FA
80# ifdef _USER
81# define MULTI_USER 1
82# else
83# define _USER fa
84# endif
85#endif
86
79#ifdef CONFIG_CPU_SA1100 87#ifdef CONFIG_CPU_SA1100
80# ifdef _USER 88# ifdef _USER
81# define MULTI_USER 1 89# define MULTI_USER 1
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index db80203b68e0..00949281d3ee 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -89,6 +89,14 @@
89# define CPU_NAME cpu_arm922 89# define CPU_NAME cpu_arm922
90# endif 90# endif
91# endif 91# endif
92# ifdef CONFIG_CPU_FA526
93# ifdef CPU_NAME
94# undef MULTI_CPU
95# define MULTI_CPU
96# else
97# define CPU_NAME cpu_fa526
98# endif
99# endif
92# ifdef CONFIG_CPU_ARM925T 100# ifdef CONFIG_CPU_ARM925T
93# ifdef CPU_NAME 101# ifdef CPU_NAME
94# undef MULTI_CPU 102# undef MULTI_CPU
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 811be55f338e..d6a4dad99c9b 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -125,6 +125,12 @@ extern unsigned int user_debug;
125 : : "r" (0) : "memory") 125 : : "r" (0) : "memory")
126#define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ 126#define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
127 : : "r" (0) : "memory") 127 : : "r" (0) : "memory")
128#elif defined(CONFIG_CPU_FA526)
129#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
130 : : "r" (0) : "memory")
131#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
132 : : "r" (0) : "memory")
133#define dmb() __asm__ __volatile__ ("" : : : "memory")
128#else 134#else
129#define isb() __asm__ __volatile__ ("" : : : "memory") 135#define isb() __asm__ __volatile__ ("" : : : "memory")
130#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \ 136#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h
index ffedd2494eab..a62218013c78 100644
--- a/arch/arm/include/asm/tlbflush.h
+++ b/arch/arm/include/asm/tlbflush.h
@@ -54,6 +54,7 @@
54 * v4wb - ARMv4 with write buffer without I TLB flush entry instruction 54 * v4wb - ARMv4 with write buffer without I TLB flush entry instruction
55 * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction 55 * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction
56 * fr - Feroceon (v4wbi with non-outer-cacheable page table walks) 56 * fr - Feroceon (v4wbi with non-outer-cacheable page table walks)
57 * fa - Faraday (v4 with write buffer with UTLB and branch target buffer (BTB))
57 * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction 58 * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction
58 * v7wbi - identical to v6wbi 59 * v7wbi - identical to v6wbi
59 */ 60 */
@@ -90,6 +91,22 @@
90# define v4_always_flags (-1UL) 91# define v4_always_flags (-1UL)
91#endif 92#endif
92 93
94#define fa_tlb_flags (TLB_WB | TLB_BTB | TLB_DCLEAN | \
95 TLB_V4_U_FULL | TLB_V4_U_PAGE)
96
97#ifdef CONFIG_CPU_TLB_FA
98# define fa_possible_flags fa_tlb_flags
99# define fa_always_flags fa_tlb_flags
100# ifdef _TLB
101# define MULTI_TLB 1
102# else
103# define _TLB fa
104# endif
105#else
106# define fa_possible_flags 0
107# define fa_always_flags (-1UL)
108#endif
109
93#define v4wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \ 110#define v4wbi_tlb_flags (TLB_WB | TLB_DCLEAN | \
94 TLB_V4_I_FULL | TLB_V4_D_FULL | \ 111 TLB_V4_I_FULL | TLB_V4_D_FULL | \
95 TLB_V4_I_PAGE | TLB_V4_D_PAGE) 112 TLB_V4_I_PAGE | TLB_V4_D_PAGE)
@@ -268,6 +285,7 @@ extern struct cpu_tlb_fns cpu_tlb;
268 v4wbi_possible_flags | \ 285 v4wbi_possible_flags | \
269 fr_possible_flags | \ 286 fr_possible_flags | \
270 v4wb_possible_flags | \ 287 v4wb_possible_flags | \
288 fa_possible_flags | \
271 v6wbi_possible_flags | \ 289 v6wbi_possible_flags | \
272 v7wbi_possible_flags) 290 v7wbi_possible_flags)
273 291
@@ -276,6 +294,7 @@ extern struct cpu_tlb_fns cpu_tlb;
276 v4wbi_always_flags & \ 294 v4wbi_always_flags & \
277 fr_always_flags & \ 295 fr_always_flags & \
278 v4wb_always_flags & \ 296 v4wb_always_flags & \
297 fa_always_flags & \
279 v6wbi_always_flags & \ 298 v6wbi_always_flags & \
280 v7wbi_always_flags) 299 v7wbi_always_flags)
281 300
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index d490f3773c01..bc3331863d9d 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -186,6 +186,24 @@ config CPU_ARM926T
186 Say Y if you want support for the ARM926T processor. 186 Say Y if you want support for the ARM926T processor.
187 Otherwise, say N. 187 Otherwise, say N.
188 188
189# FA526
190config CPU_FA526
191 bool
192 select CPU_32v4
193 select CPU_ABRT_EV4
194 select CPU_PABRT_NOIFAR
195 select CPU_CACHE_VIVT
196 select CPU_CP15_MMU
197 select CPU_CACHE_FA
198 select CPU_COPY_FA if MMU
199 select CPU_TLB_FA if MMU
200 help
201 The FA526 is a version of the ARMv4 compatible processor with
202 Branch Target Buffer, Unified TLB and cache line size 16.
203
204 Say Y if you want support for the FA526 processor.
205 Otherwise, say N.
206
189# ARM940T 207# ARM940T
190config CPU_ARM940T 208config CPU_ARM940T
191 bool "Support ARM940T processor" if ARCH_INTEGRATOR 209 bool "Support ARM940T processor" if ARCH_INTEGRATOR
@@ -484,6 +502,9 @@ config CPU_CACHE_VIVT
484config CPU_CACHE_VIPT 502config CPU_CACHE_VIPT
485 bool 503 bool
486 504
505config CPU_CACHE_FA
506 bool
507
487if MMU 508if MMU
488# The copy-page model 509# The copy-page model
489config CPU_COPY_V3 510config CPU_COPY_V3
@@ -498,6 +519,9 @@ config CPU_COPY_V4WB
498config CPU_COPY_FEROCEON 519config CPU_COPY_FEROCEON
499 bool 520 bool
500 521
522config CPU_COPY_FA
523 bool
524
501config CPU_COPY_V6 525config CPU_COPY_V6
502 bool 526 bool
503 527
@@ -528,6 +552,13 @@ config CPU_TLB_FEROCEON
528 help 552 help
529 Feroceon TLB (v4wbi with non-outer-cachable page table walks). 553 Feroceon TLB (v4wbi with non-outer-cachable page table walks).
530 554
555config CPU_TLB_FA
556 bool
557 help
558 Faraday ARM FA526 architecture, unified TLB with writeback cache
559 and invalidate instruction cache entry. Branch target buffer is
560 also supported.
561
531config CPU_TLB_V6 562config CPU_TLB_V6
532 bool 563 bool
533 564
@@ -638,7 +669,7 @@ config CPU_DCACHE_SIZE
638 669
639config CPU_DCACHE_WRITETHROUGH 670config CPU_DCACHE_WRITETHROUGH
640 bool "Force write through D-cache" 671 bool "Force write through D-cache"
641 depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020) && !CPU_DCACHE_DISABLE 672 depends on (CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_FA526) && !CPU_DCACHE_DISABLE
642 default y if CPU_ARM925T 673 default y if CPU_ARM925T
643 help 674 help
644 Say Y here to use the data cache in writethrough mode. Unless you 675 Say Y here to use the data cache in writethrough mode. Unless you
@@ -653,7 +684,7 @@ config CPU_CACHE_ROUND_ROBIN
653 684
654config CPU_BPREDICT_DISABLE 685config CPU_BPREDICT_DISABLE
655 bool "Disable branch prediction" 686 bool "Disable branch prediction"
656 depends on CPU_ARM1020 || CPU_V6 || CPU_XSC3 || CPU_V7 687 depends on CPU_ARM1020 || CPU_V6 || CPU_XSC3 || CPU_V7 || CPU_FA526
657 help 688 help
658 Say Y here to disable branch prediction. If unsure, say N. 689 Say Y here to disable branch prediction. If unsure, say N.
659 690
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 480f78a3611a..40f941c2245c 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_CPU_CACHE_V4WT) += cache-v4wt.o
32obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o 32obj-$(CONFIG_CPU_CACHE_V4WB) += cache-v4wb.o
33obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o 33obj-$(CONFIG_CPU_CACHE_V6) += cache-v6.o
34obj-$(CONFIG_CPU_CACHE_V7) += cache-v7.o 34obj-$(CONFIG_CPU_CACHE_V7) += cache-v7.o
35obj-$(CONFIG_CPU_CACHE_FA) += cache-fa.o
35 36
36obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o 37obj-$(CONFIG_CPU_COPY_V3) += copypage-v3.o
37obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o 38obj-$(CONFIG_CPU_COPY_V4WT) += copypage-v4wt.o
@@ -41,6 +42,7 @@ obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o context.o
41obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o 42obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o
42obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o 43obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o
43obj-$(CONFIG_CPU_XSC3) += copypage-xsc3.o 44obj-$(CONFIG_CPU_XSC3) += copypage-xsc3.o
45obj-$(CONFIG_CPU_COPY_FA) += copypage-fa.o
44 46
45obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o 47obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o
46obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o 48obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o
@@ -49,6 +51,7 @@ obj-$(CONFIG_CPU_TLB_V4WBI) += tlb-v4wbi.o
49obj-$(CONFIG_CPU_TLB_FEROCEON) += tlb-v4wbi.o # reuse v4wbi TLB functions 51obj-$(CONFIG_CPU_TLB_FEROCEON) += tlb-v4wbi.o # reuse v4wbi TLB functions
50obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o 52obj-$(CONFIG_CPU_TLB_V6) += tlb-v6.o
51obj-$(CONFIG_CPU_TLB_V7) += tlb-v7.o 53obj-$(CONFIG_CPU_TLB_V7) += tlb-v7.o
54obj-$(CONFIG_CPU_TLB_FA) += tlb-fa.o
52 55
53obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o 56obj-$(CONFIG_CPU_ARM610) += proc-arm6_7.o
54obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o 57obj-$(CONFIG_CPU_ARM710) += proc-arm6_7.o
@@ -62,6 +65,7 @@ obj-$(CONFIG_CPU_ARM925T) += proc-arm925.o
62obj-$(CONFIG_CPU_ARM926T) += proc-arm926.o 65obj-$(CONFIG_CPU_ARM926T) += proc-arm926.o
63obj-$(CONFIG_CPU_ARM940T) += proc-arm940.o 66obj-$(CONFIG_CPU_ARM940T) += proc-arm940.o
64obj-$(CONFIG_CPU_ARM946E) += proc-arm946.o 67obj-$(CONFIG_CPU_ARM946E) += proc-arm946.o
68obj-$(CONFIG_CPU_FA526) += proc-fa526.o
65obj-$(CONFIG_CPU_ARM1020) += proc-arm1020.o 69obj-$(CONFIG_CPU_ARM1020) += proc-arm1020.o
66obj-$(CONFIG_CPU_ARM1020E) += proc-arm1020e.o 70obj-$(CONFIG_CPU_ARM1020E) += proc-arm1020e.o
67obj-$(CONFIG_CPU_ARM1022) += proc-arm1022.o 71obj-$(CONFIG_CPU_ARM1022) += proc-arm1022.o
diff --git a/arch/arm/mm/cache-fa.S b/arch/arm/mm/cache-fa.S
new file mode 100644
index 000000000000..b63a8f7b95cf
--- /dev/null
+++ b/arch/arm/mm/cache-fa.S
@@ -0,0 +1,220 @@
1/*
2 * linux/arch/arm/mm/cache-fa.S
3 *
4 * Copyright (C) 2005 Faraday Corp.
5 * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
6 *
7 * Based on cache-v4wb.S:
8 * Copyright (C) 1997-2002 Russell king
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * Processors: FA520 FA526 FA626
15 */
16#include <linux/linkage.h>
17#include <linux/init.h>
18#include <asm/memory.h>
19#include <asm/page.h>
20
21#include "proc-macros.S"
22
23/*
24 * The size of one data cache line.
25 */
26#define CACHE_DLINESIZE 16
27
28/*
29 * The total size of the data cache.
30 */
31#ifdef CONFIG_ARCH_GEMINI
32#define CACHE_DSIZE 8192
33#else
34#define CACHE_DSIZE 16384
35#endif
36
37/* FIXME: put optimal value here. Current one is just estimation */
38#define CACHE_DLIMIT (CACHE_DSIZE * 2)
39
40/*
41 * flush_user_cache_all()
42 *
43 * Clean and invalidate all cache entries in a particular address
44 * space.
45 */
46ENTRY(fa_flush_user_cache_all)
47 /* FALLTHROUGH */
48/*
49 * flush_kern_cache_all()
50 *
51 * Clean and invalidate the entire cache.
52 */
53ENTRY(fa_flush_kern_cache_all)
54 mov ip, #0
55 mov r2, #VM_EXEC
56__flush_whole_cache:
57 mcr p15, 0, ip, c7, c14, 0 @ clean/invalidate D cache
58 tst r2, #VM_EXEC
59 mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
60 mcrne p15, 0, ip, c7, c5, 6 @ invalidate BTB
61 mcrne p15, 0, ip, c7, c10, 4 @ drain write buffer
62 mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush
63 mov pc, lr
64
65/*
66 * flush_user_cache_range(start, end, flags)
67 *
68 * Invalidate a range of cache entries in the specified
69 * address space.
70 *
71 * - start - start address (inclusive, page aligned)
72 * - end - end address (exclusive, page aligned)
73 * - flags - vma_area_struct flags describing address space
74 */
75ENTRY(fa_flush_user_cache_range)
76 mov ip, #0
77 sub r3, r1, r0 @ calculate total size
78 cmp r3, #CACHE_DLIMIT @ total size >= limit?
79 bhs __flush_whole_cache @ flush whole D cache
80
811: tst r2, #VM_EXEC
82 mcrne p15, 0, r0, c7, c5, 1 @ invalidate I line
83 mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
84 add r0, r0, #CACHE_DLINESIZE
85 cmp r0, r1
86 blo 1b
87 tst r2, #VM_EXEC
88 mcrne p15, 0, ip, c7, c5, 6 @ invalidate BTB
89 mcrne p15, 0, ip, c7, c10, 4 @ data write barrier
90 mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush
91 mov pc, lr
92
93/*
94 * coherent_kern_range(start, end)
95 *
96 * Ensure coherency between the Icache and the Dcache in the
97 * region described by start. If you have non-snooping
98 * Harvard caches, you need to implement this function.
99 *
100 * - start - virtual start address
101 * - end - virtual end address
102 */
103ENTRY(fa_coherent_kern_range)
104 /* fall through */
105
106/*
107 * coherent_user_range(start, end)
108 *
109 * Ensure coherency between the Icache and the Dcache in the
110 * region described by start. If you have non-snooping
111 * Harvard caches, you need to implement this function.
112 *
113 * - start - virtual start address
114 * - end - virtual end address
115 */
116ENTRY(fa_coherent_user_range)
117 bic r0, r0, #CACHE_DLINESIZE - 1
1181: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
119 mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
120 add r0, r0, #CACHE_DLINESIZE
121 cmp r0, r1
122 blo 1b
123 mov r0, #0
124 mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB
125 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
126 mcr p15, 0, r0, c7, c5, 4 @ prefetch flush
127 mov pc, lr
128
129/*
130 * flush_kern_dcache_page(kaddr)
131 *
132 * Ensure that the data held in the page kaddr is written back
133 * to the page in question.
134 *
135 * - kaddr - kernel address (guaranteed to be page aligned)
136 */
137ENTRY(fa_flush_kern_dcache_page)
138 add r1, r0, #PAGE_SZ
1391: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line
140 add r0, r0, #CACHE_DLINESIZE
141 cmp r0, r1
142 blo 1b
143 mov r0, #0
144 mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
145 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
146 mov pc, lr
147
148/*
149 * dma_inv_range(start, end)
150 *
151 * Invalidate (discard) the specified virtual address range.
152 * May not write back any entries. If 'start' or 'end'
153 * are not cache line aligned, those lines must be written
154 * back.
155 *
156 * - start - virtual start address
157 * - end - virtual end address
158 */
159ENTRY(fa_dma_inv_range)
160 tst r0, #CACHE_DLINESIZE - 1
161 bic r0, r0, #CACHE_DLINESIZE - 1
162 mcrne p15, 0, r0, c7, c14, 1 @ clean & invalidate D entry
163 tst r1, #CACHE_DLINESIZE - 1
164 bic r1, r1, #CACHE_DLINESIZE - 1
165 mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D entry
1661: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
167 add r0, r0, #CACHE_DLINESIZE
168 cmp r0, r1
169 blo 1b
170 mov r0, #0
171 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
172 mov pc, lr
173
174/*
175 * dma_clean_range(start, end)
176 *
177 * Clean (write back) the specified virtual address range.
178 *
179 * - start - virtual start address
180 * - end - virtual end address
181 */
182ENTRY(fa_dma_clean_range)
183 bic r0, r0, #CACHE_DLINESIZE - 1
1841: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
185 add r0, r0, #CACHE_DLINESIZE
186 cmp r0, r1
187 blo 1b
188 mov r0, #0
189 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
190 mov pc, lr
191
192/*
193 * dma_flush_range(start,end)
194 * - start - virtual start address of region
195 * - end - virtual end address of region
196 */
197ENTRY(fa_dma_flush_range)
198 bic r0, r0, #CACHE_DLINESIZE - 1
1991: mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D entry
200 add r0, r0, #CACHE_DLINESIZE
201 cmp r0, r1
202 blo 1b
203 mov r0, #0
204 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
205 mov pc, lr
206
207 __INITDATA
208
209 .type fa_cache_fns, #object
210ENTRY(fa_cache_fns)
211 .long fa_flush_kern_cache_all
212 .long fa_flush_user_cache_all
213 .long fa_flush_user_cache_range
214 .long fa_coherent_kern_range
215 .long fa_coherent_user_range
216 .long fa_flush_kern_dcache_page
217 .long fa_dma_inv_range
218 .long fa_dma_clean_range
219 .long fa_dma_flush_range
220 .size fa_cache_fns, . - fa_cache_fns
diff --git a/arch/arm/mm/copypage-fa.c b/arch/arm/mm/copypage-fa.c
new file mode 100644
index 000000000000..b2a6008b0111
--- /dev/null
+++ b/arch/arm/mm/copypage-fa.c
@@ -0,0 +1,86 @@
1/*
2 * linux/arch/arm/lib/copypage-fa.S
3 *
4 * Copyright (C) 2005 Faraday Corp.
5 * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
6 *
7 * Based on copypage-v4wb.S:
8 * Copyright (C) 1995-1999 Russell King
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14#include <linux/init.h>
15#include <linux/highmem.h>
16
17/*
18 * Faraday optimised copy_user_page
19 */
20static void __naked
21fa_copy_user_page(void *kto, const void *kfrom)
22{
23 asm("\
24 stmfd sp!, {r4, lr} @ 2\n\
25 mov r2, %0 @ 1\n\
261: ldmia r1!, {r3, r4, ip, lr} @ 4\n\
27 stmia r0, {r3, r4, ip, lr} @ 4\n\
28 mcr p15, 0, r0, c7, c14, 1 @ 1 clean and invalidate D line\n\
29 add r0, r0, #16 @ 1\n\
30 ldmia r1!, {r3, r4, ip, lr} @ 4\n\
31 stmia r0, {r3, r4, ip, lr} @ 4\n\
32 mcr p15, 0, r0, c7, c14, 1 @ 1 clean and invalidate D line\n\
33 add r0, r0, #16 @ 1\n\
34 subs r2, r2, #1 @ 1\n\
35 bne 1b @ 1\n\
36 mcr p15, 0, r2, c7, c10, 4 @ 1 drain WB\n\
37 ldmfd sp!, {r4, pc} @ 3"
38 :
39 : "I" (PAGE_SIZE / 32));
40}
41
42void fa_copy_user_highpage(struct page *to, struct page *from,
43 unsigned long vaddr)
44{
45 void *kto, *kfrom;
46
47 kto = kmap_atomic(to, KM_USER0);
48 kfrom = kmap_atomic(from, KM_USER1);
49 fa_copy_user_page(kto, kfrom);
50 kunmap_atomic(kfrom, KM_USER1);
51 kunmap_atomic(kto, KM_USER0);
52}
53
54/*
55 * Faraday optimised clear_user_page
56 *
57 * Same story as above.
58 */
59void fa_clear_user_highpage(struct page *page, unsigned long vaddr)
60{
61 void *ptr, *kaddr = kmap_atomic(page, KM_USER0);
62 asm volatile("\
63 mov r1, %2 @ 1\n\
64 mov r2, #0 @ 1\n\
65 mov r3, #0 @ 1\n\
66 mov ip, #0 @ 1\n\
67 mov lr, #0 @ 1\n\
681: stmia %0, {r2, r3, ip, lr} @ 4\n\
69 mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\
70 add %0, %0, #16 @ 1\n\
71 stmia %0, {r2, r3, ip, lr} @ 4\n\
72 mcr p15, 0, %0, c7, c14, 1 @ 1 clean and invalidate D line\n\
73 add %0, %0, #16 @ 1\n\
74 subs r1, r1, #1 @ 1\n\
75 bne 1b @ 1\n\
76 mcr p15, 0, r1, c7, c10, 4 @ 1 drain WB"
77 : "=r" (ptr)
78 : "0" (kaddr), "I" (PAGE_SIZE / 32)
79 : "r1", "r2", "r3", "ip", "lr");
80 kunmap_atomic(kaddr, KM_USER0);
81}
82
83struct cpu_user_fns fa_user_fns __initdata = {
84 .cpu_clear_user_highpage = fa_clear_user_highpage,
85 .cpu_copy_user_highpage = fa_copy_user_highpage,
86};
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S
new file mode 100644
index 000000000000..08b8a955d5d7
--- /dev/null
+++ b/arch/arm/mm/proc-fa526.S
@@ -0,0 +1,248 @@
1/*
2 * linux/arch/arm/mm/proc-fa526.S: MMU functions for FA526
3 *
4 * Written by : Luke Lee
5 * Copyright (C) 2005 Faraday Corp.
6 * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 *
14 * These are the low level assembler for performing cache and TLB
15 * functions on the fa526.
16 */
17#include <linux/linkage.h>
18#include <linux/init.h>
19#include <asm/assembler.h>
20#include <asm/hwcap.h>
21#include <asm/pgtable-hwdef.h>
22#include <asm/pgtable.h>
23#include <asm/page.h>
24#include <asm/ptrace.h>
25#include <asm/system.h>
26
27#include "proc-macros.S"
28
29#define CACHE_DLINESIZE 16
30
31 .text
32/*
33 * cpu_fa526_proc_init()
34 */
35ENTRY(cpu_fa526_proc_init)
36 mov pc, lr
37
38/*
39 * cpu_fa526_proc_fin()
40 */
41ENTRY(cpu_fa526_proc_fin)
42 stmfd sp!, {lr}
43 mov ip, #PSR_F_BIT | PSR_I_BIT | SVC_MODE
44 msr cpsr_c, ip
45 bl fa_flush_kern_cache_all
46 mrc p15, 0, r0, c1, c0, 0 @ ctrl register
47 bic r0, r0, #0x1000 @ ...i............
48 bic r0, r0, #0x000e @ ............wca.
49 mcr p15, 0, r0, c1, c0, 0 @ disable caches
50 nop
51 nop
52 ldmfd sp!, {pc}
53
54/*
55 * cpu_fa526_reset(loc)
56 *
57 * Perform a soft reset of the system. Put the CPU into the
58 * same state as it would be if it had been reset, and branch
59 * to what would be the reset vector.
60 *
61 * loc: location to jump to for soft reset
62 */
63 .align 4
64ENTRY(cpu_fa526_reset)
65/* TODO: Use CP8 if possible... */
66 mov ip, #0
67 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
68 mcr p15, 0, ip, c7, c10, 4 @ drain WB
69#ifdef CONFIG_MMU
70 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
71#endif
72 mrc p15, 0, ip, c1, c0, 0 @ ctrl register
73 bic ip, ip, #0x000f @ ............wcam
74 bic ip, ip, #0x1100 @ ...i...s........
75 bic ip, ip, #0x0800 @ BTB off
76 mcr p15, 0, ip, c1, c0, 0 @ ctrl register
77 nop
78 nop
79 mov pc, r0
80
81/*
82 * cpu_fa526_do_idle()
83 */
84 .align 4
85ENTRY(cpu_fa526_do_idle)
86 mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
87 mov pc, lr
88
89
90ENTRY(cpu_fa526_dcache_clean_area)
911: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
92 add r0, r0, #CACHE_DLINESIZE
93 subs r1, r1, #CACHE_DLINESIZE
94 bhi 1b
95 mcr p15, 0, r0, c7, c10, 4 @ drain WB
96 mov pc, lr
97
98/* =============================== PageTable ============================== */
99
100/*
101 * cpu_fa526_switch_mm(pgd)
102 *
103 * Set the translation base pointer to be as described by pgd.
104 *
105 * pgd: new page tables
106 */
107 .align 4
108ENTRY(cpu_fa526_switch_mm)
109#ifdef CONFIG_MMU
110 mov ip, #0
111#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
112 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
113#else
114 mcr p15, 0, ip, c7, c14, 0 @ clean and invalidate whole D cache
115#endif
116 mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
117 mcr p15, 0, ip, c7, c5, 6 @ invalidate BTB since mm changed
118 mcr p15, 0, ip, c7, c10, 4 @ data write barrier
119 mcr p15, 0, ip, c7, c5, 4 @ prefetch flush
120 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
121 mcr p15, 0, ip, c8, c7, 0 @ invalidate UTLB
122#endif
123 mov pc, lr
124
125/*
126 * cpu_fa526_set_pte_ext(ptep, pte, ext)
127 *
128 * Set a PTE and flush it out
129 */
130 .align 4
131ENTRY(cpu_fa526_set_pte_ext)
132#ifdef CONFIG_MMU
133 armv3_set_pte_ext
134 mov r0, r0
135 mcr p15, 0, r0, c7, c10, 1 @ clean D entry
136 mov r0, #0
137 mcr p15, 0, r0, c7, c10, 4 @ drain WB
138#endif
139 mov pc, lr
140
141 __INIT
142
143 .type __fa526_setup, #function
144__fa526_setup:
145 /* On return of this routine, r0 must carry correct flags for CFG register */
146 mov r0, #0
147 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
148 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
149#ifdef CONFIG_MMU
150 mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
151#endif
152 mcr p15, 0, r0, c7, c5, 5 @ invalidate IScratchpad RAM
153
154 mov r0, #1
155 mcr p15, 0, r0, c1, c1, 0 @ turn-on ECR
156
157 mov r0, #0
158 mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB All
159 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
160 mcr p15, 0, r0, c7, c5, 4 @ prefetch flush
161
162 mov r0, #0x1f @ Domains 0, 1 = manager, 2 = client
163 mcr p15, 0, r0, c3, c0 @ load domain access register
164
165 mrc p15, 0, r0, c1, c0 @ get control register v4
166 ldr r5, fa526_cr1_clear
167 bic r0, r0, r5
168 ldr r5, fa526_cr1_set
169 orr r0, r0, r5
170 mov pc, lr
171 .size __fa526_setup, . - __fa526_setup
172
173 /*
174 * .RVI ZFRS BLDP WCAM
175 * ..11 1001 .111 1101
176 *
177 */
178 .type fa526_cr1_clear, #object
179 .type fa526_cr1_set, #object
180fa526_cr1_clear:
181 .word 0x3f3f
182fa526_cr1_set:
183 .word 0x397D
184
185 __INITDATA
186
187/*
188 * Purpose : Function pointers used to access above functions - all calls
189 * come through these
190 */
191 .type fa526_processor_functions, #object
192fa526_processor_functions:
193 .word v4_early_abort
194 .word pabort_noifar
195 .word cpu_fa526_proc_init
196 .word cpu_fa526_proc_fin
197 .word cpu_fa526_reset
198 .word cpu_fa526_do_idle
199 .word cpu_fa526_dcache_clean_area
200 .word cpu_fa526_switch_mm
201 .word cpu_fa526_set_pte_ext
202 .size fa526_processor_functions, . - fa526_processor_functions
203
204 .section ".rodata"
205
206 .type cpu_arch_name, #object
207cpu_arch_name:
208 .asciz "armv4"
209 .size cpu_arch_name, . - cpu_arch_name
210
211 .type cpu_elf_name, #object
212cpu_elf_name:
213 .asciz "v4"
214 .size cpu_elf_name, . - cpu_elf_name
215
216 .type cpu_fa526_name, #object
217cpu_fa526_name:
218 .asciz "FA526"
219 .size cpu_fa526_name, . - cpu_fa526_name
220
221 .align
222
223 .section ".proc.info.init", #alloc, #execinstr
224
225 .type __fa526_proc_info,#object
226__fa526_proc_info:
227 .long 0x66015261
228 .long 0xff01fff1
229 .long PMD_TYPE_SECT | \
230 PMD_SECT_BUFFERABLE | \
231 PMD_SECT_CACHEABLE | \
232 PMD_BIT4 | \
233 PMD_SECT_AP_WRITE | \
234 PMD_SECT_AP_READ
235 .long PMD_TYPE_SECT | \
236 PMD_BIT4 | \
237 PMD_SECT_AP_WRITE | \
238 PMD_SECT_AP_READ
239 b __fa526_setup
240 .long cpu_arch_name
241 .long cpu_elf_name
242 .long HWCAP_SWP | HWCAP_HALF
243 .long cpu_fa526_name
244 .long fa526_processor_functions
245 .long fa_tlb_fns
246 .long fa_user_fns
247 .long fa_cache_fns
248 .size __fa526_proc_info, . - __fa526_proc_info
diff --git a/arch/arm/mm/tlb-fa.S b/arch/arm/mm/tlb-fa.S
new file mode 100644
index 000000000000..9694f1f6f485
--- /dev/null
+++ b/arch/arm/mm/tlb-fa.S
@@ -0,0 +1,75 @@
1/*
2 * linux/arch/arm/mm/tlb-fa.S
3 *
4 * Copyright (C) 2005 Faraday Corp.
5 * Copyright (C) 2008-2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
6 *
7 * Based on tlb-v4wbi.S:
8 * Copyright (C) 1997-2002 Russell King
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * ARM architecture version 4, Faraday variation.
15 * This assume an unified TLBs, with a write buffer, and branch target buffer (BTB)
16 *
17 * Processors: FA520 FA526 FA626
18 */
19#include <linux/linkage.h>
20#include <linux/init.h>
21#include <asm/asm-offsets.h>
22#include <asm/tlbflush.h>
23#include "proc-macros.S"
24
25
26/*
27 * flush_user_tlb_range(start, end, mm)
28 *
29 * Invalidate a range of TLB entries in the specified address space.
30 *
31 * - start - range start address
32 * - end - range end address
33 * - mm - mm_struct describing address space
34 */
35 .align 4
36ENTRY(fa_flush_user_tlb_range)
37 vma_vm_mm ip, r2
38 act_mm r3 @ get current->active_mm
39 eors r3, ip, r3 @ == mm ?
40 movne pc, lr @ no, we dont do anything
41 mov r3, #0
42 mcr p15, 0, r3, c7, c10, 4 @ drain WB
43 bic r0, r0, #0x0ff
44 bic r0, r0, #0xf00
451: mcr p15, 0, r0, c8, c7, 1 @ invalidate UTLB entry
46 add r0, r0, #PAGE_SZ
47 cmp r0, r1
48 blo 1b
49 mcr p15, 0, r3, c7, c5, 6 @ invalidate BTB
50 mcr p15, 0, r3, c7, c10, 4 @ data write barrier
51 mov pc, lr
52
53
54ENTRY(fa_flush_kern_tlb_range)
55 mov r3, #0
56 mcr p15, 0, r3, c7, c10, 4 @ drain WB
57 bic r0, r0, #0x0ff
58 bic r0, r0, #0xf00
591: mcr p15, 0, r0, c8, c7, 1 @ invalidate UTLB entry
60 add r0, r0, #PAGE_SZ
61 cmp r0, r1
62 blo 1b
63 mcr p15, 0, r3, c7, c5, 6 @ invalidate BTB
64 mcr p15, 0, r3, c7, c10, 4 @ data write barrier
65 mcr p15, 0, r3, c7, c5, 4 @ prefetch flush
66 mov pc, lr
67
68 __INITDATA
69
70 .type fa_tlb_fns, #object
71ENTRY(fa_tlb_fns)
72 .long fa_flush_user_tlb_range
73 .long fa_flush_kern_tlb_range
74 .long fa_tlb_flags
75 .size fa_tlb_fns, . - fa_tlb_fns