blob: 3f9edfe7844b21498983e74d4347a9449953d09f [file] [log] [blame]
/*
* Implement following commands:
* (1). LED
* (2). DRAM Address Line Continuity
* (3). RF Loop Back
* (4). Ethernet RJ-45 Continuity
*/
#include <common.h>
#include <asm/arch/platform.h>
#include <asm/io.h>
#include <command.h>
#include "net.h"
/* Seconds waiting LED turn off */
#define POST_LED_WAIT_TIME 1
#define POST_MEM_BIT 0
#define POST_PHY_BIT 1
#define POST_RF_BIT 2
#define POST_MEM_LEVEL_BIT 4
#define POST_MEM_LEVEL_MASK 3
int memory_post(unsigned long *start, unsigned long size);
void disable_phy_loopback(void);
int do_post_led(unsigned int mask)
{
unsigned val;
int offset;
int i;
if (!mask)
mask = 0xcc;
/*
* 0xcc: bit2:wifi link led, bit3:wps led,
*bit6:mode led, bit7:link quality led
*/
val = readl(RUBY_GPIO_AFSEL);
val &= ~mask;
writel(val, RUBY_GPIO_AFSEL);
/* Set GPIO to Output mode and Mask */
for (i = 0; i < RUBY_GPIO_MAX; i++) {
if (!((1 << i) & mask))
continue;
if (i < RUBY_GPIO_MODE1_MAX) {
offset = i * 2;
val = readl(RUBY_GPIO_MODE1);
val &= ~(0x3 << offset);
val |= (0x1 << offset);
writel(val, RUBY_GPIO_MODE1);
} else {
offset = (i - RUBY_GPIO_MODE1_MAX) * 2;
val = readl(RUBY_GPIO_MODE2);
val &= ~(0x3 << offset);
val |= (0x1 << offset);
writel(val, RUBY_GPIO_MODE2);
}
}
writel(mask, GPIO_OUTPUT_MASK);
/* Turn on LED */
writel(mask, GPIO_OUTPUT);
udelay(POST_LED_WAIT_TIME * 1000000);
/* Turn off LED */
writel(0, GPIO_OUTPUT);
writel(0, GPIO_OUTPUT_MASK);
return 0;
}
int post_led(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
unsigned int mask;
int ret;
/* GPIO mask used for LED */
if (argc > 1)
mask = (ulong)simple_strtoul(argv[1], NULL, 16);
else
mask = 0;
ret = do_post_led(mask);
return ret;
}
U_BOOT_CMD(
post_led, CONFIG_SYS_MAXARGS, 0, post_led,
"POST LED test",
"gpio_mask\n"
" - Set gpio_mask bits of gpio pins\n"
);
int post_phy(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int ret;
ret = NetLoop(ETHLOOP);
#ifdef CONFIG_CMD_ETHLOOP
disable_phy_loopback();
#endif
if (ret < 0)
printf("phy loopback test failed\n");
else
printf("phy loopback test pass\n");
return ret;
}
U_BOOT_CMD(
post_phy, CONFIG_SYS_MAXARGS, 0, post_phy,
"POST phy loopback test"
"ethernet loopback test\n"
);
int do_post_mem(unsigned int iteration_limit)
{
ulong *start, size;
unsigned int iterations;
int ret;
char *p;
int dcache;
dcache = dcache_status();
if (dcache)
dcache_disable();
start = (ulong *)CONFIG_SYS_MEMTEST_START;
p = getenv("post_mem_size");
if (p) {
size = simple_strtoul(p, NULL, 16);
printf("user defined mem size 0x%x\n", size);
} else {
size = RUBY_MIN_DRAM_SIZE;
}
if (!iteration_limit) { /* 0 for loop */
for (;;) {
if (ctrlc()) {
/* printf("stop by ctrl-c ... "); */
break;
}
ret = memory_post(start, size);
if (ret < 0)
break;
iterations++;
}
} else {
for (iterations = 0; iterations < iteration_limit; iterations++) {
if (ctrlc()) {
/* printf("stop by ctrl-c ... "); */
break;
}
ret = memory_post(start, size);
if (ret < 0)
break;
}
}
if (dcache)
dcache_enable ();
return ret;
}
int post_mem(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
unsigned int iteration_limit;
int ret;
if (argc > 1)
iteration_limit = (ulong)simple_strtoul(argv[1], NULL, 16);
else
iteration_limit = 1;
ret = do_post_mem(iteration_limit);
return ret;
}
U_BOOT_CMD(
post_mem, CONFIG_SYS_MAXARGS, 0, post_mem,
"POST RAM test",
"[iterations]"
" - RAM Address/Data lines read/write test\n"
);
int do_post(void){
char *p;
int post_mask, old_result = 0, new_result = 0, result_update = 0;
int old_function = 0, new_function = 0, functionn_update = 0;
int ret = 0, mem_level;
char buf[32];
p = getenv("post_result");
if (p)
old_result = simple_strtoul(p, NULL, 16);
p = getenv("post_function");
if (p)
old_function = simple_strtoul(p, NULL, 16);
new_function |= (1<<POST_PHY_BIT);
if ((new_function&(1<<POST_PHY_BIT)) != (old_function&(1<<POST_PHY_BIT)))
functionn_update = 1;
new_function |= (1<<POST_MEM_BIT);
if ((new_function&(1<<POST_MEM_BIT)) != (old_function&(1<<POST_MEM_BIT)))
functionn_update = 1;
p = getenv("post_mask");
if (p) {
post_mask = simple_strtoul(p, NULL, 16);
printf("post_mask 0x%x\n", post_mask);
if ((post_mask & 1<<POST_MEM_BIT)) {
mem_level = ((post_mask >> POST_MEM_LEVEL_BIT) & POST_MEM_LEVEL_MASK);
switch (mem_level) {
case 0:
ret = do_post_mem(1);
break;
case 1:
ret = do_post_mem(1000);
break;
case 2:
ret = do_post_mem(1000000);
break;
case 3:
ret = do_post_mem(0);
break;
}
printf("mem test ... ");
if (ret < 0) {
printf("fail\n");
new_result &= ~(1<<POST_MEM_BIT);
} else {
printf("pass\n");
new_result |= (1<<POST_MEM_BIT);
}
if ((new_result&(1<<POST_MEM_BIT)) != (old_result&(1<<POST_MEM_BIT))) {
old_result &= ~(1<<POST_MEM_BIT);
old_result |= new_result&(1<<POST_MEM_BIT);
result_update = 1;
}
}
if (post_mask & 1<<POST_PHY_BIT) {
ret = NetLoop(ETHLOOP);
#ifdef CONFIG_CMD_ETHLOOP
disable_phy_loopback();
#endif
if (ret < 0) {
new_result &= ~(1<<POST_PHY_BIT);
printf("phy loopback test ... fail\n");
} else {
new_result |= (1<<POST_PHY_BIT);
printf("phy loopback test ... pass\n");
}
if ((new_result&(1<<POST_PHY_BIT)) != (old_result&(1<<POST_PHY_BIT))) {
old_result &= ~(1<<POST_PHY_BIT);
old_result |= new_result&(1<<POST_PHY_BIT);
result_update = 1;
}
}
} else {
printf("post_mask is null\n");
}
if (functionn_update | result_update) {
if (functionn_update) {
sprintf(buf, "%x", new_function);
setenv("post_function", buf);
}
if (result_update) {
sprintf(buf, "%x", old_result);
setenv("post_result", buf);
}
saveenv();
}
}
int post (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int ret;
ret = do_post();
return ret;
}
#ifdef POST_BOOT
U_BOOT_CMD(
post, CONFIG_SYS_MAXARGS, 0, post,
"POST test",
"POST test\n"
);
#endif