PageRenderTime 25ms CodeModel.GetById 11ms app.highlight 11ms RepoModel.GetById 2ms app.codeStats 0ms

/Ethereal-msm8939-beta9/arch/metag/mm/l2cache.c

https://bitbucket.org/MilosStamenkovic95/etherealos
C | 192 lines | 126 code | 29 blank | 37 comment | 19 complexity | 5dcc470be04ce0ecfde5c390d6652760 MD5 | raw file
  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}