aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/mm/isram-driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/mm/isram-driver.c')
-rw-r--r--arch/blackfin/mm/isram-driver.c94
1 files changed, 51 insertions, 43 deletions
diff --git a/arch/blackfin/mm/isram-driver.c b/arch/blackfin/mm/isram-driver.c
index 39b058564f62..7e2e674ed444 100644
--- a/arch/blackfin/mm/isram-driver.c
+++ b/arch/blackfin/mm/isram-driver.c
@@ -43,13 +43,12 @@ static DEFINE_SPINLOCK(dtest_lock);
43/* Takes a void pointer */ 43/* Takes a void pointer */
44#define IADDR2DTEST(x) \ 44#define IADDR2DTEST(x) \
45 ({ unsigned long __addr = (unsigned long)(x); \ 45 ({ unsigned long __addr = (unsigned long)(x); \
46 (__addr & 0x47F8) | /* address bits 14 & 10:3 */ \ 46 ((__addr & (1 << 11)) << (26 - 11)) | /* addr bit 11 (Way0/Way1) */ \
47 (__addr & 0x8000) << 23 | /* Bank A/B */ \ 47 (1 << 24) | /* instruction access = 1 */ \
48 (__addr & 0x0800) << 15 | /* address bit 11 */ \ 48 ((__addr & (1 << 15)) << (23 - 15)) | /* addr bit 15 (Data Bank) */ \
49 (__addr & 0x3000) << 4 | /* address bits 13:12 */ \ 49 ((__addr & (3 << 12)) << (16 - 12)) | /* addr bits 13:12 (Subbank) */ \
50 (__addr & 0x8000) << 8 | /* address bit 15 */ \ 50 (__addr & 0x47F8) | /* addr bits 14 & 10:3 */ \
51 (0x1000000) | /* instruction access = 1 */ \ 51 (1 << 2); /* data array = 1 */ \
52 (0x4); /* data array = 1 */ \
53 }) 52 })
54 53
55/* Takes a pointer, and returns the offset (in bits) which things should be shifted */ 54/* Takes a pointer, and returns the offset (in bits) which things should be shifted */
@@ -196,7 +195,7 @@ EXPORT_SYMBOL(isram_memcpy);
196 195
197#ifdef CONFIG_BFIN_ISRAM_SELF_TEST 196#ifdef CONFIG_BFIN_ISRAM_SELF_TEST
198 197
199#define TEST_LEN 0x100 198static int test_len = 0x20000;
200 199
201static __init void hex_dump(unsigned char *buf, int len) 200static __init void hex_dump(unsigned char *buf, int len)
202{ 201{
@@ -212,15 +211,15 @@ static __init int isram_read_test(char *sdram, void *l1inst)
212 pr_info("INFO: running isram_read tests\n"); 211 pr_info("INFO: running isram_read tests\n");
213 212
214 /* setup some different data to play with */ 213 /* setup some different data to play with */
215 for (i = 0; i < TEST_LEN; ++i) 214 for (i = 0; i < test_len; ++i)
216 sdram[i] = i; 215 sdram[i] = i % 255;
217 dma_memcpy(l1inst, sdram, TEST_LEN); 216 dma_memcpy(l1inst, sdram, test_len);
218 217
219 /* make sure we can read the L1 inst */ 218 /* make sure we can read the L1 inst */
220 for (i = 0; i < TEST_LEN; i += sizeof(uint64_t)) { 219 for (i = 0; i < test_len; i += sizeof(uint64_t)) {
221 data1 = isram_read(l1inst + i); 220 data1 = isram_read(l1inst + i);
222 memcpy(&data2, sdram + i, sizeof(data2)); 221 memcpy(&data2, sdram + i, sizeof(data2));
223 if (memcmp(&data1, &data2, sizeof(uint64_t))) { 222 if (data1 != data2) {
224 pr_err("FAIL: isram_read(%p) returned %#llx but wanted %#llx\n", 223 pr_err("FAIL: isram_read(%p) returned %#llx but wanted %#llx\n",
225 l1inst + i, data1, data2); 224 l1inst + i, data1, data2);
226 ++ret; 225 ++ret;
@@ -238,25 +237,25 @@ static __init int isram_write_test(char *sdram, void *l1inst)
238 pr_info("INFO: running isram_write tests\n"); 237 pr_info("INFO: running isram_write tests\n");
239 238
240 /* setup some different data to play with */ 239 /* setup some different data to play with */
241 memset(sdram, 0, TEST_LEN * 2); 240 memset(sdram, 0, test_len * 2);
242 dma_memcpy(l1inst, sdram, TEST_LEN); 241 dma_memcpy(l1inst, sdram, test_len);
243 for (i = 0; i < TEST_LEN; ++i) 242 for (i = 0; i < test_len; ++i)
244 sdram[i] = i; 243 sdram[i] = i % 255;
245 244
246 /* make sure we can write the L1 inst */ 245 /* make sure we can write the L1 inst */
247 for (i = 0; i < TEST_LEN; i += sizeof(uint64_t)) { 246 for (i = 0; i < test_len; i += sizeof(uint64_t)) {
248 memcpy(&data1, sdram + i, sizeof(data1)); 247 memcpy(&data1, sdram + i, sizeof(data1));
249 isram_write(l1inst + i, data1); 248 isram_write(l1inst + i, data1);
250 data2 = isram_read(l1inst + i); 249 data2 = isram_read(l1inst + i);
251 if (memcmp(&data1, &data2, sizeof(uint64_t))) { 250 if (data1 != data2) {
252 pr_err("FAIL: isram_write(%p, %#llx) != %#llx\n", 251 pr_err("FAIL: isram_write(%p, %#llx) != %#llx\n",
253 l1inst + i, data1, data2); 252 l1inst + i, data1, data2);
254 ++ret; 253 ++ret;
255 } 254 }
256 } 255 }
257 256
258 dma_memcpy(sdram + TEST_LEN, l1inst, TEST_LEN); 257 dma_memcpy(sdram + test_len, l1inst, test_len);
259 if (memcmp(sdram, sdram + TEST_LEN, TEST_LEN)) { 258 if (memcmp(sdram, sdram + test_len, test_len)) {
260 pr_err("FAIL: isram_write() did not work properly\n"); 259 pr_err("FAIL: isram_write() did not work properly\n");
261 ++ret; 260 ++ret;
262 } 261 }
@@ -268,12 +267,12 @@ static __init int
268_isram_memcpy_test(char pattern, void *sdram, void *l1inst, const char *smemcpy, 267_isram_memcpy_test(char pattern, void *sdram, void *l1inst, const char *smemcpy,
269 void *(*fmemcpy)(void *, const void *, size_t)) 268 void *(*fmemcpy)(void *, const void *, size_t))
270{ 269{
271 memset(sdram, pattern, TEST_LEN); 270 memset(sdram, pattern, test_len);
272 fmemcpy(l1inst, sdram, TEST_LEN); 271 fmemcpy(l1inst, sdram, test_len);
273 fmemcpy(sdram + TEST_LEN, l1inst, TEST_LEN); 272 fmemcpy(sdram + test_len, l1inst, test_len);
274 if (memcmp(sdram, sdram + TEST_LEN, TEST_LEN)) { 273 if (memcmp(sdram, sdram + test_len, test_len)) {
275 pr_err("FAIL: %s(%p <=> %p, %#x) failed (data is %#x)\n", 274 pr_err("FAIL: %s(%p <=> %p, %#x) failed (data is %#x)\n",
276 smemcpy, l1inst, sdram, TEST_LEN, pattern); 275 smemcpy, l1inst, sdram, test_len, pattern);
277 return 1; 276 return 1;
278 } 277 }
279 return 0; 278 return 0;
@@ -292,12 +291,13 @@ static __init int isram_memcpy_test(char *sdram, void *l1inst)
292 /* check read of small, unaligned, and hardware 64bit limits */ 291 /* check read of small, unaligned, and hardware 64bit limits */
293 pr_info("INFO: running isram_memcpy (read) tests\n"); 292 pr_info("INFO: running isram_memcpy (read) tests\n");
294 293
295 for (i = 0; i < TEST_LEN; ++i) 294 /* setup some different data to play with */
296 sdram[i] = i; 295 for (i = 0; i < test_len; ++i)
297 dma_memcpy(l1inst, sdram, TEST_LEN); 296 sdram[i] = i % 255;
297 dma_memcpy(l1inst, sdram, test_len);
298 298
299 thisret = 0; 299 thisret = 0;
300 for (i = 0; i < TEST_LEN - 32; ++i) { 300 for (i = 0; i < test_len - 32; ++i) {
301 unsigned char cmp[32]; 301 unsigned char cmp[32];
302 for (j = 1; j <= 32; ++j) { 302 for (j = 1; j <= 32; ++j) {
303 memset(cmp, 0, sizeof(cmp)); 303 memset(cmp, 0, sizeof(cmp));
@@ -310,7 +310,7 @@ static __init int isram_memcpy_test(char *sdram, void *l1inst)
310 pr_cont("\n"); 310 pr_cont("\n");
311 if (++thisret > 20) { 311 if (++thisret > 20) {
312 pr_err("FAIL: skipping remaining series\n"); 312 pr_err("FAIL: skipping remaining series\n");
313 i = TEST_LEN; 313 i = test_len;
314 break; 314 break;
315 } 315 }
316 } 316 }
@@ -321,11 +321,11 @@ static __init int isram_memcpy_test(char *sdram, void *l1inst)
321 /* check write of small, unaligned, and hardware 64bit limits */ 321 /* check write of small, unaligned, and hardware 64bit limits */
322 pr_info("INFO: running isram_memcpy (write) tests\n"); 322 pr_info("INFO: running isram_memcpy (write) tests\n");
323 323
324 memset(sdram + TEST_LEN, 0, TEST_LEN); 324 memset(sdram + test_len, 0, test_len);
325 dma_memcpy(l1inst, sdram + TEST_LEN, TEST_LEN); 325 dma_memcpy(l1inst, sdram + test_len, test_len);
326 326
327 thisret = 0; 327 thisret = 0;
328 for (i = 0; i < TEST_LEN - 32; ++i) { 328 for (i = 0; i < test_len - 32; ++i) {
329 unsigned char cmp[32]; 329 unsigned char cmp[32];
330 for (j = 1; j <= 32; ++j) { 330 for (j = 1; j <= 32; ++j) {
331 isram_memcpy(l1inst + i, sdram + i, j); 331 isram_memcpy(l1inst + i, sdram + i, j);
@@ -338,7 +338,7 @@ static __init int isram_memcpy_test(char *sdram, void *l1inst)
338 pr_cont("\n"); 338 pr_cont("\n");
339 if (++thisret > 20) { 339 if (++thisret > 20) {
340 pr_err("FAIL: skipping remaining series\n"); 340 pr_err("FAIL: skipping remaining series\n");
341 i = TEST_LEN; 341 i = test_len;
342 break; 342 break;
343 } 343 }
344 } 344 }
@@ -355,22 +355,30 @@ static __init int isram_test_init(void)
355 char *sdram; 355 char *sdram;
356 void *l1inst; 356 void *l1inst;
357 357
358 sdram = kmalloc(TEST_LEN * 2, GFP_KERNEL); 358 /* Try to test as much of L1SRAM as possible */
359 if (!sdram) { 359 while (test_len) {
360 pr_warning("SKIP: could not allocate sdram\n"); 360 test_len >>= 1;
361 return 0; 361 l1inst = l1_inst_sram_alloc(test_len);
362 if (l1inst)
363 break;
362 } 364 }
363
364 l1inst = l1_inst_sram_alloc(TEST_LEN);
365 if (!l1inst) { 365 if (!l1inst) {
366 kfree(sdram);
367 pr_warning("SKIP: could not allocate L1 inst\n"); 366 pr_warning("SKIP: could not allocate L1 inst\n");
368 return 0; 367 return 0;
369 } 368 }
369 pr_info("INFO: testing %#x bytes (%p - %p)\n",
370 test_len, l1inst, l1inst + test_len);
371
372 sdram = kmalloc(test_len * 2, GFP_KERNEL);
373 if (!sdram) {
374 sram_free(l1inst);
375 pr_warning("SKIP: could not allocate sdram\n");
376 return 0;
377 }
370 378
371 /* sanity check initial L1 inst state */ 379 /* sanity check initial L1 inst state */
372 ret = 1; 380 ret = 1;
373 pr_info("INFO: running initial dma_memcpy checks\n"); 381 pr_info("INFO: running initial dma_memcpy checks %p\n", sdram);
374 if (_isram_memcpy_test(0xa, sdram, l1inst, dma_memcpy)) 382 if (_isram_memcpy_test(0xa, sdram, l1inst, dma_memcpy))
375 goto abort; 383 goto abort;
376 if (_isram_memcpy_test(0x5, sdram, l1inst, dma_memcpy)) 384 if (_isram_memcpy_test(0x5, sdram, l1inst, dma_memcpy))