summaryrefslogtreecommitdiff
path: root/post
diff options
context:
space:
mode:
authorSascha Laue <sascha.laue@liebherr.com>2010-08-19 07:38:56 (GMT)
committerStefan Roese <sr@denx.de>2010-10-04 09:19:35 (GMT)
commitf14ae4180a37cf05c6bcfa5d55cc2955e920e1e2 (patch)
treede40c143117aae93ab9d01ee179bed48bd6db4b7 /post
parentd0e6665a24c2c2a3d333db169fcd1261a0903146 (diff)
downloadu-boot-f14ae4180a37cf05c6bcfa5d55cc2955e920e1e2.tar.xz
ppc4xx: Big lwmon5 board support rework/update
This patch brings the lwmon5 board support up-to-date. Here a summary of the changes: lwmon5 board port related: - GPIO's changed to control the LSB transmitter - Reset USB PHY's upon power-up - Enable CAN upon power-up - USB init error workaround (errata CHIP_6) - EBC: Enable burstmode and modify the timings for the GDC memory - EBC: Speed up NOR flash timings lwmon5 board POST related: - Add FPGA memory test - Add GDC memory test - DSP POST reworked - SYSMON POST: Fix handling of negative temperatures - Add output for sysmon1 POST - HW-watchdog min. time test reworked Additionally some coding-style changes were done. Signed-off-by: Sascha Laue <sascha.laue@liebherr.com> Signed-off-by: Stefan Roese <sr@denx.de>
Diffstat (limited to 'post')
-rw-r--r--post/board/lwmon5/dsp.c21
-rw-r--r--post/board/lwmon5/dspic.c56
-rw-r--r--post/board/lwmon5/fpga.c308
-rw-r--r--post/board/lwmon5/gdc.c308
-rw-r--r--post/board/lwmon5/sysmon.c160
-rw-r--r--post/board/lwmon5/watchdog.c19
6 files changed, 727 insertions, 145 deletions
diff --git a/post/board/lwmon5/dsp.c b/post/board/lwmon5/dsp.c
index 0e6d908..913cd97 100644
--- a/post/board/lwmon5/dsp.c
+++ b/post/board/lwmon5/dsp.c
@@ -33,20 +33,37 @@
DECLARE_GLOBAL_DATA_PTR;
-#define DSP_STATUS_REG 0xC4000008
+#define DSP_STATUS_REG 0xC4000008
+#define FPGA_STATUS_REG 0xC400000C
int dsp_post_test(int flags)
{
+ uint old_value;
uint read_value;
int ret;
+ /* momorize fpga status */
+ old_value = in_be32((void *)FPGA_STATUS_REG);
+ /* enable outputs */
+ out_be32((void *)FPGA_STATUS_REG, 0x30);
+
+ /* generate sync signal */
+ out_be32((void *)DSP_STATUS_REG, 0x300);
+ udelay(5);
+ out_be32((void *)DSP_STATUS_REG, 0);
+ udelay(500);
+
+ /* read status */
ret = 0;
read_value = in_be32((void *)DSP_STATUS_REG) & 0x3;
- if (read_value != 0x3) {
+ if (read_value != 0x03) {
post_log("\nDSP status read %08X\n", read_value);
ret = 1;
}
+ /* restore fpga status */
+ out_be32((void *)FPGA_STATUS_REG, old_value);
+
return ret;
}
diff --git a/post/board/lwmon5/dspic.c b/post/board/lwmon5/dspic.c
index ff2ed05..8616739 100644
--- a/post/board/lwmon5/dspic.c
+++ b/post/board/lwmon5/dspic.c
@@ -38,14 +38,16 @@ DECLARE_GLOBAL_DATA_PTR;
#define DSPIC_POST_ERROR_REG 0x800
#define DSPIC_SYS_ERROR_REG 0x802
-#define DSPIC_VERSION_REG 0x804
+#define DSPIC_SYS_VERSION_REG 0x804
+#define DSPIC_FW_VERSION_REG 0x808
#if CONFIG_POST & CONFIG_SYS_POST_BSPEC1
/* Verify that dsPIC ready test done early at hw init passed ok */
int dspic_init_post_test(int flags)
{
- if (in_be32((void *)CONFIG_SYS_DSPIC_TEST_ADDR) & CONFIG_SYS_DSPIC_TEST_MASK) {
+ if (in_be32((void *)CONFIG_SYS_DSPIC_TEST_ADDR) &
+ CONFIG_SYS_DSPIC_TEST_MASK) {
post_log("dsPIC init test failed\n");
return 1;
}
@@ -57,46 +59,60 @@ int dspic_init_post_test(int flags)
#if CONFIG_POST & CONFIG_SYS_POST_BSPEC2
/* Read a register from the dsPIC. */
-int dspic_read(ushort reg)
+int dspic_read(ushort reg, ushort *data)
{
- uchar buf[2];
+ uchar buf[sizeof(*data)];
+ int rval;
if (i2c_read(CONFIG_SYS_I2C_DSPIC_IO_ADDR, reg, 2, buf, 2))
return -1;
+ rval = i2c_read(CONFIG_SYS_I2C_DSPIC_IO_ADDR, reg, sizeof(reg),
+ buf, sizeof(*data));
+ *data = (buf[0] << 8) | buf[1];
- return (uint)((buf[0] << 8) | buf[1]);
+ return rval;
}
/* Verify error codes regs, display version */
int dspic_post_test(int flags)
{
- int data;
+ ushort data;
int ret = 0;
post_log("\n");
- data = dspic_read(DSPIC_VERSION_REG);
- if (data == -1) {
- post_log("dsPIC : failed read version\n");
+
+ /* read dspic FW-Version */
+ if (dspic_read(DSPIC_FW_VERSION_REG, &data)) {
+ post_log("dsPIC: failed read FW-Version\n");
+ ret = 1;
+ } else {
+ post_log("dsPIC FW-Version: %u.%u\n",
+ (data >> 8) & 0xFF, data & 0xFF);
+ }
+
+ /* read dspic SYS-Version */
+ if (dspic_read(DSPIC_SYS_VERSION_REG, &data)) {
+ post_log("dsPIC: failed read version\n");
ret = 1;
} else {
- post_log("dsPIC version: %u.%u\n",
- (data >> 8) & 0xFF, data & 0xFF);
+ post_log("dsPIC SYS-Version: %u.%u\n",
+ (data >> 8) & 0xFF, data & 0xFF);
}
- data = dspic_read(DSPIC_POST_ERROR_REG);
- if (data != 0) ret = 1;
- if (data == -1) {
- post_log("dsPIC : failed read POST code\n");
+ /* read dspic POST error code */
+ if (dspic_read(DSPIC_POST_ERROR_REG, &data)) {
+ post_log("dsPIC: failed read POST code\n");
+ ret = 1;
} else {
- post_log("dsPIC POST code 0x%04X\n", data);
+ post_log("dsPIC POST-ERROR code: 0x%04X\n", data);
}
- data = dspic_read(DSPIC_SYS_ERROR_REG);
- if (data == -1) {
- post_log("dsPIC : failed read system error\n");
+ /* read dspic SYS error code */
+ if ((data = dspic_read(DSPIC_SYS_ERROR_REG, &data))) {
+ post_log("dsPIC: failed read system error\n");
ret = 1;
} else {
- post_log("dsPIC SYS-ERROR code: 0x%04X\n", data);
+ post_log("dsPIC SYS-ERROR code: 0x%04X\n", data);
}
return ret;
diff --git a/post/board/lwmon5/fpga.c b/post/board/lwmon5/fpga.c
index 2b84290..3067548 100644
--- a/post/board/lwmon5/fpga.c
+++ b/post/board/lwmon5/fpga.c
@@ -28,7 +28,7 @@
*/
#include <post.h>
-
+#include <watchdog.h>
#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -38,18 +38,28 @@ DECLARE_GLOBAL_DATA_PTR;
#define FPGA_RAM_START 0xC4200000
#define FPGA_RAM_END 0xC4203FFF
#define FPGA_STAT 0xC400000C
+#define FPGA_BUFFER 0x00800000
+#define FPGA_RAM_SIZE (FPGA_RAM_END - FPGA_RAM_START + 1)
#if CONFIG_POST & CONFIG_SYS_POST_BSPEC3
-/* Testpattern for fpga memorytest */
-static uint pattern[] = {
+const static unsigned long pattern[] = {
+ 0xffffffff,
+ 0xaaaaaaaa,
+ 0xcccccccc,
+ 0xf0f0f0f0,
+ 0xff00ff00,
+ 0xffff0000,
+ 0x0000ffff,
+ 0x00ff00ff,
+ 0x0f0f0f0f,
+ 0x33333333,
0x55555555,
- 0xAAAAAAAA,
- 0xAA5555AA,
- 0x55AAAA55,
- 0x0
+ 0x00000000,
};
+const static unsigned long otherpattern = 0x01234567;
+
static int one_scratch_test(uint value)
{
uint read_value;
@@ -62,51 +72,226 @@ static int one_scratch_test(uint value)
read_value = in_be32((void *)FPGA_SCRATCH_REG);
if (read_value != value) {
post_log("FPGA SCRATCH test failed write %08X, read %08X\n",
- value, read_value);
- ret = 1;
+ value, read_value);
+ ret = -1;
+ }
+
+ return ret;
+}
+
+static int fpga_post_test1(ulong *start, ulong size, ulong val)
+{
+ int ret = 0;
+ ulong i = 0;
+ ulong *mem = start;
+ ulong readback;
+
+ for (i = 0; i < size / sizeof(ulong); i++) {
+ mem[i] = val;
+ if (i % 1024 == 0)
+ WATCHDOG_RESET();
+ }
+
+ for (i = 0; i < size / sizeof(ulong); i++) {
+ readback = mem[i];
+ if (readback != val) {
+ post_log("FPGA Memory error at %08x, "
+ "wrote %08x, read %08x !\n",
+ mem + i, val, readback);
+ ret = -1;
+ break;
+ }
+ if (i % 1024 == 0)
+ WATCHDOG_RESET();
+ }
+ return ret;
+}
+
+static int fpga_post_test2(ulong *start, ulong size)
+{
+ int ret = 0;
+ ulong i = 0;
+ ulong *mem = start;
+ ulong readback;
+
+ for (i = 0; i < size / sizeof(ulong); i++) {
+ mem[i] = 1 << (i % 32);
+ if (i % 1024 == 0)
+ WATCHDOG_RESET();
+ }
+
+ for (i = 0; i < size / sizeof(ulong); i++) {
+ readback = mem[i];
+ if (readback != 1 << (i % 32)) {
+ post_log("FPGA Memory error at %08x, "
+ "wrote %08x, read %08x !\n",
+ mem + i, 1 << (i % 32), readback);
+ ret = -1;
+ break;
+ }
+ if (i % 1024 == 0)
+ WATCHDOG_RESET();
+ }
+
+ return ret;
+}
+
+static int fpga_post_test3(ulong *start, ulong size)
+{
+ int ret = 0;
+ ulong i = 0;
+ ulong *mem = start;
+ ulong readback;
+
+ for (i = 0; i < size / sizeof(ulong); i++) {
+ mem[i] = i;
+ if (i % 1024 == 0)
+ WATCHDOG_RESET();
+ }
+
+ for (i = 0; i < size / sizeof(ulong); i++) {
+ readback = mem[i];
+ if (readback != i) {
+ post_log("FPGA Memory error at %08x, "
+ "wrote %08x, read %08x !\n",
+ mem + i, i, readback);
+ ret = -1;
+ break;
+ }
+ if (i % 1024 == 0)
+ WATCHDOG_RESET();
+ }
+
+ return ret;
+}
+
+static int fpga_post_test4(ulong *start, ulong size)
+{
+ int ret = 0;
+ ulong i = 0;
+ ulong *mem = start;
+ ulong readback;
+
+ for (i = 0; i < size / sizeof(ulong); i++) {
+ mem[i] = ~i;
+ if (i % 1024 == 0)
+ WATCHDOG_RESET();
+ }
+
+ for (i = 0; i < size / sizeof(ulong); i++) {
+ readback = mem[i];
+ if (readback != ~i) {
+ post_log("FPGA Memory error at %08x, "
+ "wrote %08x, read %08x !\n",
+ mem + i, ~i, readback);
+ ret = -1;
+ break;
+ }
+ if (i % 1024 == 0)
+ WATCHDOG_RESET();
}
return ret;
}
/* FPGA Memory-pattern-test */
-static int fpga_mem_test(void * address)
+static int fpga_mem_test(void)
{
- int ret = 1;
- uint read_value;
- uint old_value;
- uint i = 0;
- /* save content */
- old_value = in_be32(address);
-
- while (pattern[i] != 0) {
- out_be32(address, pattern[i]);
- /* read other location (protect against data lines capacity) */
- ret = in_be16((void *)FPGA_VERSION_REG);
- /* verify test pattern */
- read_value = in_be32(address);
-
- if (read_value != pattern[i]) {
- post_log("FPGA Memory test failed.");
- post_log(" write %08X, read %08X at address %08X\n",
- pattern[i], read_value, address);
+ int ret = 0;
+ ulong* start = (ulong *)FPGA_RAM_START;
+ ulong size = FPGA_RAM_SIZE;
+
+ if (ret == 0)
+ ret = fpga_post_test1(start, size, 0x00000000);
+
+ if (ret == 0)
+ ret = fpga_post_test1(start, size, 0xffffffff);
+
+ if (ret == 0)
+ ret = fpga_post_test1(start, size, 0x55555555);
+
+ if (ret == 0)
+ ret = fpga_post_test1(start, size, 0xaaaaaaaa);
+
+ WATCHDOG_RESET();
+
+ if (ret == 0)
+ ret = fpga_post_test2(start, size);
+
+ if (ret == 0)
+ ret = fpga_post_test3(start, size);
+
+ if (ret == 0)
+ ret = fpga_post_test4(start, size);
+
+ return ret;
+}
+
+
+
+/* Verify FPGA addresslines */
+static int fpga_post_addrline(ulong *address, ulong *base, ulong size)
+{
+ unsigned long *target;
+ unsigned long *end;
+ unsigned long readback;
+ unsigned long xor;
+ int ret = 0;
+
+ end = (ulong *)((ulong)base + size);
+ xor = 0;
+
+ for (xor = sizeof(ulong); xor > 0; xor <<= 1) {
+ target = (ulong*)((ulong)address ^ xor);
+ if ((target >= base) && (target < end)) {
+ *address = ~*target;
+ readback = *target;
+
+ if (readback == *address) {
+ post_log("Memory (address line) error at %08x"
+ "XOR value %08x !\n",
+ address, target, xor);
+ ret = -1;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+/* Verify FPGA addresslines */
+static int fpga_post_dataline(ulong *address)
+{
+ unsigned long temp32 = 0;
+ int i = 0;
+ int ret = 0;
+
+ for (i = 0; i < ARRAY_SIZE(pattern); i++) {
+ *address = pattern[i];
+ /*
+ * Put a different pattern on the data lines: otherwise they
+ * may float long enough to read back what we wrote.
+ */
+ *(address + 1) = otherpattern;
+ temp32 = *address;
+
+ if (temp32 != pattern[i]){
+ post_log("Memory (date line) error at %08x, "
+ "wrote %08x, read %08x !\n",
+ address, pattern[i], temp32);
ret = 1;
- goto out;
}
- i++;
}
- ret = 0;
-out:
- out_be32(address, old_value);
return ret;
}
+
/* Verify FPGA, get version & memory size */
int fpga_post_test(int flags)
{
- uint address;
uint old_value;
- ushort version;
+ uint version;
uint read_value;
int ret = 0;
@@ -120,24 +305,57 @@ int fpga_post_test(int flags)
out_be32((void *)FPGA_SCRATCH_REG, old_value);
- version = in_be16((void *)FPGA_VERSION_REG);
- post_log("FPGA : version %u.%u\n",
- (version >> 8) & 0xFF, version & 0xFF);
+ version = in_be32((void *)FPGA_VERSION_REG);
+ post_log("FPGA version %u.%u\n",
+ (version >> 8) & 0xFF, version & 0xFF);
/* Enable write to FPGA RAM */
out_be32((void *)FPGA_STAT, in_be32((void *)FPGA_STAT) | 0x1000);
- read_value = get_ram_size((void *)CONFIG_SYS_FPGA_BASE_1, 0x4000);
- post_log("FPGA RAM size: %d bytes\n", read_value);
+ /* get RAM size */
+ read_value = get_ram_size((void *)CONFIG_SYS_FPGA_BASE_1, FPGA_RAM_SIZE);
+ post_log("FPGA RAM size %d bytes\n", read_value);
+ WATCHDOG_RESET();
- for (address = 0; address < 0x1000; address++) {
- if (fpga_mem_test((void *)(FPGA_RAM_START + 4*address)) == 1) {
- ret = 1;
- goto out;
- }
+ /* copy fpga memory to DDR2 RAM*/
+ memcpy((void *)FPGA_BUFFER,(void *)FPGA_RAM_START, FPGA_RAM_SIZE);
+ WATCHDOG_RESET();
+
+ /* Test datalines */
+ if (fpga_post_dataline((ulong *)FPGA_RAM_START)) {
+ ret = 1;
+ goto out;
+ }
+ WATCHDOG_RESET();
+
+ /* Test addresslines */
+ if (fpga_post_addrline((ulong *)FPGA_RAM_START,
+ (ulong *)FPGA_RAM_START, FPGA_RAM_SIZE)) {
+ ret = 1;
+ goto out;
}
+ WATCHDOG_RESET();
+ if (fpga_post_addrline((ulong *)FPGA_RAM_END - sizeof(long),
+ (ulong *)FPGA_RAM_START, FPGA_RAM_SIZE)) {
+ ret = 1;
+ goto out;
+ }
+ WATCHDOG_RESET();
+
+ /* Memory Pattern Test */
+ if (fpga_mem_test()) {
+ ret = 1;
+ goto out;
+ }
+ WATCHDOG_RESET();
+
+ /* restore memory */
+ memcpy((void *)FPGA_RAM_START,(void *)FPGA_BUFFER, FPGA_RAM_SIZE);
+ WATCHDOG_RESET();
out:
+ /* Disable write to RAM */
+ out_be32((void *)FPGA_STAT, in_be32((void *)FPGA_STAT) & 0xEFFF);
return ret;
}
diff --git a/post/board/lwmon5/gdc.c b/post/board/lwmon5/gdc.c
index eb16e36..719194b 100644
--- a/post/board/lwmon5/gdc.c
+++ b/post/board/lwmon5/gdc.c
@@ -28,18 +28,39 @@
*/
#include <post.h>
-
+#include <watchdog.h>
#include <asm/io.h>
+#include <video.h>
DECLARE_GLOBAL_DATA_PTR;
-#define GDC_SCRATCH_REG 0xC1FF8044
-#define GDC_VERSION_REG 0xC1FF8084
-#define GDC_RAM_START 0xC0000000
-#define GDC_RAM_END 0xC2000000
+#define GDC_SCRATCH_REG 0xC1FF8044
+#define GDC_VERSION_REG 0xC1FF8084
+#define GDC_HOST_BASE 0xC1FC0000
+#define GDC_RAM_START 0xC0000000
+#define GDC_RAM_END (GDC_HOST_BASE - 1)
+#define GDC_RAM_SIZE (GDC_RAM_END - GDC_RAM_START)
#if CONFIG_POST & CONFIG_SYS_POST_BSPEC4
+const static unsigned long pattern[] = {
+ 0xffffffff,
+ 0xaaaaaaaa,
+ 0xcccccccc,
+ 0xf0f0f0f0,
+ 0xff00ff00,
+ 0xffff0000,
+ 0x0000ffff,
+ 0x00ff00ff,
+ 0x0f0f0f0f,
+ 0x33333333,
+ 0x55555555,
+ 0x00000000
+};
+
+const static unsigned long otherpattern = 0x01234567;
+
+/* test write/read og a given LIME Register */
static int gdc_test_reg_one(uint value)
{
int ret;
@@ -53,17 +74,229 @@ static int gdc_test_reg_one(uint value)
read_value = in_be32((void *)GDC_SCRATCH_REG);
if (read_value != value) {
post_log("GDC SCRATCH test failed write %08X, read %08X\n",
- value, read_value);
+ value, read_value);
}
return (read_value != value);
}
-/* Verify GDC, get memory size */
+/* test with a given static 32 bit pattern in a given memory addressrange */
+static int gdc_post_test1(ulong *start, ulong size, ulong val)
+{
+ int ret = 0;
+ ulong i = 0;
+ ulong *mem = start;
+ ulong readback;
+
+ for (i = 0; i < size / sizeof(ulong); i++) {
+ mem[i] = val;
+ if (i % 1024 == 0)
+ WATCHDOG_RESET();
+ }
+
+ for (i = 0; i < size / sizeof(ulong); i++) {
+ readback = mem[i];
+ if (readback != val) {
+ post_log("GDC Memory error at %08x, "
+ "wrote %08x, read %08x !\n",
+ mem + i, val, readback);
+ ret = -1;
+ break;
+ }
+ if (i % 1024 == 0)
+ WATCHDOG_RESET();
+ }
+
+ return ret;
+}
+
+/* test with dynamic 32 bit pattern in a given memory addressrange */
+static int gdc_post_test2(ulong *start, ulong size)
+{
+ int ret = 0;
+ ulong i = 0;
+ ulong *mem = start;
+ ulong readback;
+
+ for (i = 0; i < size / sizeof(ulong); i++) {
+ mem[i] = 1 << (i % 32);
+ if (i % 1024 == 0)
+ WATCHDOG_RESET();
+ }
+
+ for (i = 0; i < size / sizeof(ulong); i++) {
+ readback = mem[i];
+ if (readback != 1 << (i % 32)) {
+ post_log("GDC Memory error at %08x, "
+ "wrote %08x, read %08x !\n",
+ mem + i, 1 << (i % 32), readback);
+ ret = -1;
+ break;
+ }
+ if (i % 1024 == 0)
+ WATCHDOG_RESET();
+ }
+
+ return ret;
+}
+
+/* test with dynamic 32 bit pattern in a given memory addressrange */
+static int gdc_post_test3(ulong *start, ulong size)
+{
+ int ret = 0;
+ ulong i = 0;
+ ulong *mem = start;
+ ulong readback;
+
+ for (i = 0; i < size / sizeof(ulong); i++) {
+ mem[i] = i;
+ if (i % 1024 == 0)
+ WATCHDOG_RESET();
+ }
+
+ for (i = 0; i < size / sizeof(ulong); i++) {
+ readback = mem[i];
+ if (readback != i) {
+ post_log("GDC Memory error at %08x, "
+ "wrote %08x, read %08x !\n",
+ mem + i, i, readback);
+ ret = -1;
+ break;
+ }
+ if (i % 1024 == 0)
+ WATCHDOG_RESET();
+ }
+
+ return ret;
+}
+
+/* test with dynamic 32 bit pattern in a given memory addressrange */
+static int gdc_post_test4(ulong *start, ulong size)
+{
+ int ret = 0;
+ ulong i = 0;
+ ulong *mem = start;
+ ulong readback;
+
+ for (i = 0; i < size / sizeof(ulong); i++) {
+ mem[i] = ~i;
+ if (i % 1024 == 0)
+ WATCHDOG_RESET();
+ }
+
+ for (i = 0; i < size / sizeof(ulong); i++) {
+ readback = mem[i];
+ if (readback != ~i) {
+ post_log("GDC Memory error at %08x, "
+ "wrote %08x, read %08x !\n",
+ mem + i, ~i, readback);
+ ret = -1;
+ break;
+ }
+ if (i % 1024 == 0)
+ WATCHDOG_RESET();
+ }
+
+ return ret;
+}
+
+/* do some patterntests in a given addressrange */
+int gdc_mem_test(ulong *start, ulong size)
+{
+ int ret = 0;
+
+ /*
+ * check addressrange and do different static and dynamic
+ * pattern tests with it.
+ */
+ if (((void *)start) + size <= (void *)GDC_RAM_END) {
+ if (ret == 0)
+ ret = gdc_post_test1(start, size, 0x00000000);
+
+ if (ret == 0)
+ ret = gdc_post_test1(start, size, 0xffffffff);
+
+ if (ret == 0)
+ ret = gdc_post_test1(start, size, 0x55555555);
+
+ if (ret == 0)
+ ret = gdc_post_test1(start, size, 0xaaaaaaaa);
+
+ if (ret == 0)
+ ret = gdc_post_test2(start, size);
+
+ if (ret == 0)
+ ret = gdc_post_test3(start, size);
+
+ if (ret == 0)
+ ret = gdc_post_test4(start, size);
+ }
+
+ return ret;
+}
+
+/* test function of gdc memory addresslines*/
+static int gdc_post_addrline(ulong *address, ulong *base, ulong size)
+{
+ ulong *target;
+ ulong *end;
+ ulong readback = 0;
+ ulong xor = 0;
+ int ret = 0;
+
+ end = (ulong *)((ulong)base + size);
+
+ for (xor = sizeof(long); xor > 0; xor <<= 1) {
+ target = (ulong *)((ulong)address ^ xor);
+ if ((target >= base) && (target < end)) {
+ *address = ~*target;
+ readback = *target;
+ }
+
+ if (readback == *address) {
+ post_log("GDC Memory (address line) error at %08x"
+ "XOR value %08x !\n",
+ address, target , xor);
+ ret = -1;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static int gdc_post_dataline(ulong *address)
+{
+ unsigned long temp32 = 0;
+ int i = 0;
+ int ret = 0;
+
+ for (i = 0; i < ARRAY_SIZE(pattern); i++) {
+ *address = pattern[i];
+ /*
+ * Put a different pattern on the data lines: otherwise they
+ * may float long enough to read back what we wrote.
+ */
+ *(address + 1) = otherpattern;
+ temp32 = *address;
+
+ if (temp32 != pattern[i]){
+ post_log("GDC Memory (date line) error at %08x, "
+ "wrote %08x, read %08x !\n",
+ address, pattern[i], temp32);
+ ret = 1;
+ }
+ }
+
+ return ret;
+}
+
+/* Verify GDC, get memory size, verify GDC memory */
int gdc_post_test(int flags)
{
- uint old_value;
- int ret = 0;
+ uint old_value;
+ int i = 0;
+ int ret = 0;
post_log("\n");
old_value = in_be32((void *)GDC_SCRATCH_REG);
@@ -84,13 +317,64 @@ int gdc_post_test(int flags)
old_value = in_be32((void *)GDC_VERSION_REG);
post_log("GDC chip version %u.%u, year %04X\n",
- (old_value >> 8) & 0xFF, old_value & 0xFF,
- (old_value >> 16) & 0xFFFF);
+ (old_value >> 8) & 0xFF, old_value & 0xFF,
+ (old_value >> 16) & 0xFFFF);
old_value = get_ram_size((void *)GDC_RAM_START,
- GDC_RAM_END - GDC_RAM_START);
+ 0x02000000);
+
+ debug("GDC RAM size (ist): %d bytes\n", old_value);
+ debug("GDC RAM size (soll): %d bytes\n", GDC_RAM_SIZE);
post_log("GDC RAM size: %d bytes\n", old_value);
+ /* Test SDRAM datalines */
+ if (gdc_post_dataline((ulong *)GDC_RAM_START)) {
+ ret = 1;
+ goto out;
+ }
+ WATCHDOG_RESET();
+
+ /* Test SDRAM adresslines */
+ if (gdc_post_addrline((ulong *)GDC_RAM_START,
+ (ulong *)GDC_RAM_START, GDC_RAM_SIZE)) {
+ ret = 1;
+ goto out;
+ }
+ WATCHDOG_RESET();
+ if (gdc_post_addrline((ulong *)GDC_RAM_END - sizeof(long),
+ (ulong *)GDC_RAM_START, GDC_RAM_SIZE)) {
+ ret = 1;
+ goto out;
+ }
+ WATCHDOG_RESET();
+
+ /* memory pattern test */
+ debug("GDC Memory test (flags %8x:%8x)\n", flags,
+ POST_SLOWTEST | POST_MANUAL);
+
+ if (flags & POST_MANUAL) {
+ debug("Full memory test\n");
+ if (gdc_mem_test((ulong *)GDC_RAM_START, GDC_RAM_SIZE)) {
+ ret = 1;
+ goto out;
+ }
+ /* load splashscreen again */
+ } else {
+ debug("smart memory test\n");
+ for (i = 0; i < (GDC_RAM_SIZE >> 20) && ret == 0; i++) {
+ if (ret == 0)
+ ret = gdc_mem_test((ulong *)(GDC_RAM_START +
+ (i << 20)),
+ 0x800);
+ if (ret == 0)
+ ret = gdc_mem_test((ulong *)(GDC_RAM_START +
+ (i << 20) + 0xff800),
+ 0x800);
+ }
+ }
+ WATCHDOG_RESET();
+
+out:
return ret;
}
#endif /* CONFIG_POST & CONFIG_SYS_POST_BSPEC4 */
diff --git a/post/board/lwmon5/sysmon.c b/post/board/lwmon5/sysmon.c
index 9c49d0e..4a78240 100644
--- a/post/board/lwmon5/sysmon.c
+++ b/post/board/lwmon5/sysmon.c
@@ -56,7 +56,7 @@
DECLARE_GLOBAL_DATA_PTR;
/* from dspic.c */
-extern int dspic_read(ushort reg);
+extern int dspic_read(ushort reg, ushort *data);
#define REG_TEMPERATURE 0x12BC
#define REG_VOLTAGE_5V 0x12CA
@@ -76,31 +76,38 @@ extern int dspic_read(ushort reg);
typedef struct sysmon_s sysmon_t;
typedef struct sysmon_table_s sysmon_table_t;
-static void sysmon_dspic_init (sysmon_t * this);
-static int sysmon_dspic_read (sysmon_t * this, uint addr);
-static void sysmon_backlight_disable (sysmon_table_t * this);
+static void sysmon_dspic_init(sysmon_t *this);
+static int sysmon_dspic_read(sysmon_t *this, uint addr, int *val);
+static int sysmon_dspic_read_sgn(sysmon_t *this, uint addr, int *val);
+static void sysmon_backlight_disable(sysmon_table_t *this);
-struct sysmon_s
-{
+struct sysmon_s {
uchar chip;
void (*init)(sysmon_t *);
- int (*read)(sysmon_t *, uint);
+ int (*read)(sysmon_t *, uint, int *);
};
-static sysmon_t sysmon_dspic =
- {CONFIG_SYS_I2C_DSPIC_IO_ADDR, sysmon_dspic_init, sysmon_dspic_read};
+static sysmon_t sysmon_dspic = {
+ CONFIG_SYS_I2C_DSPIC_IO_ADDR,
+ sysmon_dspic_init,
+ sysmon_dspic_read
+};
-static sysmon_t * sysmon_list[] =
-{
+static sysmon_t sysmon_dspic_sgn = {
+ CONFIG_SYS_I2C_DSPIC_IO_ADDR,
+ sysmon_dspic_init,
+ sysmon_dspic_read_sgn
+};
+
+static sysmon_t *sysmon_list[] = {
&sysmon_dspic,
NULL
};
-struct sysmon_table_s
-{
- char * name;
- char * unit_name;
- sysmon_t * sysmon;
+struct sysmon_table_s {
+ char *name;
+ char *unit_name;
+ sysmon_t *sysmon;
void (*exec_before)(sysmon_table_t *);
void (*exec_after)(sysmon_table_t *);
@@ -118,37 +125,43 @@ struct sysmon_table_s
uint addr;
};
-static sysmon_table_t sysmon_table[] =
-{
+static sysmon_table_t sysmon_table[] = {
{
- "Temperature", " C", &sysmon_dspic, NULL, sysmon_backlight_disable,
- 1, 1, -32768, 32767, 0xFFFF,
- 0x8000 + TEMPERATURE_MIN, 0x8000 + TEMPERATURE_MAX, 0,
- 0x8000 + TEMPERATURE_DISPLAY_MIN, 0x8000 + TEMPERATURE_DISPLAY_MAX, 0,
- REG_TEMPERATURE,
+ "Temperature", " C", &sysmon_dspic, NULL, sysmon_backlight_disable,
+ 1, 1, -32768, 32767, 0xFFFF,
+ 0x8000 + TEMPERATURE_MIN, 0x8000 + TEMPERATURE_MAX, 0,
+ 0x8000 + TEMPERATURE_DISPLAY_MIN, 0x8000 + TEMPERATURE_DISPLAY_MAX, 0,
+ REG_TEMPERATURE,
},
{
- "+ 5 V", "V", &sysmon_dspic, NULL, NULL,
- 100, 1000, -0x8000, 0x7FFF, 0xFFFF,
- 0x8000 + VOLTAGE_5V_MIN, 0x8000 + VOLTAGE_5V_MAX, 0,
- 0x8000 + VOLTAGE_5V_MIN, 0x8000 + VOLTAGE_5V_MAX, 0,
- REG_VOLTAGE_5V,
+ "+ 5 V", "V", &sysmon_dspic, NULL, NULL,
+ 100, 1000, -0x8000, 0x7FFF, 0xFFFF,
+ 0x8000 + VOLTAGE_5V_MIN, 0x8000 + VOLTAGE_5V_MAX, 0,
+ 0x8000 + VOLTAGE_5V_MIN, 0x8000 + VOLTAGE_5V_MAX, 0,
+ REG_VOLTAGE_5V,
},
{
- "+ 5 V standby", "V", &sysmon_dspic, NULL, NULL,
- 100, 1000, -0x8000, 0x7FFF, 0xFFFF,
- 0x8000 + VOLTAGE_5V_STANDBY_MIN, 0x8000 + VOLTAGE_5V_STANDBY_MAX, 0,
- 0x8000 + VOLTAGE_5V_STANDBY_MIN, 0x8000 + VOLTAGE_5V_STANDBY_MAX, 0,
- REG_VOLTAGE_5V_STANDBY,
+ "+ 5 V standby", "V", &sysmon_dspic, NULL, NULL,
+ 100, 1000, -0x8000, 0x7FFF, 0xFFFF,
+ 0x8000 + VOLTAGE_5V_STANDBY_MIN, 0x8000 + VOLTAGE_5V_STANDBY_MAX, 0,
+ 0x8000 + VOLTAGE_5V_STANDBY_MIN, 0x8000 + VOLTAGE_5V_STANDBY_MAX, 0,
+ REG_VOLTAGE_5V_STANDBY,
+ },
+
+ {
+ "Temperature", "°C", &sysmon_dspic_sgn, NULL, sysmon_backlight_disable,
+ 1, 1, -32768, 32767, 0xFFFF,
+ 0x8000 + TEMPERATURE_MIN, 0x8000 + TEMPERATURE_MAX, 0,
+ 0x8000 + TEMPERATURE_DISPLAY_MIN, 0x8000 + TEMPERATURE_DISPLAY_MAX, 0,
+ REG_TEMPERATURE,
},
};
-static int sysmon_table_size = sizeof(sysmon_table) / sizeof(sysmon_table[0]);
-int sysmon_init_f (void)
+int sysmon_init_f(void)
{
- sysmon_t ** l;
+ sysmon_t **l;
for (l = sysmon_list; *l; l++)
(*l)->init(*l);
@@ -156,12 +169,12 @@ int sysmon_init_f (void)
return 0;
}
-void sysmon_reloc (void)
+void sysmon_reloc(void)
{
/* Do nothing for now, sysmon_reloc() is required by the sysmon post */
}
-static char *sysmon_unit_value (sysmon_table_t *s, uint val)
+static char *sysmon_unit_value(sysmon_table_t *s, uint val)
{
static char buf[32];
char *p, sign;
@@ -176,14 +189,13 @@ static char *sysmon_unit_value (sysmon_table_t *s, uint val)
if (unit_val < 0) {
sign = '-';
unit_val = -unit_val;
- } else
+ } else {
sign = '+';
+ }
p = buf + sprintf(buf, "%c%2d", sign, unit_val / s->unit_div);
-
frac = unit_val % s->unit_div;
-
frac /= (s->unit_div / s->unit_precision);
decimal = s->unit_precision;
@@ -197,58 +209,84 @@ static char *sysmon_unit_value (sysmon_table_t *s, uint val)
return buf;
}
-static void sysmon_dspic_init (sysmon_t * this)
+static void sysmon_dspic_init(sysmon_t *this)
{
}
-static int sysmon_dspic_read (sysmon_t * this, uint addr)
+static int sysmon_dspic_read(sysmon_t *this, uint addr, int *val)
{
- int res = dspic_read(addr);
+ ushort data;
+
+ if (dspic_read(addr, &data) == 0){
+ /* To fit into the table range we should add 0x8000 */
+ *val = data + 0x8000;
+ return 0;
+ }
- /* To fit into the table range we should add 0x8000 */
- return (res == -1) ? -1 : (res + 0x8000);
+ return -1;
}
-static void sysmon_backlight_disable (sysmon_table_t * this)
+static int sysmon_dspic_read_sgn(sysmon_t *this, uint addr, int *val)
+{
+ ushort data;
+
+ if (dspic_read(addr, &data) == 0){
+ /* To fit into the table range we should add 0x8000 */
+ *val = (signed short)data + 0x8000;
+ return 0;
+ }
+
+ return -1;
+}
+
+static void sysmon_backlight_disable(sysmon_table_t *this)
{
#if defined(CONFIG_VIDEO)
board_backlight_switch(this->val_valid_alt);
#endif
}
-int sysmon_post_test (int flags)
+int sysmon_post_test(int flags)
{
int res = 0;
sysmon_table_t * t;
int val;
- for (t = sysmon_table; t < sysmon_table + sysmon_table_size; t ++) {
+ for (t = sysmon_table; t < sysmon_table + ARRAY_SIZE(sysmon_table); t++) {
+ t->val_valid = 1;
if (t->exec_before)
t->exec_before(t);
- val = t->sysmon->read(t->sysmon, t->addr);
- if (val != -1) {
- t->val_valid = val >= t->val_min && val <= t->val_max;
- t->val_valid_alt = val >= t->val_min_alt && val <= t->val_max_alt;
- } else {
+ if (t->sysmon->read(t->sysmon, t->addr, &val) != 0) {
t->val_valid = 0;
t->val_valid_alt = 0;
+ post_log(": read failed\n");
+ res = 1;
+ break;
+ }
+
+ if (t->val_valid != 0) {
+ t->val_valid = val >= t->val_min && val <= t->val_max;
+ t->val_valid_alt = val >= t->val_min_alt && val <= t->val_max_alt;
}
if (t->exec_after)
t->exec_after(t);
- if ((!t->val_valid) || (flags & POST_MANUAL)) {
- printf("%-17s = %-10s ", t->name, sysmon_unit_value(t, val));
- printf("allowed range");
- printf(" %-8s ..", sysmon_unit_value(t, t->val_min));
- printf(" %-8s", sysmon_unit_value(t, t->val_max));
- printf(" %s\n", t->val_valid ? "OK" : "FAIL");
+ if ((!t->val_valid) || (flags)) {
+ post_log("\n\t%-17s = %-10s ", t->name, sysmon_unit_value(t, val));
+ post_log("allowed range");
+ post_log(" %-8s ..", sysmon_unit_value(t, t->val_min));
+ post_log(" %-8s", sysmon_unit_value(t, t->val_max));
+ post_log(" %s", t->val_valid ? "OK" : "FAIL");
}
- if (!t->val_valid)
+ if (!t->val_valid) {
res = 1;
+ break;
+ }
}
+ post_log("\n");
return res;
}
diff --git a/post/board/lwmon5/watchdog.c b/post/board/lwmon5/watchdog.c
index f181506..4e5ed0d 100644
--- a/post/board/lwmon5/watchdog.c
+++ b/post/board/lwmon5/watchdog.c
@@ -57,8 +57,11 @@ int sysmon1_post_test(int flags)
* 3.1. GPIO62 is low
* Assuming system voltage failure.
*/
- post_log("Abnormal voltage detected (GPIO62)\n");
+ post_log("sysmon1 Abnormal voltage detected (GPIO62)\n");
+ post_log("POST sysmon1 FAILED\n");
return 1;
+ } else {
+ post_log("sysmon1 PASSED\n");
}
return 0;
@@ -117,10 +120,16 @@ int lwmon5_watchdog_post_test(int flags)
ulong time;
/* 3.3.1. So, the test succeed, save measured time to syslog. */
time = in_be32((void *)CONFIG_SYS_WATCHDOG_TIME_ADDR);
- post_log("hw watchdog time : %u ms, passed ", time);
- /* 3.3.2. Set scratch register 1 to 0x0000xxxx */
- watchdog_magic_write(0);
- return 0;
+ if (time > 90 ) { /* ms*/
+ post_log("hw watchdog time : %u ms, passed ", time);
+ /* 3.3.2. Set scratch register 1 to 0x0000xxxx */
+ watchdog_magic_write(0);
+ return 0;
+ } else {
+ /*test minimum watchdogtime */
+ post_log("hw watchdog time : %u ms, failed ", time);
+ return 2;
+ }
}
return -1;
}