diff options
Diffstat (limited to 'arch/arm/mach-tegra/pmc.c')
| -rw-r--r-- | arch/arm/mach-tegra/pmc.c | 82 |
1 files changed, 57 insertions, 25 deletions
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c index 8acb881f7cf..7c7123e7557 100644 --- a/arch/arm/mach-tegra/pmc.c +++ b/arch/arm/mach-tegra/pmc.c @@ -20,6 +20,7 @@ #include <linux/io.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/tegra-powergate.h> #include "flowctrl.h" #include "fuse.h" @@ -40,15 +41,17 @@ #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 -#define TEGRA_POWERGATE_PCIE 3 -#define TEGRA_POWERGATE_VDEC 4 -#define TEGRA_POWERGATE_CPU1 9 -#define TEGRA_POWERGATE_CPU2 10 -#define TEGRA_POWERGATE_CPU3 11 - static u8 tegra_cpu_domains[] = { 0xFF, /* not available for CPU0 */ TEGRA_POWERGATE_CPU1, @@ -166,6 +169,31 @@ int tegra_pmc_cpu_remove_clamping(int cpuid) return tegra_pmc_powergate_remove_clamping(id); } +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); +} + #ifdef CONFIG_PM_SLEEP static void set_power_timers(u32 us_on, u32 us_off, unsigned long rate) { @@ -279,19 +307,17 @@ void tegra_pmc_suspend_init(void) #endif static const struct of_device_id matches[] __initconst = { + { .compatible = "nvidia,tegra124-pmc" }, { .compatible = "nvidia,tegra114-pmc" }, { .compatible = "nvidia,tegra30-pmc" }, { .compatible = "nvidia,tegra20-pmc" }, { } }; -static void __init tegra_pmc_parse_dt(void) +void __init tegra_pmc_init_irq(void) { struct device_node *np; - u32 prop; - enum tegra_suspend_mode suspend_mode; - u32 core_good_time[2] = {0, 0}; - u32 lp0_vec[2] = {0, 0}; + u32 val; np = of_find_matching_node(NULL, matches); BUG_ON(!np); @@ -300,6 +326,26 @@ static void __init tegra_pmc_parse_dt(void) tegra_pmc_invert_interrupt = of_property_read_bool(np, "nvidia,invert-interrupt"); + + val = tegra_pmc_readl(PMC_CTRL); + if (tegra_pmc_invert_interrupt) + val |= PMC_CTRL_INTR_LOW; + else + val &= ~PMC_CTRL_INTR_LOW; + tegra_pmc_writel(val, PMC_CTRL); +} + +void __init tegra_pmc_init(void) +{ + struct device_node *np; + u32 prop; + enum tegra_suspend_mode suspend_mode; + u32 core_good_time[2] = {0, 0}; + u32 lp0_vec[2] = {0, 0}; + + np = of_find_matching_node(NULL, matches); + BUG_ON(!np); + tegra_pclk = of_clk_get_by_name(np, "pclk"); WARN_ON(IS_ERR(tegra_pclk)); @@ -365,17 +411,3 @@ static void __init tegra_pmc_parse_dt(void) pmc_pm_data.suspend_mode = suspend_mode; } - -void __init tegra_pmc_init(void) -{ - u32 val; - - tegra_pmc_parse_dt(); - - val = tegra_pmc_readl(PMC_CTRL); - if (tegra_pmc_invert_interrupt) - val |= PMC_CTRL_INTR_LOW; - else - val &= ~PMC_CTRL_INTR_LOW; - tegra_pmc_writel(val, PMC_CTRL); -} |
