diff options
Diffstat (limited to 'arch/blackfin/mm/isram-driver.c')
-rw-r--r-- | arch/blackfin/mm/isram-driver.c | 94 |
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 | 198 | static int test_len = 0x20000; |
200 | 199 | ||
201 | static __init void hex_dump(unsigned char *buf, int len) | 200 | static __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)) |