]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
ARM: tegra: Support reboot modes
authorThierry Reding <treding@nvidia.com>
Tue, 6 May 2014 15:04:11 +0000 (17:04 +0200)
committerStephen Warren <swarren@nvidia.com>
Wed, 7 May 2014 15:58:03 +0000 (09:58 -0600)
The boot ROM on Tegra SoCs supports booting into forced recovery mode
(RCM) by setting a bit in the PMC scratch register 0. Similarily, the
Android bootloader examines some of the bits in this register to disable
autoboot or enter recovery mode.

Support these modes by setting the corresponding bits depending on the
specified reboot command (forced-recovery, bootloader, recovery). Recent
systemd-based distributions allow this to be specified using an optional
argument to the reboot command.

Signed-off-by: Thierry Reding <treding@nvidia.com>
Tested-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
arch/arm/mach-tegra/pmc.c

index fb7920201ab4de46c654321409c39df1066e5641..7c7123e7557bef24037e00c3427d072f4f778cf3 100644 (file)
 #define PMC_REMOVE_CLAMPING            0x34
 #define PMC_PWRGATE_STATUS             0x38
 
+#define PMC_SCRATCH0                   0x50
+#define PMC_SCRATCH0_MODE_RECOVERY     (1 << 31)
+#define PMC_SCRATCH0_MODE_BOOTLOADER   (1 << 30)
+#define PMC_SCRATCH0_MODE_RCM          (1 << 1)
+#define PMC_SCRATCH0_MODE_MASK         (PMC_SCRATCH0_MODE_RECOVERY | \
+                                        PMC_SCRATCH0_MODE_BOOTLOADER | \
+                                        PMC_SCRATCH0_MODE_RCM)
+
 #define PMC_CPUPWRGOOD_TIMER   0xc8
 #define PMC_CPUPWROFF_TIMER    0xcc
 
@@ -165,6 +173,22 @@ void tegra_pmc_restart(enum reboot_mode mode, const char *cmd)
 {
        u32 val;
 
+       val = tegra_pmc_readl(PMC_SCRATCH0);
+       val &= ~PMC_SCRATCH0_MODE_MASK;
+
+       if (cmd) {
+               if (strcmp(cmd, "recovery") == 0)
+                       val |= PMC_SCRATCH0_MODE_RECOVERY;
+
+               if (strcmp(cmd, "bootloader") == 0)
+                       val |= PMC_SCRATCH0_MODE_BOOTLOADER;
+
+               if (strcmp(cmd, "forced-recovery") == 0)
+                       val |= PMC_SCRATCH0_MODE_RCM;
+       }
+
+       tegra_pmc_writel(val, PMC_SCRATCH0);
+
        val = tegra_pmc_readl(0);
        val |= 0x10;
        tegra_pmc_writel(val, 0);