obj-y += timer.o io.o devices.o iomux.o clock.o rk29-pl330.o dma.o gpio.o ddr.o sram.o memcpy_dma.o reset.o
+obj-y += tests.o memtester.o
obj-y += early_printk.o
ifndef CONFIG_DEBUG_LL
obj-y += ../kernel/debug.o
#include <asm/io.h>
-#define ddr_print(x...) printk( "ddr init: " x )
+#define ddr_print(x...) printk( "DDR DEBUG: " x )
// save_sp must be static global variable
pDDR_Reg->CCR |= HOSTEN; //enable host port
}
-void __sramfunc ddr_change_freq(uint32_t nMHz)
+uint32_t __sramfunc ddr_change_freq(uint32_t nMHz)
{
uint32_t ret;
volatile u32 n;
DDR_RESTORE_SP(save_sp);
local_irq_restore(flags);
+ return ret;
//ddr_print("%s exit\n", __func__);
}
void __sramfunc ddr_suspend(void)
if((mem_type == DDRII) || (mem_type == DDR3))
{
- pDDR_Reg->ALPMR = LPPERIOD_POWER_DOWN(0xFF);// | AUTOPD;
+ pDDR_Reg->ALPMR = LPPERIOD_POWER_DOWN(0xFF) | AUTOPD;
}
else
{
Hz = clk_get_rate(clk_get(NULL,"ddr"));
MHz = Hz/1000000;
- ddr_change_freq(MHz);
- ddr_print("ddr pll freq=%dMHz\n", MHz);
-
- return 0;
+ value = ddr_change_freq(MHz);
+ ddr_print("init success!!! freq=%dMHz\n", value);
+ return 0;
}
core_initcall_sync(ddr_probe);
--- /dev/null
+/*
+ * Very simple (yet, for some reason, very effective) memory tester.
+ * Originally by Simon Kirby <sim@stormix.com> <sim@neato.org>
+ * Version 2 by Charles Cazabon <charlesc-memtester@pyropus.ca>
+ * Version 3 not publicly released.
+ * Version 4 rewrite:
+ * Copyright (C) 2007-2009 Charles Cazabon <charlesc-memtester@pyropus.ca>
+ * Licensed under the terms of the GNU General Public License version 2 (only).
+ * See the file COPYING for details.
+ *
+ * This file contains the declarations for external variables from the main file.
+ * See other comments in that file.
+ *
+ */
+
+
+/* extern declarations. */
+
+extern void memtester(void);
\ No newline at end of file
--- /dev/null
+/*
+ * memtester version 4
+ *
+ * Very simple but very effective user-space memory tester.
+ * Originally by Simon Kirby <sim@stormix.com> <sim@neato.org>
+ * Version 2 by Charles Cazabon <charlesc-memtester@pyropus.ca>
+ * Version 3 not publicly released.
+ * Version 4 rewrite:
+ * Copyright (C) 2007-2009 Charles Cazabon <charlesc-memtester@pyropus.ca>
+ * Licensed under the terms of the GNU General Public License version 2 (only).
+ * See the file COPYING for details.
+ *
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include "tests.h"
+
+
+#define EXIT_FAIL_NONSTARTER 0x01
+#define EXIT_FAIL_ADDRESSLINES 0x02
+#define EXIT_FAIL_OTHERTEST 0x04
+
+//#pragma arm section rwdata="DDR"
+useful_data_t useful_data={(2*1024*1024), 133, 333};
+//#pragma arm section
+
+struct test tests[17]
+= {
+ #ifdef TEST_RANDOM
+ { "Random Value", test_random_value },
+ #endif
+ #ifdef TEST_XOR
+ { "Compare XOR", test_xor_comparison },
+ #endif
+ #ifdef TEST_SUB
+ { "Compare SUB", test_sub_comparison },
+ #endif
+ #ifdef TEST_MUL
+ { "Compare MUL", test_mul_comparison },
+ #endif
+ #ifdef TEST_DIV
+ { "Compare DIV",test_div_comparison },
+ #endif
+ #ifdef TEST_OR
+ { "Compare OR", test_or_comparison },
+ #endif
+ #ifdef TEST_AND
+ { "Compare AND", test_and_comparison },
+ #endif
+ #ifdef TEST_SEQINC
+ { "Sequential Increment", test_seqinc_comparison },
+ #endif
+ #ifdef TEST_SOLID_BIT
+ { "Solid Bits", test_solidbits_comparison },
+ #endif
+ #ifdef TEST_BLOCK_SEQ
+ { "Block Sequential", test_blockseq_comparison },
+ #endif
+ #ifdef TEST_CHECK_BOARD
+ { "Checkerboard", test_checkerboard_comparison },
+ #endif
+ #ifdef TEST_BIT_SPREAD
+ { "Bit Spread", test_bitspread_comparison },
+ #endif
+ #ifdef TEST_BIT_FLIP
+ { "Bit Flip", test_bitflip_comparison },
+ #endif
+ #ifdef TEST_ONE
+ { "Walking Ones", test_walkbits1_comparison },
+ #endif
+ #ifdef TEST_ZERO
+ { "Walking Zeroes", test_walkbits0_comparison },
+ #endif
+ { NULL, NULL }
+};
+
+int exit_code = 0;
+
+int memtester(void) {
+ ul loops, loop, i;
+ size_t pagesize, wantraw, wantmb, wantbytes, wantbytes_orig, bufsize,
+ halflen, count;
+ ptrdiff_t pagesizemask;
+ void volatile *buf, *aligned;
+ ulv *bufa, *bufb;
+ int memshift;
+ ul cap;
+
+
+
+ print("Copyright (C) 2009 Charles Cazabon.\n");
+ print("Licensed under the GNU General Public License version 2 (only).\n");
+ print("\n");
+ pagesize = 1024;
+ pagesizemask = (ptrdiff_t) ~(pagesize - 1);
+ print("pagesizemask is 0x");
+ print_Hex(pagesizemask);
+ print("\n");
+
+ if(useful_data.testCap == 0xFFFFFFFF)
+ {
+ cap = 0x800000 << (((pDDR_Reg->DCR >> 4) & 0x7)
+ + ((((pDDR_Reg->DCR >> 7) & 0x7)+1) >> ((pDDR_Reg->DCR >> 2) & 0x3))
+ + ((pDDR_Reg->DCR >> 11) & 0x3));
+ }
+ else if(useful_data.testCap == 0)
+ {
+ cap = (0x1 << 20);
+ }
+ else
+ {
+ cap = useful_data.testCap;
+ }
+
+ wantraw = cap>>20;
+ memshift = 20; /* megabytes */
+
+ wantbytes_orig = wantbytes = ((size_t) wantraw << memshift);
+ wantmb = (wantbytes_orig >> 20);
+
+ loops = 10;
+
+ print("want ");
+ print_Dec((ull) wantmb);
+ print("MB (");
+ print_Dec((ull) wantbytes);
+ print(" bytes)\n");
+ buf = NULL;
+
+ buf = (void volatile *) kmalloc(wantbytes, GFP_KERNEL);
+ // buf = (void volatile *)0x60000000;
+ bufsize = wantbytes;
+ aligned = buf;
+
+ halflen = bufsize / 2;
+ count = halflen / sizeof(ul);
+ bufa = (ulv *) aligned;
+ bufb = (ulv *) ((size_t) aligned + halflen);
+
+ for(loop=1; ((!loops) || loop <= loops); loop++) {
+ print("Loop ");
+ print_Dec(loop);
+ //if (loops) {
+ // print_Dec(loops);
+ //}
+ print(":\n");
+ print(" Stuck Address: ");
+ if (!test_stuck_address(aligned, bufsize / sizeof(ul))) {
+ print("ok\n");
+ } else {
+ exit_code |= EXIT_FAIL_ADDRESSLINES;
+ goto error;
+ }
+ for (i=0;;i++) {
+ if (!tests[i].name) break;
+ print(" ");
+ print(tests[i].name);
+ print(": ");
+ if (!tests[i].fp(bufa, bufb, count)) {
+ print("ok\n");
+ } else {
+ exit_code |= EXIT_FAIL_OTHERTEST;
+ goto error;
+ }
+ }
+ print("\n");
+ }
+ kfree((const void *)buf);
+ print("Done.\n");
+ return 0;
+error:
+ print("failed\n");
+ return 1;
+}
#include <mach/sram.h>
#include <mach/gpio.h>
#include <mach/ddr.h>
+#include <mach/memtester.h>
#define cru_readl(offset) readl(RK29_CRU_BASE + offset)
#define cru_writel(v, offset) do { writel(v, RK29_CRU_BASE + offset); readl(RK29_CRU_BASE + offset); } while (0)
printch('\r');
}
-static void inline printascii(const char *s)
+static void __sramfunc printascii(const char *s)
{
while (*s) {
- printch(*s);
- s++;
+ if (*s == '\n')
+ {
+ printch('\r');
+ }
+ printch(*s);
+ s++;
+ }
+}
+void print(const char *s)
+{
+ printascii(s);
+}
+
+void __sramfunc print_Hex(unsigned int hex)
+{
+ int i = 8;
+ printch('0');
+ printch('x');
+ while (i--) {
+ unsigned char c = (hex & 0xF0000000) >> 28;
+ printch(c < 0xa ? c + '0' : c - 0xa + 'a');
+ hex <<= 4;
}
}
+void __sramfunc print_Dec (uint32_t n)
+{
+ if (n >= 10)
+ {
+ print_Dec(n / 10);
+ n %= 10;
+ }
+ printch((char)(n + '0'));
+}
+
+void print_Dec_3(uint32_t value)
+{
+ if(value<10)
+ {
+ print(" ");
+ }
+ else if(value<100)
+ {
+ print(" ");
+ }
+ else
+ {
+ }
+ print_Dec(value);
+}
+
static void /* inline*/ __sramfunc printhex(unsigned int hex)
{
int i = 8;
// printascii("self refresh success\n");
}
}
-
+ else if(ddr_debug == 3)
+ {
+ memtester();
+ }
}
#else
void __sramfunc ddr_testmode(void)
{
u32 clksel0;
- if(ddr_debug)
+ if((ddr_debug == 1)||(ddr_debug == 2))
ddr_testmode();
printch('5');
ddr_suspend();
{
u32 apll, cpll, gpll, mode, clksel0;
u32 clkgate[4];
+
+ // memory teseter
+ if(ddr_debug == 3)
+ ddr_testmode();
+
printch('0');
#ifdef CONFIG_RK29_PWM_REGULATOR
--- /dev/null
+/*
+ * Very simple but very effective user-space memory tester.
+ * Originally by Simon Kirby <sim@stormix.com> <sim@neato.org>
+ * Version 2 by Charles Cazabon <charlesc-memtester@pyropus.ca>
+ * Version 3 not publicly released.
+ * Version 4 rewrite:
+ * Copyright (C) 2007-2009 Charles Cazabon <charlesc-memtester@pyropus.ca>
+ * Licensed under the terms of the GNU General Public License version 2 (only).
+ * See the file COPYING for details.
+ *
+ * This file contains the functions for the actual tests, called from the
+ * main routine in memtester.c. See other comments in that file.
+ *
+ */
+
+#include "tests.h"
+
+char progress[] = "-\\|/";
+#define PROGRESSLEN 4
+#define PROGRESSOFTEN 2500
+
+int compare_regions(ulv *bufa, ulv *bufb, size_t count) {
+ int r = 0;
+ size_t i;
+ ulv *p1 = bufa;
+ ulv *p2 = bufb;
+ int n=0;
+
+ for (i = 0; i < count; i++, p1++, p2++) {
+ if (*p1 != *p2) {
+ {
+ print("FAILURE: 0x");
+ print_Hex((ul) *p1);
+ print(" != 0x");
+ print_Hex((ul) *p2);
+ print(" at offset 0x");
+ print_Hex((ul) i);
+ print(".\n");
+ }
+ /* printf("Skipping to next test..."); */
+ r = -1;
+ n++;
+ if(n>10)
+ {
+ break;
+ }
+ }
+ }
+ return r;
+}
+
+int compare_regions_reverse(ulv *bufa, ulv *bufb, size_t count) {
+ int r = 0;
+ size_t i;
+ ulv *p1 = bufa;
+ ulv *p2 = bufb;
+ int n=0;
+
+ for (i = 0; i < count; i++, p1++, p2++) {
+ if (*p1 != ~(*p2)) {
+ {
+ print("FAILURE: 0x");
+ print_Hex((ul) *p1);
+ print(" != 0x");
+ print_Hex((ul) *p2);
+ print(" at offset 0x");
+ print_Hex((ul) i);
+ print(".\n");
+ }
+ /* printf("Skipping to next test..."); */
+ r = -1;
+ n++;
+ if(n>10)
+ {
+ break;
+ }
+ }
+ }
+ return r;
+}
+
+int test_stuck_address(ulv *bufa, size_t count) {
+ ulv *p1 = bufa;
+ unsigned int j;
+ size_t i;
+
+ print(" ");
+ for (j = 0; j < 16; j++) {
+ print("\b\b\b\b\b\b\b\b\b\b\b");
+ p1 = (ulv *) bufa;
+ print("setting ");
+ print_Dec_3(j);
+ for (i = 0; i < count; i++) {
+ *p1 = ((j + i) % 2) == 0 ? (ul) p1 : ~((ul) p1);
+ *p1++;
+ }
+ print("\b\b\b\b\b\b\b\b\b\b\b");
+ print("testing ");
+ print_Dec_3(j);
+ p1 = (ulv *) bufa;
+ for (i = 0; i < count; i++, p1++) {
+ if (*p1 != (((j + i) % 2) == 0 ? (ul) p1 : ~((ul) p1))) {
+ {
+ print("FAILURE: possible bad address line at offset 0x");
+ print_Hex((ul) i);
+ print(".\n");
+ }
+ print("Skipping to next test...\n");
+ return -1;
+ }
+ }
+ }
+ print("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b");
+ return 0;
+}
+
+#ifdef TEST_RANDOM
+int test_random_value(ulv *bufa, ulv *bufb, size_t count) {
+ ulv *p1 = bufa;
+ ulv *p2 = bufb;
+ size_t i;
+
+ for (i = 0; i < count; i++) {
+ *p1++ = *p2++ = rand_ul();
+ if (!(i % PROGRESSOFTEN)) {
+ }
+ }
+ print("\b \b");
+ return compare_regions(bufa, bufb, count);
+}
+#endif
+
+#ifdef TEST_XOR
+int test_xor_comparison(ulv *bufa, ulv *bufb, size_t count) {
+ ulv *p1 = bufa;
+ ulv *p2 = bufb;
+ size_t i;
+ ul q = rand_ul();
+
+ for (i = 0; i < count; i++) {
+ *p1++ ^= q;
+ *p2++ ^= q;
+ }
+ return compare_regions(bufa, bufb, count);
+}
+#endif
+
+#ifdef TEST_SUB
+int test_sub_comparison(ulv *bufa, ulv *bufb, size_t count) {
+ ulv *p1 = bufa;
+ ulv *p2 = bufb;
+ size_t i;
+ ul q = rand_ul();
+
+ for (i = 0; i < count; i++) {
+ *p1++ -= q;
+ *p2++ -= q;
+ }
+ return compare_regions(bufa, bufb, count);
+}
+#endif
+
+#ifdef TEST_MUL
+int test_mul_comparison(ulv *bufa, ulv *bufb, size_t count) {
+ ulv *p1 = bufa;
+ ulv *p2 = bufb;
+ size_t i;
+ ul q = rand_ul();
+
+ for (i = 0; i < count; i++) {
+ *p1++ *= q;
+ *p2++ *= q;
+ }
+ return compare_regions(bufa, bufb, count);
+}
+#endif
+
+#ifdef TEST_DIV
+int test_div_comparison(ulv *bufa, ulv *bufb, size_t count) {
+ ulv *p1 = bufa;
+ ulv *p2 = bufb;
+ size_t i;
+ ul q = rand_ul();
+
+ for (i = 0; i < count; i++) {
+ if (!q) {
+ q++;
+ }
+ *p1++ /= q;
+ *p2++ /= q;
+ }
+ return compare_regions(bufa, bufb, count);
+}
+#endif
+
+#ifdef TEST_OR
+int test_or_comparison(ulv *bufa, ulv *bufb, size_t count) {
+ ulv *p1 = bufa;
+ ulv *p2 = bufb;
+ size_t i;
+ ul q = rand_ul();
+
+ for (i = 0; i < count; i++) {
+ *p1++ |= q;
+ *p2++ |= q;
+ }
+ return compare_regions(bufa, bufb, count);
+}
+#endif
+
+#ifdef TEST_AND
+int test_and_comparison(ulv *bufa, ulv *bufb, size_t count) {
+ ulv *p1 = bufa;
+ ulv *p2 = bufb;
+ size_t i;
+ ul q = rand_ul();
+
+ for (i = 0; i < count; i++) {
+ *p1++ &= q;
+ *p2++ &= q;
+ }
+ return compare_regions(bufa, bufb, count);
+}
+#endif
+
+#ifdef TEST_SEQINC
+int test_seqinc_comparison(ulv *bufa, ulv *bufb, size_t count) {
+ ulv *p1 = bufa;
+ ulv *p2 = bufb;
+ size_t i;
+ ul q = rand_ul();
+ ul value;
+
+ for (i = 0; i < count; i++) {
+ value = (i+q);
+ *p1++ = value;
+ *p2++ = ~value;
+ //*p1++ = *p2++ = (i + q);
+ }
+ return compare_regions_reverse(bufa, bufb, count);
+}
+#endif
+
+#ifdef TEST_SOLID_BIT
+int test_solidbits_comparison(ulv *bufa, ulv *bufb, size_t count) {
+ ulv *p1 = bufa;
+ ulv *p2 = bufb;
+ unsigned int j;
+ ul q;
+ size_t i;
+ ul value;
+
+ print(" ");
+ for (j = 0; j < 64; j++) {
+ print("\b\b\b\b\b\b\b\b\b\b\b");
+ q = (j % 2) == 0 ? UL_ONEBITS : 0;
+ print("setting ");
+ print_Dec_3(j);
+ p1 = (ulv *) bufa;
+ p2 = (ulv *) bufb;
+ for (i = 0; i < count; i++) {
+ value = (i % 2) == 0 ? q : ~q;
+ *p1++ = value;
+ *p2++ = ~value;
+ //*p1++ = *p2++ = (i % 2) == 0 ? q : ~q;
+ }
+ print("\b\b\b\b\b\b\b\b\b\b\b");
+ print("testing ");
+ print_Dec_3(j);
+ if (compare_regions_reverse(bufa, bufb, count)) {
+ return -1;
+ }
+ }
+ print("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b");
+ return 0;
+}
+#endif
+
+#ifdef TEST_CHECK_BOARD
+int test_checkerboard_comparison(ulv *bufa, ulv *bufb, size_t count) {
+ ulv *p1 = bufa;
+ ulv *p2 = bufb;
+ unsigned int j;
+ ul q;
+ size_t i;
+ ul value;
+
+ print(" ");
+ for (j = 0; j < 64; j++) {
+ print("\b\b\b\b\b\b\b\b\b\b\b");
+ q = (j % 2) == 0 ? CHECKERBOARD1 : CHECKERBOARD2;
+ print("setting ");
+ print_Dec_3(j);
+ p1 = (ulv *) bufa;
+ p2 = (ulv *) bufb;
+ for (i = 0; i < count; i++) {
+ value = (i % 2) == 0 ? q : ~q;
+ *p1++ = value;
+ *p2++ = ~value;
+ //*p1++ = *p2++ = (i % 2) == 0 ? q : ~q;
+ }
+ print("\b\b\b\b\b\b\b\b\b\b\b");
+ print("testing ");
+ print_Dec_3(j);
+ if (compare_regions_reverse(bufa, bufb, count)) {
+ return -1;
+ }
+ }
+ print("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b");
+ return 0;
+}
+#endif
+
+#ifdef TEST_BLOCK_SEQ
+int test_blockseq_comparison(ulv *bufa, ulv *bufb, size_t count) {
+ ulv *p1 = bufa;
+ ulv *p2 = bufb;
+ unsigned int j;
+ size_t i;
+ ul value;
+
+ print(" ");
+ for (j = 0; j < 256; j++) {
+ print("\b\b\b\b\b\b\b\b\b\b\b");
+ p1 = (ulv *) bufa;
+ p2 = (ulv *) bufb;
+ print("setting ");
+ print_Dec_3(j);
+ for (i = 0; i < count; i++) {
+ value = (ul) UL_BYTE(j);
+ *p1++ = value;
+ *p2++ = ~value;
+ //*p1++ = *p2++ = (ul) UL_BYTE(j);
+ }
+ print("\b\b\b\b\b\b\b\b\b\b\b");
+ print("testing ");
+ print_Dec_3(j);
+ if (compare_regions_reverse(bufa, bufb, count)) {
+ return -1;
+ }
+ }
+ print("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b");
+ return 0;
+}
+#endif
+
+#ifdef TEST_ZERO
+int test_walkbits0_comparison(ulv *bufa, ulv *bufb, size_t count) {
+ ulv *p1 = bufa;
+ ulv *p2 = bufb;
+ unsigned int j;
+ size_t i;
+ ul value;
+
+ print(" ");
+ for (j = 0; j < UL_LEN * 2; j++) {
+ print("\b\b\b\b\b\b\b\b\b\b\b");
+ p1 = (ulv *) bufa;
+ p2 = (ulv *) bufb;
+ print("setting ");
+ print_Dec_3(j);
+ for (i = 0; i < count; i++) {
+ if (j < UL_LEN) { /* Walk it up. */
+ //*p1++ = *p2++ = 0x00000001 << j;
+ value = 0x00000001 << j;
+ *p1++ = value;
+ *p2++ = ~value;
+ } else { /* Walk it back down. */
+ //*p1++ = *p2++ = 0x00000001 << (UL_LEN * 2 - j - 1);
+ value = 0x00000001 << (UL_LEN * 2 - j - 1);
+ *p1++ = value;
+ *p2++ = ~value;
+ }
+ }
+ print("\b\b\b\b\b\b\b\b\b\b\b");
+ print("testing ");
+ print_Dec_3(j);
+ if (compare_regions_reverse(bufa, bufb, count)) {
+ return -1;
+ }
+ }
+ print("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b");
+ return 0;
+}
+#endif
+
+#ifdef TEST_ONE
+int test_walkbits1_comparison(ulv *bufa, ulv *bufb, size_t count) {
+ ulv *p1 = bufa;
+ ulv *p2 = bufb;
+ unsigned int j;
+ size_t i;
+ ul value;
+
+ print(" ");
+ for (j = 0; j < UL_LEN * 2; j++) {
+ print("\b\b\b\b\b\b\b\b\b\b\b");
+ p1 = (ulv *) bufa;
+ p2 = (ulv *) bufb;
+ print("setting ");
+ print_Dec_3(j);
+ for (i = 0; i < count; i++) {
+ if (j < UL_LEN) { /* Walk it up. */
+ //*p1++ = *p2++ = UL_ONEBITS ^ (0x00000001 << j);
+ value = UL_ONEBITS ^ (0x00000001 << j);
+ *p1++ = value;
+ *p2++ = ~value;
+ } else { /* Walk it back down. */
+ //*p1++ = *p2++ = UL_ONEBITS ^ (0x00000001 << (UL_LEN * 2 - j - 1));
+ value = UL_ONEBITS ^ (0x00000001 << (UL_LEN * 2 - j - 1));
+ *p1++ = value;
+ *p2++ = ~value;
+ }
+ }
+ print("\b\b\b\b\b\b\b\b\b\b\b");
+ print("testing ");
+ print_Dec_3(j);
+ if (compare_regions_reverse(bufa, bufb, count)) {
+ return -1;
+ }
+ }
+ print("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b");
+ return 0;
+}
+#endif
+
+#ifdef TEST_BIT_SPREAD
+int test_bitspread_comparison(ulv *bufa, ulv *bufb, size_t count) {
+ ulv *p1 = bufa;
+ ulv *p2 = bufb;
+ unsigned int j;
+ size_t i;
+ ul value;
+
+ print(" ");
+ for (j = 0; j < UL_LEN * 2; j++) {
+ print("\b\b\b\b\b\b\b\b\b\b\b");
+ p1 = (ulv *) bufa;
+ p2 = (ulv *) bufb;
+ print("setting ");
+ print_Dec_3(j);
+ for (i = 0; i < count; i++) {
+ if (j < UL_LEN) { /* Walk it up. */
+ //*p1++ = *p2++ = (i % 2 == 0)
+ // ? (0x00000001 << j) | (0x00000001 << (j + 2))
+ // : UL_ONEBITS ^ ((0x00000001 << j)
+ // | (0x00000001 << (j + 2)));
+ value = (i % 2 == 0)
+ ? (0x00000001 << j) | (0x00000001 << (j + 2))
+ : UL_ONEBITS ^ ((0x00000001 << j)
+ | (0x00000001 << (j + 2)));
+ *p1++ = value;
+ *p2++ = ~value;
+ } else { /* Walk it back down. */
+ //*p1++ = *p2++ = (i % 2 == 0)
+ // ? (0x00000001 << (UL_LEN * 2 - 1 - j)) | (0x00000001 << (UL_LEN * 2 + 1 - j))
+ // : UL_ONEBITS ^ (0x00000001 << (UL_LEN * 2 - 1 - j)
+ // | (0x00000001 << (UL_LEN * 2 + 1 - j)));
+ value = (i % 2 == 0)
+ ? (0x00000001 << (UL_LEN * 2 - 1 - j)) | (0x00000001 << (UL_LEN * 2 + 1 - j))
+ : UL_ONEBITS ^ (0x00000001 << (UL_LEN * 2 - 1 - j)
+ | (0x00000001 << (UL_LEN * 2 + 1 - j)));
+ *p1++ = value;
+ *p2++ = ~value;
+ }
+ }
+ print("\b\b\b\b\b\b\b\b\b\b\b");
+ print("testing ");
+ print_Dec_3(j);
+ if (compare_regions_reverse(bufa, bufb, count)) {
+ return -1;
+ }
+ }
+ print("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b");
+ return 0;
+}
+#endif
+
+#ifdef TEST_BIT_FLIP
+int test_bitflip_comparison(ulv *bufa, ulv *bufb, size_t count) {
+ ulv *p1 = bufa;
+ ulv *p2 = bufb;
+ unsigned int j, k;
+ ul q;
+ size_t i;
+ ul value;
+
+ print(" ");
+ for (k = 0; k < UL_LEN; k++) {
+ q = 0x00000001 << k;
+ for (j = 0; j < 8; j++) {
+ print("\b\b\b\b\b\b\b\b\b\b\b");
+ q = ~q;
+ print("setting ");
+ print_Dec_3(k * 8 + j);
+ p1 = (ulv *) bufa;
+ p2 = (ulv *) bufb;
+ for (i = 0; i < count; i++) {
+ //*p1++ = *p2++ = (i % 2) == 0 ? q : ~q;
+ value = (i % 2) == 0 ? q : ~q;
+ *p1++ = value;
+ *p2++ = ~value;
+ }
+ print("\b\b\b\b\b\b\b\b\b\b\b");
+ print("testing ");
+ print_Dec_3(k * 8 + j);
+ if (compare_regions_reverse(bufa, bufb, count)) {
+ return -1;
+ }
+ }
+ }
+ print("\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b");
+ return 0;
+}
+#endif
--- /dev/null
+/*
+ * Very simple yet very effective memory tester.
+ * Originally by Simon Kirby <sim@stormix.com> <sim@neato.org>
+ * Version 2 by Charles Cazabon <charlesc-memtester@pyropus.ca>
+ * Version 3 not publicly released.
+ * Version 4 rewrite:
+ * Copyright (C) 2007-2009 Charles Cazabon <charlesc-memtester@pyropus.ca>
+ * Licensed under the terms of the GNU General Public License version 2 (only).
+ * See the file COPYING for details.
+ *
+ * This file contains the declarations for the functions for the actual tests,
+ * called from the main routine in memtester.c. See other comments in that
+ * file.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <mach/rk29_iomap.h>
+
+#include <linux/random.h>
+
+//#if (ULONG_MAX == 4294967295UL)
+#if 1
+ #define rand_ul() random32()
+ #define UL_ONEBITS 0xffffffff
+ #define UL_LEN 32
+ #define CHECKERBOARD1 0x55555555
+ #define CHECKERBOARD2 0xaaaaaaaa
+ #define UL_BYTE(x) ((x | x << 8 | x << 16 | x << 24))
+#elif (ULONG_MAX == 18446744073709551615ULL)
+ #define rand64() (((ul) rand32()) << 32 | ((ul) rand32()))
+ #define rand_ul() rand64()
+ #define UL_ONEBITS 0xffffffffffffffffUL
+ #define UL_LEN 64
+ #define CHECKERBOARD1 0x5555555555555555
+ #define CHECKERBOARD2 0xaaaaaaaaaaaaaaaa
+ #define UL_BYTE(x) (((ul)x | (ul)x<<8 | (ul)x<<16 | (ul)x<<24 | (ul)x<<32 | (ul)x<<40 | (ul)x<<48 | (ul)x<<56))
+#else
+ #error long on this platform is not 32 or 64 bits
+#endif
+
+#define TEST_ALL
+
+#ifdef TEST_ALL // TEST_ALLµÄʱºòÕâЩ¶¼²»¶¯
+#define TEST_RANDOM
+#define TEST_XOR
+#define TEST_SUB
+#define TEST_MUL
+#define TEST_DIV
+#define TEST_OR
+#define TEST_AND
+#define TEST_SEQINC
+#define TEST_SOLID_BIT
+#define TEST_BLOCK_SEQ
+#define TEST_CHECK_BOARD
+#define TEST_BIT_SPREAD
+#define TEST_BIT_FLIP
+#define TEST_ONE
+#define TEST_ZERO
+#else //ÕâЩÅäÖÃÓÃÓÚÔöɾ
+//#define TEST_RANDOM
+//#define TEST_XOR
+//#define TEST_SUB
+//#define TEST_MUL
+//#define TEST_DIV
+//#define TEST_OR
+//#define TEST_AND
+//#define TEST_SEQINC
+//#define TEST_SOLID_BIT
+//#define TEST_BLOCK_SEQ
+//#define TEST_CHECK_BOARD
+//#define TEST_BIT_SPREAD
+#define TEST_BIT_FLIP
+//#define TEST_ONE
+//#define TEST_ZERO
+#endif
+
+
+typedef unsigned long ul;
+typedef unsigned long long ull;
+typedef unsigned long volatile ulv;
+/* DDR Controller register struct */
+typedef volatile struct DDR_REG_Tag
+{
+ volatile unsigned int CCR; //Controller Configuration Register
+ volatile unsigned int DCR; //DRAM Configuration Register
+ volatile unsigned int IOCR; //IO Configuration Register
+ volatile unsigned int CSR; //Controller Status Register
+ volatile unsigned int DRR; //DRAM Refresh Register
+ volatile unsigned int TPR[3]; //SDRAM Timing Parameters Registers
+ volatile unsigned int DLLCR; //Global DLL Control Register
+ volatile unsigned int DLLCR09[10]; //DDR Control Register 0-9
+ volatile unsigned int RSLR[4]; //Rank System Latency Register 0-3
+ volatile unsigned int RDGR[4]; //Rank DQS Gating Register 0-3
+ volatile unsigned int DQTR[9]; //DQ Timing Register 0-8
+ volatile unsigned int DQSTR; //DQS Timing Register
+ volatile unsigned int DQSBTR; //DQS_b Timing Register
+ volatile unsigned int ODTCR; //ODT Configuration Register
+ volatile unsigned int DTR[2]; //Data Training Register 0-1
+ volatile unsigned int DTAR; //Data Training Address Register
+ volatile unsigned int ZQCR[3]; //SDRAM ZQ Control Register and SDRAM ZQCS Control Register 0-2
+ volatile unsigned int ZQSR; //SDRAM ZQ Status Register
+ volatile unsigned int TPR3; //SDRAM Timing Parameters Register 3
+ volatile unsigned int ALPMR; //Automatic Low Power Mode Register
+ volatile unsigned int Reserved[0x7c-0x30];
+ volatile unsigned int MR; //Mode Register
+ volatile unsigned int EMR; //Extended Mode Register
+ volatile unsigned int EMR2; //Extended Mode Register 2
+ volatile unsigned int EMR3; //Extended Mode Register 3
+ //Memory Management Unit Registers
+ volatile unsigned int HPCR[32]; //Host Port Configuration Register 0-31
+ volatile unsigned int PQCR[8]; //Priority Queue Configuration Register 0-7
+ volatile unsigned int MMGCR; //Memory Manager General Configuration Register
+}DDR_REG_T, *pDDR_REG_T;
+
+typedef struct tagGPIO_IOMUX
+{
+ volatile unsigned int GPIOL_IOMUX;
+ volatile unsigned int GPIOH_IOMUX;
+}GPIO_IOMUX_T;
+
+//GRF Registers
+typedef volatile struct tagREG_FILE
+{
+ volatile unsigned int GRF_GPIO_DIR[6];
+ volatile unsigned int GRF_GPIO_DO[6];
+ volatile unsigned int GRF_GPIO_EN[6];
+ GPIO_IOMUX_T GRF_GPIO_IOMUX[6];
+ volatile unsigned int GRF_GPIO_PULL[7];
+ volatile unsigned int GRF_UOC_CON[2];
+ volatile unsigned int GRF_USB_CON;
+ volatile unsigned int GRF_CPU_CON[2];
+ volatile unsigned int GRF_CPU_STATUS;
+ volatile unsigned int GRF_MEM_CON;
+ volatile unsigned int GRF_MEM_STATUS[3];
+ volatile unsigned int GRF_SOC_CON[5];
+ volatile unsigned int GRF_OS_REG[4];
+} REG_FILE, *pREG_FILE;
+
+//CRU Registers
+typedef volatile struct tagCRU_REG
+{
+ volatile unsigned int CRU_APLL_CON;
+ volatile unsigned int CRU_DPLL_CON;
+ volatile unsigned int CRU_CPLL_CON;
+ volatile unsigned int CRU_PPLL_CON;
+ volatile unsigned int CRU_MODE_CON;
+ volatile unsigned int CRU_CLKSEL_CON[18];
+ volatile unsigned int CRU_CLKGATE_CON[4];
+ volatile unsigned int CRU_SOFTRST_CON[3];
+} CRU_REG, *pCRU_REG;
+
+#define pDDR_Reg ((pDDR_REG_T)RK29_DDRC_BASE)
+#define pGRF_Reg ((pREG_FILE)RK29_GRF_BASE)
+#define pSCU_Reg ((pCRU_REG)RK29_CRU_BASE)
+
+struct test
+{
+ char *name;
+ int (*fp)(ulv *bufa, ulv *bufb, size_t count);
+};
+
+typedef struct useful_data_tag
+{
+ unsigned int testCap; //²âÊÔµÄÈÝÁ¿
+ unsigned int WriteFreq;
+ unsigned int ReadFreq;
+}useful_data_t;
+extern void printascii(const char *s);
+extern void print_Dec(unsigned int n);
+extern void print_Hex(unsigned int hex);
+extern void print(const char *s);
+extern void print_Dec_3(unsigned int value);
+
+
+/* Function declaration. */
+
+int test_stuck_address(unsigned long volatile *bufa, size_t count);
+int test_random_value(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
+int test_xor_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
+int test_sub_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
+int test_mul_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
+int test_div_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
+int test_or_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
+int test_and_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
+int test_seqinc_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
+int test_solidbits_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
+int test_checkerboard_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
+int test_blockseq_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
+int test_walkbits0_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
+int test_walkbits1_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
+int test_bitspread_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
+int test_bitflip_comparison(unsigned long volatile *bufa, unsigned long volatile *bufb, size_t count);
+int test_simple_comparison(ulv *bufa, ulv *bufb, size_t count);
+