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