aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds2017-05-09 12:10:15 -0500
committerLinus Torvalds2017-05-09 12:10:15 -0500
commit4a1e31c68e9f40be32838944931178b0d9ed9162 (patch)
tree98b2cd1280ec759543a07a9517db04706ebf5de5 /arch
parentc6778ff813d2ca3e3c8733c87dc8b6831a64578b (diff)
parentcf4100d1cddcd243f80ac2af2e4c4273919ff225 (diff)
downloadkernel-4a1e31c68e9f40be32838944931178b0d9ed9162.tar.gz
kernel-4a1e31c68e9f40be32838944931178b0d9ed9162.tar.xz
kernel-4a1e31c68e9f40be32838944931178b0d9ed9162.zip
Merge tag 'arc-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arcHEADmaster
Pull ARC updates from Vineet Gupta: - AXS10x platform clk updates for I2S, PGU - add region based cache flush operation for ARCv2 cores - enforce PAE40 dependency on HIGHMEM - ptrace support for additional regs in ARCv2 cores - fix build failure in linux-next dut to a header include ordering change * tag 'arc-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc: Revert "ARCv2: Allow enabling PAE40 w/o HIGHMEM" ARC: mm: fix build failure in linux-next for UP builds ARCv2: ptrace: provide regset for accumulator/r30 regs elf: Add ARCv2 specific core note section ARCv2: mm: micro-optimize region flush generated code ARCv2: mm: Merge 2 updates to DC_CTRL for region flush ARCv2: mm: Implement cache region flush operations ARC: mm: Move full_page computation into cache version agnostic wrapper arc: axs10x: Fix ARC PGU default clock frequency arc: axs10x: Add DT bindings for I2S audio playback
Diffstat (limited to 'arch')
-rw-r--r--arch/arc/Kconfig1
-rw-r--r--arch/arc/boot/dts/axs10x_mb.dtsi24
-rw-r--r--arch/arc/include/asm/cache.h6
-rw-r--r--arch/arc/include/asm/mmu.h4
-rw-r--r--arch/arc/include/asm/pgtable.h6
-rw-r--r--arch/arc/include/uapi/asm/elf.h1
-rw-r--r--arch/arc/include/uapi/asm/ptrace.h5
-rw-r--r--arch/arc/kernel/ptrace.c62
-rw-r--r--arch/arc/mm/cache.c111
9 files changed, 196 insertions, 24 deletions
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 5d7fb3e7cb97..a5459698f0ee 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -444,6 +444,7 @@ config ARC_HAS_PAE40
444 bool "Support for the 40-bit Physical Address Extension" 444 bool "Support for the 40-bit Physical Address Extension"
445 default n 445 default n
446 depends on ISA_ARCV2 446 depends on ISA_ARCV2
447 select HIGHMEM
447 help 448 help
448 Enable access to physical memory beyond 4G, only supported on 449 Enable access to physical memory beyond 4G, only supported on
449 ARC cores with 40 bit Physical Addressing support 450 ARC cores with 40 bit Physical Addressing support
diff --git a/arch/arc/boot/dts/axs10x_mb.dtsi b/arch/arc/boot/dts/axs10x_mb.dtsi
index d6c1bbc98ac3..41cfb29b62c1 100644
--- a/arch/arc/boot/dts/axs10x_mb.dtsi
+++ b/arch/arc/boot/dts/axs10x_mb.dtsi
@@ -51,7 +51,7 @@
51 pguclk: pguclk { 51 pguclk: pguclk {
52 #clock-cells = <0>; 52 #clock-cells = <0>;
53 compatible = "fixed-clock"; 53 compatible = "fixed-clock";
54 clock-frequency = <74440000>; 54 clock-frequency = <74250000>;
55 }; 55 };
56 }; 56 };
57 57
@@ -149,12 +149,13 @@
149 interrupts = <14>; 149 interrupts = <14>;
150 }; 150 };
151 151
152 i2c@0x1e000 { 152 i2s: i2s@1e000 {
153 compatible = "snps,designware-i2c"; 153 compatible = "snps,designware-i2s";
154 reg = <0x1e000 0x100>; 154 reg = <0x1e000 0x100>;
155 clock-frequency = <400000>; 155 clocks = <&i2sclk 0>;
156 clocks = <&i2cclk>; 156 clock-names = "i2sclk";
157 interrupts = <15>; 157 interrupts = <15>;
158 #sound-dai-cells = <0>;
158 }; 159 };
159 160
160 i2c@0x1f000 { 161 i2c@0x1f000 {
@@ -174,6 +175,7 @@
174 adi,input-colorspace = "rgb"; 175 adi,input-colorspace = "rgb";
175 adi,input-clock = "1x"; 176 adi,input-clock = "1x";
176 adi,clock-delay = <0x03>; 177 adi,clock-delay = <0x03>;
178 #sound-dai-cells = <0>;
177 179
178 ports { 180 ports {
179 #address-cells = <1>; 181 #address-cells = <1>;
@@ -295,5 +297,17 @@
295 }; 297 };
296 }; 298 };
297 }; 299 };
300
301 sound_playback {
302 compatible = "simple-audio-card";
303 simple-audio-card,name = "AXS10x HDMI Audio";
304 simple-audio-card,format = "i2s";
305 simple-audio-card,cpu {
306 sound-dai = <&i2s>;
307 };
308 simple-audio-card,codec {
309 sound-dai = <&adv7511>;
310 };
311 };
298 }; 312 };
299}; 313};
diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h
index 5008021fba98..19ebddffb279 100644
--- a/arch/arc/include/asm/cache.h
+++ b/arch/arc/include/asm/cache.h
@@ -62,6 +62,8 @@ extern unsigned long perip_base, perip_end;
62#define ARC_REG_IC_BCR 0x77 /* Build Config reg */ 62#define ARC_REG_IC_BCR 0x77 /* Build Config reg */
63#define ARC_REG_IC_IVIC 0x10 63#define ARC_REG_IC_IVIC 0x10
64#define ARC_REG_IC_CTRL 0x11 64#define ARC_REG_IC_CTRL 0x11
65#define ARC_REG_IC_IVIR 0x16
66#define ARC_REG_IC_ENDR 0x17
65#define ARC_REG_IC_IVIL 0x19 67#define ARC_REG_IC_IVIL 0x19
66#define ARC_REG_IC_PTAG 0x1E 68#define ARC_REG_IC_PTAG 0x1E
67#define ARC_REG_IC_PTAG_HI 0x1F 69#define ARC_REG_IC_PTAG_HI 0x1F
@@ -76,6 +78,8 @@ extern unsigned long perip_base, perip_end;
76#define ARC_REG_DC_IVDL 0x4A 78#define ARC_REG_DC_IVDL 0x4A
77#define ARC_REG_DC_FLSH 0x4B 79#define ARC_REG_DC_FLSH 0x4B
78#define ARC_REG_DC_FLDL 0x4C 80#define ARC_REG_DC_FLDL 0x4C
81#define ARC_REG_DC_STARTR 0x4D
82#define ARC_REG_DC_ENDR 0x4E
79#define ARC_REG_DC_PTAG 0x5C 83#define ARC_REG_DC_PTAG 0x5C
80#define ARC_REG_DC_PTAG_HI 0x5F 84#define ARC_REG_DC_PTAG_HI 0x5F
81 85
@@ -83,6 +87,8 @@ extern unsigned long perip_base, perip_end;
83#define DC_CTRL_DIS 0x001 87#define DC_CTRL_DIS 0x001
84#define DC_CTRL_INV_MODE_FLUSH 0x040 88#define DC_CTRL_INV_MODE_FLUSH 0x040
85#define DC_CTRL_FLUSH_STATUS 0x100 89#define DC_CTRL_FLUSH_STATUS 0x100
90#define DC_CTRL_RGN_OP_INV 0x200
91#define DC_CTRL_RGN_OP_MSK 0x200
86 92
87/*System-level cache (L2 cache) related Auxiliary registers */ 93/*System-level cache (L2 cache) related Auxiliary registers */
88#define ARC_REG_SLC_CFG 0x901 94#define ARC_REG_SLC_CFG 0x901
diff --git a/arch/arc/include/asm/mmu.h b/arch/arc/include/asm/mmu.h
index b144d7ca7d20..db7319e9b506 100644
--- a/arch/arc/include/asm/mmu.h
+++ b/arch/arc/include/asm/mmu.h
@@ -9,6 +9,10 @@
9#ifndef _ASM_ARC_MMU_H 9#ifndef _ASM_ARC_MMU_H
10#define _ASM_ARC_MMU_H 10#define _ASM_ARC_MMU_H
11 11
12#ifndef __ASSEMBLY__
13#include <linux/threads.h> /* NR_CPUS */
14#endif
15
12#if defined(CONFIG_ARC_MMU_V1) 16#if defined(CONFIG_ARC_MMU_V1)
13#define CONFIG_ARC_MMU_VER 1 17#define CONFIG_ARC_MMU_VER 1
14#elif defined(CONFIG_ARC_MMU_V2) 18#elif defined(CONFIG_ARC_MMU_V2)
diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
index ee22d40afef4..08fe33830d4b 100644
--- a/arch/arc/include/asm/pgtable.h
+++ b/arch/arc/include/asm/pgtable.h
@@ -35,11 +35,11 @@
35#ifndef _ASM_ARC_PGTABLE_H 35#ifndef _ASM_ARC_PGTABLE_H
36#define _ASM_ARC_PGTABLE_H 36#define _ASM_ARC_PGTABLE_H
37 37
38#include <asm/page.h> 38#include <linux/const.h>
39#include <asm/mmu.h>
40#define __ARCH_USE_5LEVEL_HACK 39#define __ARCH_USE_5LEVEL_HACK
41#include <asm-generic/pgtable-nopmd.h> 40#include <asm-generic/pgtable-nopmd.h>
42#include <linux/const.h> 41#include <asm/page.h>
42#include <asm/mmu.h> /* to propagate CONFIG_ARC_MMU_VER <n> */
43 43
44/************************************************************************** 44/**************************************************************************
45 * Page Table Flags 45 * Page Table Flags
diff --git a/arch/arc/include/uapi/asm/elf.h b/arch/arc/include/uapi/asm/elf.h
index 0037a587320d..06d95e611616 100644
--- a/arch/arc/include/uapi/asm/elf.h
+++ b/arch/arc/include/uapi/asm/elf.h
@@ -27,6 +27,7 @@ typedef unsigned long elf_greg_t;
27typedef unsigned long elf_fpregset_t; 27typedef unsigned long elf_fpregset_t;
28 28
29#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t)) 29#define ELF_NGREG (sizeof(struct user_regs_struct) / sizeof(elf_greg_t))
30#define ELF_ARCV2REG (sizeof(struct user_regs_arcv2) / sizeof(elf_greg_t))
30 31
31typedef elf_greg_t elf_gregset_t[ELF_NGREG]; 32typedef elf_greg_t elf_gregset_t[ELF_NGREG];
32 33
diff --git a/arch/arc/include/uapi/asm/ptrace.h b/arch/arc/include/uapi/asm/ptrace.h
index 0b3ef63d4a03..dd206e6b482c 100644
--- a/arch/arc/include/uapi/asm/ptrace.h
+++ b/arch/arc/include/uapi/asm/ptrace.h
@@ -47,6 +47,11 @@ struct user_regs_struct {
47 unsigned long efa; /* break pt addr, for break points in delay slots */ 47 unsigned long efa; /* break pt addr, for break points in delay slots */
48 unsigned long stop_pc; /* give dbg stop_pc after ensuring brkpt trap */ 48 unsigned long stop_pc; /* give dbg stop_pc after ensuring brkpt trap */
49}; 49};
50
51struct user_regs_arcv2 {
52 unsigned long r30, r58, r59;
53};
54
50#endif /* !__ASSEMBLY__ */ 55#endif /* !__ASSEMBLY__ */
51 56
52#endif /* _UAPI__ASM_ARC_PTRACE_H */ 57#endif /* _UAPI__ASM_ARC_PTRACE_H */
diff --git a/arch/arc/kernel/ptrace.c b/arch/arc/kernel/ptrace.c
index 31150060d38b..5ee4676f135d 100644
--- a/arch/arc/kernel/ptrace.c
+++ b/arch/arc/kernel/ptrace.c
@@ -184,19 +184,75 @@ static int genregs_set(struct task_struct *target,
184 return ret; 184 return ret;
185} 185}
186 186
187#ifdef CONFIG_ISA_ARCV2
188static int arcv2regs_get(struct task_struct *target,
189 const struct user_regset *regset,
190 unsigned int pos, unsigned int count,
191 void *kbuf, void __user *ubuf)
192{
193 const struct pt_regs *regs = task_pt_regs(target);
194 int ret, copy_sz;
195
196 if (IS_ENABLED(CONFIG_ARC_HAS_ACCL_REGS))
197 copy_sz = sizeof(struct user_regs_arcv2);
198 else
199 copy_sz = 4; /* r30 only */
200
201 /*
202 * itemized copy not needed like above as layout of regs (r30,r58,r59)
203 * is exactly same in kernel (pt_regs) and userspace (user_regs_arcv2)
204 */
205 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &regs->r30,
206 0, copy_sz);
207
208 return ret;
209}
210
211static int arcv2regs_set(struct task_struct *target,
212 const struct user_regset *regset,
213 unsigned int pos, unsigned int count,
214 const void *kbuf, const void __user *ubuf)
215{
216 const struct pt_regs *regs = task_pt_regs(target);
217 int ret, copy_sz;
218
219 if (IS_ENABLED(CONFIG_ARC_HAS_ACCL_REGS))
220 copy_sz = sizeof(struct user_regs_arcv2);
221 else
222 copy_sz = 4; /* r30 only */
223
224 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, (void *)&regs->r30,
225 0, copy_sz);
226
227 return ret;
228}
229
230#endif
231
187enum arc_getset { 232enum arc_getset {
188 REGSET_GENERAL, 233 REGSET_CMN,
234 REGSET_ARCV2,
189}; 235};
190 236
191static const struct user_regset arc_regsets[] = { 237static const struct user_regset arc_regsets[] = {
192 [REGSET_GENERAL] = { 238 [REGSET_CMN] = {
193 .core_note_type = NT_PRSTATUS, 239 .core_note_type = NT_PRSTATUS,
194 .n = ELF_NGREG, 240 .n = ELF_NGREG,
195 .size = sizeof(unsigned long), 241 .size = sizeof(unsigned long),
196 .align = sizeof(unsigned long), 242 .align = sizeof(unsigned long),
197 .get = genregs_get, 243 .get = genregs_get,
198 .set = genregs_set, 244 .set = genregs_set,
199 } 245 },
246#ifdef CONFIG_ISA_ARCV2
247 [REGSET_ARCV2] = {
248 .core_note_type = NT_ARC_V2,
249 .n = ELF_ARCV2REG,
250 .size = sizeof(unsigned long),
251 .align = sizeof(unsigned long),
252 .get = arcv2regs_get,
253 .set = arcv2regs_set,
254 },
255#endif
200}; 256};
201 257
202static const struct user_regset_view user_arc_view = { 258static const struct user_regset_view user_arc_view = {
diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c
index 928562967f3c..a867575a758b 100644
--- a/arch/arc/mm/cache.c
+++ b/arch/arc/mm/cache.c
@@ -21,6 +21,10 @@
21#include <asm/cachectl.h> 21#include <asm/cachectl.h>
22#include <asm/setup.h> 22#include <asm/setup.h>
23 23
24#ifdef CONFIG_ISA_ARCV2
25#define USE_RGN_FLSH 1
26#endif
27
24static int l2_line_sz; 28static int l2_line_sz;
25static int ioc_exists; 29static int ioc_exists;
26int slc_enable = 1, ioc_enable = 1; 30int slc_enable = 1, ioc_enable = 1;
@@ -28,7 +32,7 @@ unsigned long perip_base = ARC_UNCACHED_ADDR_SPACE; /* legacy value for boot */
28unsigned long perip_end = 0xFFFFFFFF; /* legacy value */ 32unsigned long perip_end = 0xFFFFFFFF; /* legacy value */
29 33
30void (*_cache_line_loop_ic_fn)(phys_addr_t paddr, unsigned long vaddr, 34void (*_cache_line_loop_ic_fn)(phys_addr_t paddr, unsigned long vaddr,
31 unsigned long sz, const int cacheop); 35 unsigned long sz, const int op, const int full_page);
32 36
33void (*__dma_cache_wback_inv)(phys_addr_t start, unsigned long sz); 37void (*__dma_cache_wback_inv)(phys_addr_t start, unsigned long sz);
34void (*__dma_cache_inv)(phys_addr_t start, unsigned long sz); 38void (*__dma_cache_inv)(phys_addr_t start, unsigned long sz);
@@ -233,11 +237,10 @@ slc_chk:
233 237
234static inline 238static inline
235void __cache_line_loop_v2(phys_addr_t paddr, unsigned long vaddr, 239void __cache_line_loop_v2(phys_addr_t paddr, unsigned long vaddr,
236 unsigned long sz, const int op) 240 unsigned long sz, const int op, const int full_page)
237{ 241{
238 unsigned int aux_cmd; 242 unsigned int aux_cmd;
239 int num_lines; 243 int num_lines;
240 const int full_page = __builtin_constant_p(sz) && sz == PAGE_SIZE;
241 244
242 if (op == OP_INV_IC) { 245 if (op == OP_INV_IC) {
243 aux_cmd = ARC_REG_IC_IVIL; 246 aux_cmd = ARC_REG_IC_IVIL;
@@ -279,11 +282,10 @@ void __cache_line_loop_v2(phys_addr_t paddr, unsigned long vaddr,
279 */ 282 */
280static inline 283static inline
281void __cache_line_loop_v3(phys_addr_t paddr, unsigned long vaddr, 284void __cache_line_loop_v3(phys_addr_t paddr, unsigned long vaddr,
282 unsigned long sz, const int op) 285 unsigned long sz, const int op, const int full_page)
283{ 286{
284 unsigned int aux_cmd, aux_tag; 287 unsigned int aux_cmd, aux_tag;
285 int num_lines; 288 int num_lines;
286 const int full_page = __builtin_constant_p(sz) && sz == PAGE_SIZE;
287 289
288 if (op == OP_INV_IC) { 290 if (op == OP_INV_IC) {
289 aux_cmd = ARC_REG_IC_IVIL; 291 aux_cmd = ARC_REG_IC_IVIL;
@@ -334,6 +336,8 @@ void __cache_line_loop_v3(phys_addr_t paddr, unsigned long vaddr,
334 } 336 }
335} 337}
336 338
339#ifndef USE_RGN_FLSH
340
337/* 341/*
338 * In HS38x (MMU v4), I-cache is VIPT (can alias), D-cache is PIPT 342 * In HS38x (MMU v4), I-cache is VIPT (can alias), D-cache is PIPT
339 * Here's how cache ops are implemented 343 * Here's how cache ops are implemented
@@ -349,17 +353,16 @@ void __cache_line_loop_v3(phys_addr_t paddr, unsigned long vaddr,
349 */ 353 */
350static inline 354static inline
351void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr, 355void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr,
352 unsigned long sz, const int cacheop) 356 unsigned long sz, const int op, const int full_page)
353{ 357{
354 unsigned int aux_cmd; 358 unsigned int aux_cmd;
355 int num_lines; 359 int num_lines;
356 const int full_page_op = __builtin_constant_p(sz) && sz == PAGE_SIZE;
357 360
358 if (cacheop == OP_INV_IC) { 361 if (op == OP_INV_IC) {
359 aux_cmd = ARC_REG_IC_IVIL; 362 aux_cmd = ARC_REG_IC_IVIL;
360 } else { 363 } else {
361 /* d$ cmd: INV (discard or wback-n-discard) OR FLUSH (wback) */ 364 /* d$ cmd: INV (discard or wback-n-discard) OR FLUSH (wback) */
362 aux_cmd = cacheop & OP_INV ? ARC_REG_DC_IVDL : ARC_REG_DC_FLDL; 365 aux_cmd = op & OP_INV ? ARC_REG_DC_IVDL : ARC_REG_DC_FLDL;
363 } 366 }
364 367
365 /* Ensure we properly floor/ceil the non-line aligned/sized requests 368 /* Ensure we properly floor/ceil the non-line aligned/sized requests
@@ -368,7 +371,7 @@ void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr,
368 * -@paddr will be cache-line aligned already (being page aligned) 371 * -@paddr will be cache-line aligned already (being page aligned)
369 * -@sz will be integral multiple of line size (being page sized). 372 * -@sz will be integral multiple of line size (being page sized).
370 */ 373 */
371 if (!full_page_op) { 374 if (!full_page) {
372 sz += paddr & ~CACHE_LINE_MASK; 375 sz += paddr & ~CACHE_LINE_MASK;
373 paddr &= CACHE_LINE_MASK; 376 paddr &= CACHE_LINE_MASK;
374 } 377 }
@@ -381,7 +384,7 @@ void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr,
381 * - (and needs to be written before the lower 32 bits) 384 * - (and needs to be written before the lower 32 bits)
382 */ 385 */
383 if (is_pae40_enabled()) { 386 if (is_pae40_enabled()) {
384 if (cacheop == OP_INV_IC) 387 if (op == OP_INV_IC)
385 /* 388 /*
386 * Non aliasing I-cache in HS38, 389 * Non aliasing I-cache in HS38,
387 * aliasing I-cache handled in __cache_line_loop_v3() 390 * aliasing I-cache handled in __cache_line_loop_v3()
@@ -397,6 +400,55 @@ void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr,
397 } 400 }
398} 401}
399 402
403#else
404
405/*
406 * optimized flush operation which takes a region as opposed to iterating per line
407 */
408static inline
409void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr,
410 unsigned long sz, const int op, const int full_page)
411{
412 unsigned int s, e;
413
414 /* Only for Non aliasing I-cache in HS38 */
415 if (op == OP_INV_IC) {
416 s = ARC_REG_IC_IVIR;
417 e = ARC_REG_IC_ENDR;
418 } else {
419 s = ARC_REG_DC_STARTR;
420 e = ARC_REG_DC_ENDR;
421 }
422
423 if (!full_page) {
424 /* for any leading gap between @paddr and start of cache line */
425 sz += paddr & ~CACHE_LINE_MASK;
426 paddr &= CACHE_LINE_MASK;
427
428 /*
429 * account for any trailing gap to end of cache line
430 * this is equivalent to DIV_ROUND_UP() in line ops above
431 */
432 sz += L1_CACHE_BYTES - 1;
433 }
434
435 if (is_pae40_enabled()) {
436 /* TBD: check if crossing 4TB boundary */
437 if (op == OP_INV_IC)
438 write_aux_reg(ARC_REG_IC_PTAG_HI, (u64)paddr >> 32);
439 else
440 write_aux_reg(ARC_REG_DC_PTAG_HI, (u64)paddr >> 32);
441 }
442
443 /* ENDR needs to be set ahead of START */
444 write_aux_reg(e, paddr + sz); /* ENDR is exclusive */
445 write_aux_reg(s, paddr);
446
447 /* caller waits on DC_CTRL.FS */
448}
449
450#endif
451
400#if (CONFIG_ARC_MMU_VER < 3) 452#if (CONFIG_ARC_MMU_VER < 3)
401#define __cache_line_loop __cache_line_loop_v2 453#define __cache_line_loop __cache_line_loop_v2
402#elif (CONFIG_ARC_MMU_VER == 3) 454#elif (CONFIG_ARC_MMU_VER == 3)
@@ -411,6 +463,11 @@ void __cache_line_loop_v4(phys_addr_t paddr, unsigned long vaddr,
411 * Machine specific helpers for Entire D-Cache or Per Line ops 463 * Machine specific helpers for Entire D-Cache or Per Line ops
412 */ 464 */
413 465
466#ifndef USE_RGN_FLSH
467/*
468 * this version avoids extra read/write of DC_CTRL for flush or invalid ops
469 * in the non region flush regime (such as for ARCompact)
470 */
414static inline void __before_dc_op(const int op) 471static inline void __before_dc_op(const int op)
415{ 472{
416 if (op == OP_FLUSH_N_INV) { 473 if (op == OP_FLUSH_N_INV) {
@@ -424,6 +481,32 @@ static inline void __before_dc_op(const int op)
424 } 481 }
425} 482}
426 483
484#else
485
486static inline void __before_dc_op(const int op)
487{
488 const unsigned int ctl = ARC_REG_DC_CTRL;
489 unsigned int val = read_aux_reg(ctl);
490
491 if (op == OP_FLUSH_N_INV) {
492 val |= DC_CTRL_INV_MODE_FLUSH;
493 }
494
495 if (op != OP_INV_IC) {
496 /*
497 * Flush / Invalidate is provided by DC_CTRL.RNG_OP 0 or 1
498 * combined Flush-n-invalidate uses DC_CTRL.IM = 1 set above
499 */
500 val &= ~DC_CTRL_RGN_OP_MSK;
501 if (op & OP_INV)
502 val |= DC_CTRL_RGN_OP_INV;
503 }
504 write_aux_reg(ctl, val);
505}
506
507#endif
508
509
427static inline void __after_dc_op(const int op) 510static inline void __after_dc_op(const int op)
428{ 511{
429 if (op & OP_FLUSH) { 512 if (op & OP_FLUSH) {
@@ -486,13 +569,14 @@ static void __dc_enable(void)
486static inline void __dc_line_op(phys_addr_t paddr, unsigned long vaddr, 569static inline void __dc_line_op(phys_addr_t paddr, unsigned long vaddr,
487 unsigned long sz, const int op) 570 unsigned long sz, const int op)
488{ 571{
572 const int full_page = __builtin_constant_p(sz) && sz == PAGE_SIZE;
489 unsigned long flags; 573 unsigned long flags;
490 574
491 local_irq_save(flags); 575 local_irq_save(flags);
492 576
493 __before_dc_op(op); 577 __before_dc_op(op);
494 578
495 __cache_line_loop(paddr, vaddr, sz, op); 579 __cache_line_loop(paddr, vaddr, sz, op, full_page);
496 580
497 __after_dc_op(op); 581 __after_dc_op(op);
498 582
@@ -521,10 +605,11 @@ static inline void
521__ic_line_inv_vaddr_local(phys_addr_t paddr, unsigned long vaddr, 605__ic_line_inv_vaddr_local(phys_addr_t paddr, unsigned long vaddr,
522 unsigned long sz) 606 unsigned long sz)
523{ 607{
608 const int full_page = __builtin_constant_p(sz) && sz == PAGE_SIZE;
524 unsigned long flags; 609 unsigned long flags;
525 610
526 local_irq_save(flags); 611 local_irq_save(flags);
527 (*_cache_line_loop_ic_fn)(paddr, vaddr, sz, OP_INV_IC); 612 (*_cache_line_loop_ic_fn)(paddr, vaddr, sz, OP_INV_IC, full_page);
528 local_irq_restore(flags); 613 local_irq_restore(flags);
529} 614}
530 615