blob: 7c74e1adfed12ddb377e16c5ab4050a50af78ede [file] [log] [blame]
Thomas Chou21ff7342015-10-23 07:58:20 +08001/*
2 * Copyright (C) 2015 Thomas Chou <thomas@wytron.com.tw>
3 * Copyright (C) 2009, Wind River Systems Inc
4 * Implemented by fredrik.markstrom@gmail.com and ivarholmqvist@gmail.com
5 *
6 * SPDX-License-Identifier: GPL-2.0+
7 */
8
9#include <common.h>
10#include <asm/cache.h>
11
12DECLARE_GLOBAL_DATA_PTR;
13
14static void __flush_dcache(unsigned long start, unsigned long end)
15{
16 unsigned long addr;
17
18 start &= ~(gd->arch.dcache_line_size - 1);
19 end += (gd->arch.dcache_line_size - 1);
20 end &= ~(gd->arch.dcache_line_size - 1);
21
22 for (addr = start; addr < end; addr += gd->arch.dcache_line_size) {
23 __asm__ __volatile__ (" flushda 0(%0)\n"
24 : /* Outputs */
25 : /* Inputs */ "r"(addr)
26 /* : No clobber */);
27 }
28}
29
30static void __flush_dcache_all(unsigned long start, unsigned long end)
31{
32 unsigned long addr;
33
34 start &= ~(gd->arch.dcache_line_size - 1);
35 end += (gd->arch.dcache_line_size - 1);
36 end &= ~(gd->arch.dcache_line_size - 1);
37
38 if (end > start + gd->arch.dcache_size)
39 end = start + gd->arch.dcache_size;
40
41 for (addr = start; addr < end; addr += gd->arch.dcache_line_size) {
42 __asm__ __volatile__ (" flushd 0(%0)\n"
43 : /* Outputs */
44 : /* Inputs */ "r"(addr)
45 /* : No clobber */);
46 }
47}
48
49static void __invalidate_dcache(unsigned long start, unsigned long end)
50{
51 unsigned long addr;
52
53 start &= ~(gd->arch.dcache_line_size - 1);
54 end += (gd->arch.dcache_line_size - 1);
55 end &= ~(gd->arch.dcache_line_size - 1);
56
57 for (addr = start; addr < end; addr += gd->arch.dcache_line_size) {
58 __asm__ __volatile__ (" initda 0(%0)\n"
59 : /* Outputs */
60 : /* Inputs */ "r"(addr)
61 /* : No clobber */);
62 }
63}
64
65static void __flush_icache(unsigned long start, unsigned long end)
66{
67 unsigned long addr;
68
69 start &= ~(gd->arch.icache_line_size - 1);
70 end += (gd->arch.icache_line_size - 1);
71 end &= ~(gd->arch.icache_line_size - 1);
72
73 if (end > start + gd->arch.icache_size)
74 end = start + gd->arch.icache_size;
75
76 for (addr = start; addr < end; addr += gd->arch.icache_line_size) {
77 __asm__ __volatile__ (" flushi %0\n"
78 : /* Outputs */
79 : /* Inputs */ "r"(addr)
80 /* : No clobber */);
81 }
82 __asm__ __volatile(" flushp\n");
83}
84
85void flush_dcache_all(void)
86{
87 __flush_dcache_all(0, gd->arch.dcache_size);
88 __flush_icache(0, gd->arch.icache_size);
89}
90
91void flush_dcache_range(unsigned long start, unsigned long end)
92{
93 if (gd->arch.has_initda)
94 __flush_dcache(start, end);
95 else
96 __flush_dcache_all(start, end);
97}
98
99void flush_cache(unsigned long start, unsigned long size)
100{
101 if (gd->arch.has_initda)
102 __flush_dcache(start, start + size);
103 else
104 __flush_dcache_all(start, start + size);
105 __flush_icache(start, start + size);
106}
107
108void invalidate_dcache_range(unsigned long start, unsigned long end)
109{
110 if (gd->arch.has_initda)
111 __invalidate_dcache(start, end);
112 else
113 __flush_dcache_all(start, end);
114}
115
116int dcache_status(void)
117{
118 return 1;
119}
120
121void dcache_enable(void)
122{
123 flush_dcache_all();
124}
125
126void dcache_disable(void)
127{
128 flush_dcache_all();
129}