]> git.ipfire.org Git - people/ms/u-boot.git/blob - arch/sh/cpu/sh4/cache.c
sh: cache: Change cache API to defines as U-Boot
[people/ms/u-boot.git] / arch / sh / cpu / sh4 / cache.c
1 /*
2 * (C) Copyright 2007
3 * Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8 #include <common.h>
9 #include <command.h>
10 #include <asm/processor.h>
11 #include <asm/io.h>
12
13 /*
14 * Jump to P2 area.
15 * When handling TLB or caches, we need to do it from P2 area.
16 */
17 #define jump_to_P2() \
18 do { \
19 unsigned long __dummy; \
20 __asm__ __volatile__( \
21 "mov.l 1f, %0\n\t" \
22 "or %1, %0\n\t" \
23 "jmp @%0\n\t" \
24 " nop\n\t" \
25 ".balign 4\n" \
26 "1: .long 2f\n" \
27 "2:" \
28 : "=&r" (__dummy) \
29 : "r" (0x20000000)); \
30 } while (0)
31
32 /*
33 * Back to P1 area.
34 */
35 #define back_to_P1() \
36 do { \
37 unsigned long __dummy; \
38 __asm__ __volatile__( \
39 "nop;nop;nop;nop;nop;nop;nop\n\t" \
40 "mov.l 1f, %0\n\t" \
41 "jmp @%0\n\t" \
42 " nop\n\t" \
43 ".balign 4\n" \
44 "1: .long 2f\n" \
45 "2:" \
46 : "=&r" (__dummy)); \
47 } while (0)
48
49 #define CACHE_VALID 1
50 #define CACHE_UPDATED 2
51
52 static inline void cache_wback_all(void)
53 {
54 unsigned long addr, data, i, j;
55
56 jump_to_P2();
57 for (i = 0; i < CACHE_OC_NUM_ENTRIES; i++){
58 for (j = 0; j < CACHE_OC_NUM_WAYS; j++) {
59 addr = CACHE_OC_ADDRESS_ARRAY | (j << CACHE_OC_WAY_SHIFT)
60 | (i << CACHE_OC_ENTRY_SHIFT);
61 data = inl(addr);
62 if (data & CACHE_UPDATED) {
63 data &= ~CACHE_UPDATED;
64 outl(data, addr);
65 }
66 }
67 }
68 back_to_P1();
69 }
70
71
72 #define CACHE_ENABLE 0
73 #define CACHE_DISABLE 1
74
75 int cache_control(unsigned int cmd)
76 {
77 unsigned long ccr;
78
79 jump_to_P2();
80 ccr = inl(CCR);
81
82 if (ccr & CCR_CACHE_ENABLE)
83 cache_wback_all();
84
85 if (cmd == CACHE_DISABLE)
86 outl(CCR_CACHE_STOP, CCR);
87 else
88 outl(CCR_CACHE_INIT, CCR);
89 back_to_P1();
90
91 return 0;
92 }
93
94 void flush_dcache_range(unsigned long start, unsigned long end)
95 {
96 u32 v;
97
98 start &= ~(L1_CACHE_BYTES - 1);
99 for (v = start; v < end; v += L1_CACHE_BYTES) {
100 asm volatile ("ocbwb %0" : /* no output */
101 : "m" (__m(v)));
102 }
103 }
104
105 void invalidate_dcache_range(unsigned long start, unsigned long end)
106 {
107 u32 v;
108
109 start &= ~(L1_CACHE_BYTES - 1);
110 for (v = start; v < end; v += L1_CACHE_BYTES) {
111 asm volatile ("ocbi %0" : /* no output */
112 : "m" (__m(v)));
113 }
114 }