diff options
Diffstat (limited to 'post/drivers')
| -rw-r--r-- | post/drivers/i2c.c | 99 | ||||
| -rw-r--r-- | post/drivers/memory.c | 68 |
2 files changed, 111 insertions, 56 deletions
diff --git a/post/drivers/i2c.c b/post/drivers/i2c.c index b152deaf6..4a1b1a49d 100644 --- a/post/drivers/i2c.c +++ b/post/drivers/i2c.c @@ -21,70 +21,89 @@ * MA 02111-1307 USA */ -#include <common.h> - /* * I2C test * * For verifying the I2C bus, a full I2C bus scanning is performed. * - * #ifdef I2C_ADDR_LIST - * The test is considered as passed if all the devices and - * only the devices in the list are found. - * #else [ ! I2C_ADDR_LIST ] + * #ifdef CONFIG_SYS_POST_I2C_ADDRS + * The test is considered as passed if all the devices and only the devices + * in the list are found. + * #ifdef CONFIG_SYS_POST_I2C_IGNORES + * Ignore devices listed in CONFIG_SYS_POST_I2C_IGNORES. These devices + * are optional or not vital to board functionality. + * #endif + * #else [ ! CONFIG_SYS_POST_I2C_ADDRS ] * The test is considered as passed if any I2C device is found. * #endif */ +#include <common.h> #include <post.h> #include <i2c.h> #if CONFIG_POST & CONFIG_SYS_POST_I2C +static int i2c_ignore_device(unsigned int chip) +{ +#ifdef CONFIG_SYS_POST_I2C_IGNORES + const unsigned char i2c_ignore_list[] = CONFIG_SYS_POST_I2C_IGNORES; + int i; + + for (i = 0; i < sizeof(i2c_ignore_list); i++) + if (i2c_ignore_list[i] == chip) + return 1; +#endif + + return 0; +} + int i2c_post_test (int flags) { unsigned int i; - unsigned int good = 0; -#ifdef I2C_ADDR_LIST - unsigned int bad = 0; +#ifndef CONFIG_SYS_POST_I2C_ADDRS + /* Start at address 1, address 0 is the general call address */ + for (i = 1; i < 128; i++) + if (i2c_ignore_device(i)) + continue; + if (i2c_probe (i) == 0) + return 0; + + /* No devices found */ + return -1; +#else + unsigned int ret = 0; int j; - unsigned char i2c_addr_list[] = I2C_ADDR_LIST; - unsigned char i2c_miss_list[] = I2C_ADDR_LIST; -#endif + unsigned char i2c_addr_list[] = CONFIG_SYS_POST_I2C_ADDRS; - for (i = 0; i < 128; i++) { - if (i2c_probe (i) == 0) { -#ifndef I2C_ADDR_LIST - good++; -#else /* I2C_ADDR_LIST */ - for (j=0; j<sizeof(i2c_addr_list); ++j) { - if (i == i2c_addr_list[j]) { - good++; - i2c_miss_list[j] = 0xFF; - break; - } - } - if (j == sizeof(i2c_addr_list)) { - bad++; - post_log ("I2C: addr %02X not expected\n", - i); + /* Start at address 1, address 0 is the general call address */ + for (i = 1; i < 128; i++) { + if (i2c_ignore_device(i)) + continue; + if (i2c_probe(i) != 0) + continue; + + for (j = 0; j < sizeof(i2c_addr_list); ++j) { + if (i == i2c_addr_list[j]) { + i2c_addr_list[j] = 0xff; + break; } -#endif /* I2C_ADDR_LIST */ } - } -#ifndef I2C_ADDR_LIST - return good > 0 ? 0 : -1; -#else /* I2C_ADDR_LIST */ - if (good != sizeof(i2c_addr_list)) { - for (j=0; j<sizeof(i2c_miss_list); ++j) { - if (i2c_miss_list[j] != 0xFF) { - post_log ("I2C: addr %02X did not respond\n", - i2c_miss_list[j]); - } + if (j == sizeof(i2c_addr_list)) { + ret = -1; + post_log("I2C: addr %02x not expected\n", i); } } - return ((good == sizeof(i2c_addr_list)) && (bad == 0)) ? 0 : -1; + + for (i = 0; i < sizeof(i2c_addr_list); ++i) { + if (i2c_addr_list[i] == 0xff) + continue; + post_log("I2C: addr %02x did not respond\n", i2c_addr_list[i]); + ret = -1; + } + + return ret; #endif } diff --git a/post/drivers/memory.c b/post/drivers/memory.c index 006236009..3f47449f1 100644 --- a/post/drivers/memory.c +++ b/post/drivers/memory.c @@ -452,30 +452,66 @@ static int memory_post_tests (unsigned long start, unsigned long size) return ret; } -int memory_post_test (int flags) +__attribute__((weak)) +int arch_memory_test_prepare(u32 *vstart, u32 *size, phys_addr_t *phys_offset) { - int ret = 0; bd_t *bd = gd->bd; - unsigned long memsize = (bd->bi_memsize >= 256 << 20 ? - 256 << 20 : bd->bi_memsize) - (1 << 20); + *vstart = CONFIG_SYS_SDRAM_BASE; + *size = (bd->bi_memsize >= 256 << 20 ? + 256 << 20 : bd->bi_memsize) - (1 << 20); /* Limit area to be tested with the board info struct */ - if (CONFIG_SYS_SDRAM_BASE + memsize > (ulong)bd) - memsize = (ulong)bd - CONFIG_SYS_SDRAM_BASE; + if ((*vstart) + (*size) > (ulong)bd) + *size = (ulong)bd - *vstart; - if (flags & POST_SLOWTEST) { - ret = memory_post_tests (CONFIG_SYS_SDRAM_BASE, memsize); - } else { /* POST_NORMAL */ + return 0; +} - unsigned long i; +__attribute__((weak)) +int arch_memory_test_advance(u32 *vstart, u32 *size, phys_addr_t *phys_offset) +{ + return 1; +} - for (i = 0; i < (memsize >> 20) && ret == 0; i++) { - if (ret == 0) - ret = memory_post_tests (i << 20, 0x800); - if (ret == 0) - ret = memory_post_tests ((i << 20) + 0xff800, 0x800); +__attribute__((weak)) +int arch_memory_test_cleanup(u32 *vstart, u32 *size, phys_addr_t *phys_offset) +{ + return 0; +} + +__attribute__((weak)) +void arch_memory_failure_handle(void) +{ + return; +} + +int memory_post_test(int flags) +{ + int ret = 0; + phys_addr_t phys_offset = 0; + u32 memsize, vstart; + + arch_memory_test_prepare(&vstart, &memsize, &phys_offset); + + do { + if (flags & POST_SLOWTEST) { + ret = memory_post_tests(vstart, memsize); + } else { /* POST_NORMAL */ + unsigned long i; + for (i = 0; i < (memsize >> 20) && ret == 0; i++) { + if (ret == 0) + ret = memory_post_tests(i << 20, 0x800); + if (ret == 0) + ret = memory_post_tests( + (i << 20) + 0xff800, 0x800); + } } - } + } while (!ret && + !arch_memory_test_advance(&vstart, &memsize, &phys_offset)); + + arch_memory_test_cleanup(&vstart, &memsize, &phys_offset); + if (ret) + arch_memory_failure_handle(); return ret; } |