1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2016 Vladimir Zapolskiy <vz@mleia.com>
4 * (C) Copyright 2007 Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
5 */
6
7 #include <command.h>
8 #include <cpu_func.h>
9 #include <stdio.h>
10 #include <asm/cache.h>
11 #include <asm/io.h>
12 #include <asm/processor.h>
13 #include <asm/system.h>
14 #include <linux/errno.h>
15
16 #define CACHE_VALID 1
17 #define CACHE_UPDATED 2
18
cache_wback_all(void)19 static inline void cache_wback_all(void)
20 {
21 unsigned long addr, data, i, j;
22
23 for (i = 0; i < CACHE_OC_NUM_ENTRIES; i++) {
24 for (j = 0; j < CACHE_OC_NUM_WAYS; j++) {
25 addr = CACHE_OC_ADDRESS_ARRAY
26 | (j << CACHE_OC_WAY_SHIFT)
27 | (i << CACHE_OC_ENTRY_SHIFT);
28 data = inl(addr);
29 if (data & CACHE_UPDATED) {
30 data &= ~CACHE_UPDATED;
31 outl(data, addr);
32 }
33 }
34 }
35 }
36
37 #define CACHE_ENABLE 0
38 #define CACHE_DISABLE 1
39 #define CACHE_INVALIDATE 2
40
cache_control(unsigned int cmd)41 static int cache_control(unsigned int cmd)
42 {
43 unsigned long ccr;
44
45 jump_to_P2();
46 ccr = inl(CCR);
47
48 if (ccr & CCR_CACHE_ENABLE)
49 cache_wback_all();
50
51 if (cmd == CACHE_INVALIDATE)
52 outl(CCR_CACHE_ICI | ccr, CCR);
53 else if (cmd == CACHE_DISABLE)
54 outl(CCR_CACHE_STOP, CCR);
55 else
56 outl(CCR_CACHE_INIT, CCR);
57 back_to_P1();
58
59 return 0;
60 }
61
flush_dcache_range(unsigned long start,unsigned long end)62 void flush_dcache_range(unsigned long start, unsigned long end)
63 {
64 u32 v;
65
66 start &= ~(L1_CACHE_BYTES - 1);
67 for (v = start; v < end; v += L1_CACHE_BYTES) {
68 asm volatile ("ocbp %0" : /* no output */
69 : "m" (__m(v)));
70 }
71 }
72
73 /*
74 * Default implementation:
75 * do a range flush for the entire range
76 */
flush_dcache_all(void)77 void flush_dcache_all(void)
78 {
79 flush_dcache_range(0, ~0);
80 }
81
invalidate_dcache_range(unsigned long start,unsigned long end)82 void invalidate_dcache_range(unsigned long start, unsigned long end)
83 {
84 u32 v;
85
86 start &= ~(L1_CACHE_BYTES - 1);
87 for (v = start; v < end; v += L1_CACHE_BYTES) {
88 asm volatile ("ocbi %0" : /* no output */
89 : "m" (__m(v)));
90 }
91 }
92
flush_cache(unsigned long addr,unsigned long size)93 void flush_cache(unsigned long addr, unsigned long size)
94 {
95 flush_dcache_range(addr , addr + size);
96 }
97
icache_enable(void)98 void icache_enable(void)
99 {
100 cache_control(CACHE_ENABLE);
101 }
102
icache_disable(void)103 void icache_disable(void)
104 {
105 cache_control(CACHE_DISABLE);
106 }
107
invalidate_icache_all(void)108 void invalidate_icache_all(void)
109 {
110 cache_control(CACHE_INVALIDATE);
111 }
112
icache_status(void)113 int icache_status(void)
114 {
115 return 0;
116 }
117
dcache_enable(void)118 void dcache_enable(void)
119 {
120 }
121
dcache_disable(void)122 void dcache_disable(void)
123 {
124 }
125
dcache_status(void)126 int dcache_status(void)
127 {
128 return 0;
129 }
130
pgprot_set_attrs(phys_addr_t addr,size_t size,enum pgprot_attrs perm)131 int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm)
132 {
133 return -ENOSYS;
134 }
135