Merge branches 'acpica', 'acpi-video' and 'device-properties'
[deliverable/linux.git] / arch / metag / mm / l2cache.c
CommitLineData
99ef7c2a
JH
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 */
9static int l2cache_init = 1;
10/* If non-0, then initialise the L2 cache prefetch */
11static int l2cache_init_pf = 1;
12
13int l2c_pfenable;
14
15static volatile u32 l2c_testdata[16] __initdata __aligned(64);
16
17static 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}
27early_param("l2cache", parse_l2cache);
28
29static 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}
39early_param("l2cache_pf", parse_l2cache_pf);
40
41static 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}
94core_initcall(meta_l2c_setup);
95
96int 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
121int 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
147int 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
169int 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}
This page took 0.142804 seconds and 5 git commands to generate.