]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - arch/metag/mm/l2cache.c
Merge tag 'irqchip-4.15-4' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm...
[mirror_ubuntu-bionic-kernel.git] / arch / metag / mm / l2cache.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/init.h>
3 #include <linux/kernel.h>
4 #include <linux/delay.h>
5
6 #include <asm/l2cache.h>
7 #include <asm/metag_isa.h>
8
9 /* If non-0, then initialise the L2 cache */
10 static int l2cache_init = 1;
11 /* If non-0, then initialise the L2 cache prefetch */
12 static int l2cache_init_pf = 1;
13
14 int l2c_pfenable;
15
16 static volatile u32 l2c_testdata[16] __initdata __aligned(64);
17
18 static int __init parse_l2cache(char *p)
19 {
20 char *cp = p;
21
22 if (get_option(&cp, &l2cache_init) != 1) {
23 pr_err("Bad l2cache parameter (%s)\n", p);
24 return 1;
25 }
26 return 0;
27 }
28 early_param("l2cache", parse_l2cache);
29
30 static int __init parse_l2cache_pf(char *p)
31 {
32 char *cp = p;
33
34 if (get_option(&cp, &l2cache_init_pf) != 1) {
35 pr_err("Bad l2cache_pf parameter (%s)\n", p);
36 return 1;
37 }
38 return 0;
39 }
40 early_param("l2cache_pf", parse_l2cache_pf);
41
42 static int __init meta_l2c_setup(void)
43 {
44 /*
45 * If the L2 cache isn't even present, don't do anything, but say so in
46 * the log.
47 */
48 if (!meta_l2c_is_present()) {
49 pr_info("L2 Cache: Not present\n");
50 return 0;
51 }
52
53 /*
54 * Check whether the line size is recognised.
55 */
56 if (!meta_l2c_linesize()) {
57 pr_warn_once("L2 Cache: unknown line size id (config=0x%08x)\n",
58 meta_l2c_config());
59 }
60
61 /*
62 * Initialise state.
63 */
64 l2c_pfenable = _meta_l2c_pf_is_enabled();
65
66 /*
67 * Enable the L2 cache and print to log whether it was already enabled
68 * by the bootloader.
69 */
70 if (l2cache_init) {
71 pr_info("L2 Cache: Enabling... ");
72 if (meta_l2c_enable())
73 pr_cont("already enabled\n");
74 else
75 pr_cont("done\n");
76 } else {
77 pr_info("L2 Cache: Not enabling\n");
78 }
79
80 /*
81 * Enable L2 cache prefetch.
82 */
83 if (l2cache_init_pf) {
84 pr_info("L2 Cache: Enabling prefetch... ");
85 if (meta_l2c_pf_enable(1))
86 pr_cont("already enabled\n");
87 else
88 pr_cont("done\n");
89 } else {
90 pr_info("L2 Cache: Not enabling prefetch\n");
91 }
92
93 return 0;
94 }
95 core_initcall(meta_l2c_setup);
96
97 int meta_l2c_disable(void)
98 {
99 unsigned long flags;
100 int en;
101
102 if (!meta_l2c_is_present())
103 return 1;
104
105 /*
106 * Prevent other threads writing during the writeback, otherwise the
107 * writes will get "lost" when the L2 is disabled.
108 */
109 __global_lock2(flags);
110 en = meta_l2c_is_enabled();
111 if (likely(en)) {
112 _meta_l2c_pf_enable(0);
113 wr_fence();
114 _meta_l2c_purge();
115 _meta_l2c_enable(0);
116 }
117 __global_unlock2(flags);
118
119 return !en;
120 }
121
122 int meta_l2c_enable(void)
123 {
124 unsigned long flags;
125 int en;
126
127 if (!meta_l2c_is_present())
128 return 0;
129
130 /*
131 * Init (clearing the L2) can happen while the L2 is disabled, so other
132 * threads are safe to continue executing, however we must not init the
133 * cache if it's already enabled (dirty lines would be discarded), so
134 * this operation should still be atomic with other threads.
135 */
136 __global_lock1(flags);
137 en = meta_l2c_is_enabled();
138 if (likely(!en)) {
139 _meta_l2c_init();
140 _meta_l2c_enable(1);
141 _meta_l2c_pf_enable(l2c_pfenable);
142 }
143 __global_unlock1(flags);
144
145 return en;
146 }
147
148 int meta_l2c_pf_enable(int pfenable)
149 {
150 unsigned long flags;
151 int en = l2c_pfenable;
152
153 if (!meta_l2c_is_present())
154 return 0;
155
156 /*
157 * We read modify write the enable register, so this operation must be
158 * atomic with other threads.
159 */
160 __global_lock1(flags);
161 en = l2c_pfenable;
162 l2c_pfenable = pfenable;
163 if (meta_l2c_is_enabled())
164 _meta_l2c_pf_enable(pfenable);
165 __global_unlock1(flags);
166
167 return en;
168 }
169
170 int meta_l2c_flush(void)
171 {
172 unsigned long flags;
173 int en;
174
175 /*
176 * Prevent other threads writing during the writeback. This also
177 * involves read modify writes.
178 */
179 __global_lock2(flags);
180 en = meta_l2c_is_enabled();
181 if (likely(en)) {
182 _meta_l2c_pf_enable(0);
183 wr_fence();
184 _meta_l2c_purge();
185 _meta_l2c_enable(0);
186 _meta_l2c_init();
187 _meta_l2c_enable(1);
188 _meta_l2c_pf_enable(l2c_pfenable);
189 }
190 __global_unlock2(flags);
191
192 return !en;
193 }