blob: 51f3b232ef985f98c1d6facc5540ea258b4c4c45 [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0-only */
#include <soc/emi.h>
enum {
/* test patterns */
PATTERN0 = 0x00000000,
PATTERN1 = 0x5A5A5A5A,
PATTERN2 = 0xA5A5A5A5,
PATTERN3 = 0xA5A5A500,
PATTERN4 = 0xA500A500,
PATTERN5 = 0xA5000000,
PATTERN6 = 0xFFFF0000,
PATTERN7 = 0x0000FFFF,
PATTERN8 = 0x00000012,
PATTERN9 = 0x00000034,
PATTERNA = 0x00000056,
PATTERNB = 0x00000078,
PATTERNC = 0x00001234,
PATTERND = 0x00005678,
PATTERNE = 0x12345678,
PATTERNF = 0xFFFFFFFF
};
int complex_mem_test(u8 *start, unsigned int len)
{
unsigned char *mem8_base = (unsigned char *)start;
unsigned short *mem16_base = (unsigned short *)start;
unsigned int *mem32_base = (unsigned int *)start;
unsigned int *mem_base = (unsigned int *)start;
unsigned char pattern8;
unsigned short pattern16;
unsigned int i, j, size, pattern32;
unsigned int value;
uintptr_t p;
size = len >> 2;
/* verify the tied bits (tied high) */
for (i = 0; i < size; i++)
mem32_base[i] = PATTERN0;
for (i = 0; i < size; i++) {
if (mem32_base[i] != PATTERN0)
return -1;
mem32_base[i] = PATTERNF;
}
/* verify the tied bits (tied low) */
for (i = 0; i < size; i++) {
if (mem32_base[i] != PATTERNF)
return -2;
mem32_base[i] = PATTERN0;
}
/* verify pattern 1 (0x00~0xff) */
pattern8 = PATTERN0;
for (i = 0; i < len; i++)
mem8_base[i] = pattern8++;
pattern8 = PATTERN0;
for (i = 0; i < len; i++) {
if (mem8_base[i] != pattern8++)
return -3;
}
/* verify pattern 2 (0x00~0xff) */
pattern8 = PATTERN0;
for (i = j = 0; i < len; i += 2, j++) {
if (mem8_base[i] == pattern8)
mem16_base[j] = pattern8;
if (mem16_base[j] != pattern8)
return -4;
pattern8 += 2;
}
/* verify pattern 3 (0x00~0xffff) */
pattern16 = PATTERN0;
for (i = 0; i < (len >> 1); i++)
mem16_base[i] = pattern16++;
pattern16 = PATTERN0;
for (i = 0; i < (len >> 1); i++) {
if (mem16_base[i] != pattern16++)
return -5;
}
/* verify pattern 4 (0x00~0xffffffff) */
pattern32 = PATTERN0;
for (i = 0; i < (len >> 2); i++)
mem32_base[i] = pattern32++;
pattern32 = PATTERN0;
for (i = 0; i < (len >> 2); i++) {
if (mem32_base[i] != pattern32++)
return -6;
}
/* pattern 5: filling memory range with 0x12345678 */
for (i = 0; i < size; i++)
mem32_base[i] = PATTERNE;
/* read check then fill memory with a5a5a5a5 pattern */
for (i = 0; i < size; i++) {
if (mem32_base[i] != PATTERNE)
return -7;
mem32_base[i] = PATTERN2;
}
/* read check then fill memory with 00 byte pattern at offset 0h */
for (i = 0; i < size; i++) {
if (mem32_base[i] != PATTERN2)
return -8;
mem8_base[i * 4] = PATTERN0;
}
/* read check then fill memory with 00 byte pattern at offset 2h */
for (i = 0; i < size; i++) {
if (mem32_base[i] != PATTERN3)
return -9;
mem8_base[i * 4 + 2] = PATTERN0;
}
/* read check then fill memory with 00 byte pattern at offset 1h */
for (i = 0; i < size; i++) {
if (mem32_base[i] != PATTERN4)
return -10;
mem8_base[i * 4 + 1] = PATTERN0;
}
/* read check then fill memory with 00 byte pattern at offset 3h */
for (i = 0; i < size; i++) {
if (mem32_base[i] != PATTERN5)
return -11;
mem8_base[i * 4 + 3] = PATTERN0;
}
/* read check then fill memory with ffff word pattern at offset 1h */
for (i = 0; i < size; i++) {
if (mem32_base[i] != PATTERN0)
return -12;
mem16_base[i * 2 + 1] = PATTERN7;
}
/* read check then fill memory with ffff word pattern at offset 0h */
for (i = 0; i < size; i++) {
if (mem32_base[i] != PATTERN6)
return -13;
mem16_base[i * 2] = PATTERN7;
}
/* read check */
for (i = 0; i < size; i++) {
if (mem32_base[i] != PATTERNF)
return -14;
}
/* stage 1 => write 0 */
for (i = 0; i < size; i++)
mem_base[i] = PATTERN1;
/* stage 2 => read 0, write 0xf */
for (i = 0; i < size; i++) {
value = mem_base[i];
if (value != PATTERN1)
return -15;
mem_base[i] = PATTERN2;
}
/* stage 3 => read 0xf, write 0 */
for (i = 0; i < size; i++) {
value = mem_base[i];
if (value != PATTERN2)
return -16;
mem_base[i] = PATTERN1;
}
/* stage 4 => read 0, write 0xf */
for (i = 0; i < size; i++) {
value = mem_base[i];
if (value != PATTERN1)
return -17;
mem_base[i] = PATTERN2;
}
/* stage 5 => read 0xf, write 0 */
for (i = 0; i < size; i++) {
value = mem_base[i];
if (value != PATTERN2)
return -18;
mem_base[i] = PATTERN1;
}
/* stage 6 => read 0 */
for (i = 0; i < size; i++) {
value = mem_base[i];
if (value != PATTERN1)
return -19;
}
/* 1/2/4-byte combination test */
p = (uintptr_t)mem_base;
while (p < (uintptr_t)mem_base + (size << 2)) {
*((unsigned char *)p) = PATTERNB;
p += 1;
*((unsigned char *)p) = PATTERNA;
p += 1;
*((unsigned short *)p) = PATTERNC;
p += 2;
*((unsigned int *)p) = PATTERNE;
p += 4;
*((unsigned short *)p) = PATTERND;
p += 2;
*((unsigned char *)p) = PATTERN9;
p += 1;
*((unsigned char *)p) = PATTERN8;
p += 1;
*((unsigned int *)p) = PATTERNE;
p += 4;
*((unsigned char *)p) = PATTERNB;
p += 1;
*((unsigned char *)p) = PATTERNA;
p += 1;
*((unsigned short *)p) = PATTERNC;
p += 2;
*((unsigned int *)p) = PATTERNE;
p += 4;
*((unsigned short *)p) = PATTERND;
p += 2;
*((unsigned char *)p) = PATTERN9;
p += 1;
*((unsigned char *)p) = PATTERN8;
p += 1;
*((unsigned int *)p) = PATTERNE;
p += 4;
}
for (i = 0; i < size; i++) {
value = mem_base[i];
if (value != PATTERNE)
return -20;
}
/* verify pattern 1 (0x00~0xff) */
pattern8 = PATTERN0;
mem8_base[0] = pattern8;
for (i = 0; i < size * 4; i++) {
unsigned char waddr8, raddr8;
waddr8 = i + 1;
raddr8 = i;
if (i < size * 4 - 1)
mem8_base[waddr8] = pattern8 + 1;
if (mem8_base[raddr8] != pattern8)
return -21;
pattern8++;
}
/* verify pattern 2 (0x00~0xffff) */
pattern16 = PATTERN0;
mem16_base[0] = pattern16;
for (i = 0; i < size * 2; i++) {
if (i < size * 2 - 1)
mem16_base[i + 1] = pattern16 + 1;
if (mem16_base[i] != pattern16)
return -22;
pattern16++;
}
/* verify pattern 3 (0x00~0xffffffff) */
pattern32 = PATTERN0;
mem32_base[0] = pattern32;
for (i = 0; i < size; i++) {
if (i < size - 1)
mem32_base[i + 1] = pattern32 + 1;
if (mem32_base[i] != pattern32)
return -23;
pattern32++;
}
return 0;
}