power: reset: rockchip-reboot: rk3368 support reboot with argument
authorHuang, Tao <huangtao@rock-chips.com>
Thu, 12 Feb 2015 08:38:12 +0000 (16:38 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Thu, 12 Feb 2015 08:39:01 +0000 (16:39 +0800)
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
drivers/power/reset/rockchip-reboot.c

index 93f1c3f204f1ca55b395931761db55c53afdd7e0..1ab43fd35654a2d2650a6609e6ab85efe77a99b2 100644 (file)
 #include <linux/regmap.h>
 #include <linux/of.h>
 #include <linux/mfd/syscon.h>
+#include <linux/rockchip/common.h>
 #include <asm/system_misc.h>
 
+/* high 24 bits is tag, low 8 bits is type */
+#define SYS_LOADER_REBOOT_FLAG   0x5242C300
+#define SYS_KERNRL_REBOOT_FLAG   0xC3524200
+
+enum {
+       BOOT_NORMAL = 0,/* normal boot */
+       BOOT_LOADER,    /* enter loader rockusb mode */
+       BOOT_MASKROM,   /* enter maskrom rockusb mode (not support now) */
+       BOOT_RECOVER,   /* enter recover */
+       BOOT_NORECOVER, /* do not enter recover */
+       BOOT_SECONDOS,  /* boot second OS (not support now) */
+       BOOT_WIPEDATA,  /* enter recover and wipe data */
+       BOOT_WIPEALL,   /* enter recover and wipe all data */
+       BOOT_CHECKIMG,  /* check firmware img with backup part in loader mode */
+       BOOT_FASTBOOT,  /* enter fast boot mode */
+       BOOT_SECUREBOOT_DISABLE,
+       BOOT_CHARGING,  /* enter charge mode */
+       BOOT_MAX,       /* MAX VALID BOOT TYPE */
+};
+
 static struct regmap *cru;
+static struct regmap *pmugrf;
 
 #define RK3368_CRU_APLLB_CON3  0x0c
 #define RK3368_CRU_APLLL_CON3  0x01c
@@ -25,9 +47,21 @@ static struct regmap *cru;
 #define RK3368_CRU_GLB_SRST_FST_VALUE  0x280
 #define RK3368_CRU_GLB_SRST_SND_VALUE  0x284
 #define RK3368_CRU_GLB_RST_CON 0x388
+#define RK3368_CRU_GLB_RST_ST  0x38c
+
+#define RK3368_PMUGRF_OS_REG0  0x200
+#define RK3368_PMUGRF_OS_REG1  0x204
 
 static void rk3368_reboot(char str, const char *cmd)
 {
+       u32 flag, mode;
+
+       rockchip_restart_get_boot_mode(cmd, &flag, &mode);
+       /* for loader */
+       regmap_write(pmugrf, RK3368_PMUGRF_OS_REG0, flag);
+       /* for linux */
+       regmap_write(pmugrf, RK3368_PMUGRF_OS_REG1, mode);
+
        /* pll enter slow mode */
        regmap_write(cru, RK3368_CRU_APLLB_CON3, 0x03000000);
        regmap_write(cru, RK3368_CRU_APLLL_CON3, 0x03000000);
@@ -40,6 +74,7 @@ static void rk3368_reboot(char str, const char *cmd)
 
 static __init int rk3368_reboot_init(struct platform_device *pdev)
 {
+       u32 flag, mode, rst_st;
        struct device_node *np = pdev->dev.of_node;
 
        cru = syscon_regmap_lookup_by_phandle(np, "rockchip,cru");
@@ -48,6 +83,24 @@ static __init int rk3368_reboot_init(struct platform_device *pdev)
                return PTR_ERR(cru);
        }
 
+       pmugrf = syscon_regmap_lookup_by_phandle(np, "rockchip,pmugrf");
+       if (IS_ERR(pmugrf)) {
+               dev_err(&pdev->dev, "No rockchip,pmugrf phandle specified");
+               return PTR_ERR(pmugrf);
+       }
+
+       regmap_read(pmugrf, RK3368_PMUGRF_OS_REG0, &flag);
+       regmap_read(pmugrf, RK3368_PMUGRF_OS_REG1, &mode);
+       regmap_read(cru, RK3368_CRU_GLB_RST_ST, &rst_st);
+
+       if (flag == (SYS_KERNRL_REBOOT_FLAG | BOOT_RECOVER))
+               mode = BOOT_MODE_RECOVERY;
+       if (rst_st & ((1 << 4) | (1 << 5)))
+               mode = BOOT_MODE_WATCHDOG;
+       else if (rst_st & ((1 << 2) | (1 << 3)))
+               mode = BOOT_MODE_TSADC;
+       rockchip_boot_mode_init(flag, mode);
+
        arm_pm_restart = rk3368_reboot;
 
        return 0;