This feature can be used to trigger special command "sysrst_cmd" using
reset key long press event
(useful for reset to factory or manufacturing mode execution)

Kirkwood SoC implements a hardware-based SYSRSTn duration counter.
When SYSRSTn is asserted low, a SYSRSTn duration counter is running.
The SYSRSTn duration counter is useful for implementing a sysrst_cmd.
Upon a long reset assertion that is greater than a pre-configured
threshold CONFIG_SYS_RST_THRESHOLD_TIME,
The counter value is stored in the SYSRSTn Length Counter Register
The counter is based on the 25-MHz reference clock (40ns)
It is a 29-bit counter, yielding a maximum counting duration of
2^29/25 MHz (21.4 seconds). When the counter reach its maximum value,
it remains at this value until counter reset is triggered by setting
bit 31 of KW_REG_SYSRST_CNT

Implementation: upon long reset assertion (> 5secs)
sysrst_cmd will be executed if pre-defined in environment variables

for-ex.
setenv sysrst_cmd "echo starting factory reset;
                   nand erase 0xa0000 0x20000;
                   echo finish ed sysrst command;"
will erase particular nand sector if triggered by this event

Signed-off-by: Prafulla Wadaskar <[email protected]>
---
 cpu/arm926ejs/kirkwood/cpu.c        |   77 +++++++++++++++++++++++++++++++++++
 include/asm-arm/arch-kirkwood/cpu.h |    2 +
 2 files changed, 79 insertions(+), 0 deletions(-)

diff --git a/cpu/arm926ejs/kirkwood/cpu.c b/cpu/arm926ejs/kirkwood/cpu.c
index 795a739..a23c61f 100644
--- a/cpu/arm926ejs/kirkwood/cpu.c
+++ b/cpu/arm926ejs/kirkwood/cpu.c
@@ -195,6 +195,78 @@ int kw_config_mpp(u32 mpp0_7, u32 mpp8_15, u32 mpp16_23, 
u32 mpp24_31,
        return 0;
 }
 
+/*
+ * SYSRSTn Duration Counter Support
+ *
+ * Kirkwood SoC implements a hardware-based SYSRSTn duration counter.
+ * When SYSRSTn is asserted low, a SYSRSTn duration counter is running.
+ * The SYSRSTn duration counter is useful for implementing a manufacturer
+ * or factory reset. Upon a long reset assertion that is greater than a
+ * pre-configured threshold CONFIG_SYS_RST_THRESHOLD_TIME,
+ * The counter value is stored in the SYSRSTn Length Counter Register
+ * The counter is based on the 25-MHz reference clock (40ns)
+ * It is a 29-bit counter, yielding a maximum counting duration of
+ * 2^29/25 MHz (21.4 seconds). When the counter reach its maximum value,
+ * it remains at this value until counter reset is triggered by setting
+ * bit 31 of KW_REG_SYSRST_CNT
+ */
+#ifndef CONFIG_SYS_RST_THRESHOLD_TIME
+#define CONFIG_SYS_RST_THRESHOLD_TIME  5
+#endif /* CONFIG_SYS_RST_THRESHOLD_TIME */
+static void kw_sysrst_action(void)
+{
+#ifdef CONFIG_CMD_RUN
+       char cmd[BUFLEN];
+       char img[BUFLEN * 2];
+       char *argv[3];
+
+       printf("Starting %s process...\n", __FUNCTION__);
+       sprintf(cmd, "run ");
+       sprintf(img, "sysrst_cmd");
+       argv[0] = cmd;
+       argv[1] = img;
+       if ((do_run(NULL, 0, 2, argv)) != 0x0) {
+               printf("Error.. %s failed\n", __FUNCTION__);
+       } else {
+               printf("%s process finished\n", __FUNCTION__);
+       }
+#else  /* CONFIG_CMD_RUN */
+       printf("Error.. %s needs run command support\n", __FUNCTION__);
+#endif /* CONFIG_CMD_RUN */
+}
+
+static void kw_sysrst_check(void)
+{
+       u32 sysrst_cnt = 0;
+
+       /* read SysRst Length counter register (bits 28:0) */
+       sysrst_cnt = (0x1fffffff & readl(KW_REG_SYSRST_CNT));
+       printf("H/w Rst hold time: %d.%d secs\n",
+               sysrst_cnt/SYSRST_CNT_1SEC_VAL,
+               sysrst_cnt%SYSRST_CNT_1SEC_VAL);
+       /* clear the counter for next valid read*/
+       writel(1 << 31, KW_REG_SYSRST_CNT);
+
+       /*
+        * no action if read count value is less than
+        * CONFIG_SYS_RST_THRESHOLD_TIME in seconds
+        */
+       if (sysrst_cnt < SYSRST_CNT_1SEC_VAL * CONFIG_SYS_RST_THRESHOLD_TIME)
+               return;
+
+       /*
+        * sysrst_action:
+        * if H/w Reset key is pressed and hold for time
+        * more than CONFIG_SYS_RST_THRESHOLD_TIME seconds
+        */
+       if (getenv("sysrst_cmd") == NULL) {
+               printf("Error.. %s failed, check sysrst_cmd\n",
+                       __FUNCTION__);
+               return;
+       } else
+               kw_sysrst_action();
+}
+
 #if defined(CONFIG_DISPLAY_CPUINFO)
 int print_cpuinfo(void)
 {
@@ -298,6 +370,11 @@ int arch_misc_init(void)
        temp = get_cr();
        set_cr(temp & ~CR_V);
 
+#ifdef CONFIG_SYS_TIME_RST2FACTORY
+       /* checks and execute resset to factory event */
+       kw_sysrst_check();
+#endif /* CONFIG_SYS_TIME_RST2FACTORY */
+
        return 0;
 }
 #endif /* CONFIG_ARCH_MISC_INIT */
diff --git a/include/asm-arm/arch-kirkwood/cpu.h 
b/include/asm-arm/arch-kirkwood/cpu.h
index d1440af..b3022a3 100644
--- a/include/asm-arm/arch-kirkwood/cpu.h
+++ b/include/asm-arm/arch-kirkwood/cpu.h
@@ -36,6 +36,8 @@
                ((_x ? KW_EGIGA0_BASE : KW_EGIGA1_BASE) + 0x44c)
 
 #define KW_REG_DEVICE_ID               (KW_MPP_BASE + 0x34)
+#define KW_REG_SYSRST_CNT              (KW_MPP_BASE + 0x50)
+#define SYSRST_CNT_1SEC_VAL            (25*1000000)
 #define KW_REG_MPP_OUT_DRV_REG         (KW_MPP_BASE + 0xE0)
 
 enum memory_bank {
-- 
1.5.3.4

_______________________________________________
U-Boot mailing list
[email protected]
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to