[U-Boot] [RFC] Detecting coldstart on kirkwood CPUs

Hi (mostly Prafulla)!
I'm looking at detecting cold starts on the OpenRD board (and also maintain the bootcounter via this). I've come up with a slight hack which works in practice for me, but which feels a bit unsafe.
What I do is basically to reset the SYSRST duration counter just before doing the soft reset in reset_cpu() (see patch below, I do a similar thing in Linux). I've then added the following function to the board code:
#if defined(CONFIG_MISC_INIT_R) # define MS_TO_COUNT(x) ( ((x) * 1000 * 1000) / 40) int misc_init_r (void) { u32 rst_count = 0x1fffffff & readl(KW_REG_SYSRST_CNT); struct uboot_com *p = (struct uboot_com *)CONFIG_BOOTCOUNT_ADDR;
/* clear the counter for next valid read*/ writel(1 << 31, KW_REG_SYSRST_CNT);
/* If the reset has been held for over 20ms it's a cold-start, * wait for 40 to be sure * * FIXME! This should rely one some more safe metric for the future */ if ( rst_count > MS_TO_COUNT(40) ) { printf("Start type: cold\n"); p->bootcount_magic = 0x12345678; /* Clear the bootcount magic */ p->is_coldstart = is_coldstart = 1; } else { printf("Start type: warm\n"); p->is_coldstart = is_coldstart = 0; }
return 0; } #endif
i.e., just check how long the reset was held at startup. If it's longer than an empirically determined value (~40ms), then it's a cold start. Pressing the reset button, I always get cold starts (even when tapping as fast as I can), while soft resets are always warm.
But... Isn't there some better way of checking this on Kirkwood?
// Simon
[PATCH] Reset sysrst count before restarting
Signed-off-by: Simon Kagstrom simon.kagstrom@netinsight.net --- cpu/arm926ejs/kirkwood/cpu.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/cpu/arm926ejs/kirkwood/cpu.c b/cpu/arm926ejs/kirkwood/cpu.c index bab5faf..d0cdaf6 100644 --- a/cpu/arm926ejs/kirkwood/cpu.c +++ b/cpu/arm926ejs/kirkwood/cpu.c @@ -37,6 +37,7 @@ void reset_cpu(unsigned long ignored)
writel(readl(&cpureg->rstoutn_mask) | (1 << 2), &cpureg->rstoutn_mask); + writel(1 << 31, KW_REG_SYSRST_CNT); writel(readl(&cpureg->sys_soft_rst) | 1, &cpureg->sys_soft_rst); while (1) ;
participants (1)
-
Simon Kagstrom