ARM: tegra11x: Define ncpu residency for 2 clusters
[linux-3.10.git] / arch / arm / mach-tegra / pm.c
index 57fcf55..a63471d 100644 (file)
@@ -3,7 +3,7 @@
  *
  * CPU complex suspend & resume functions for Tegra SoCs
  *
- * Copyright (c) 2009-2011, NVIDIA Corporation.
+ * Copyright (c) 2009-2013, NVIDIA Corporation.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include <linux/vmalloc.h>
 #include <linux/memblock.h>
 #include <linux/console.h>
+#include <linux/tegra_audio.h>
+
+#include <trace/events/power.h>
+#include <trace/events/nvsecurity.h>
 
 #include <asm/cacheflush.h>
-#include <asm/hardware/cache-l2x0.h>
 #include <asm/idmap.h>
 #include <asm/localtimer.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
+#include <asm/suspend.h>
+#include <asm/smp_plat.h>
 
 #include <mach/irqs.h>
 #include <mach/powergate.h>
+#include <mach/hardware.h>
 
 #include "board.h"
 #include "clock.h"
+#include "common.h"
 #include "cpuidle.h"
-#include "flowctrl.h"
 #include "fuse.h"
 #include "gic.h"
 #include "iomap.h"
 #include "reset.h"
 #include "sleep.h"
 #include "timer.h"
-#include "reset.h"
+#include "dvfs.h"
+#include "cpu-tegra.h"
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/nvpower.h>
 
 struct suspend_context {
        /*
@@ -94,9 +104,6 @@ struct suspend_context {
 };
 
 #ifdef CONFIG_PM_SLEEP
-#if USE_TEGRA_CPU_SUSPEND
-void *tegra_cpu_context;       /* non-cacheable page for CPU context */
-#endif
 phys_addr_t tegra_pgd_phys;    /* pgd used by hotplug & LP2 bootup */
 static pgd_t *tegra_pgd;
 static DEFINE_SPINLOCK(tegra_lp2_lock);
@@ -121,6 +128,7 @@ struct suspend_context tegra_sctx;
 #define TEGRA_POWER_EFFECT_LP0         (1 << 14)  /* enter LP0 when CPU pwr gated */
 #define TEGRA_POWER_CPU_PWRREQ_POLARITY (1 << 15)  /* CPU power request polarity */
 #define TEGRA_POWER_CPU_PWRREQ_OE      (1 << 16)  /* CPU power request enable */
+#define TEGRA_POWER_CPUPWRGOOD_EN      (1 << 19)  /* CPU power good enable */
 
 #define PMC_CTRL               0x0
 #define PMC_CTRL_LATCH_WAKEUPS (1 << 5)
@@ -129,16 +137,29 @@ struct suspend_context tegra_sctx;
 #define PMC_DPAD_ORIDE         0x1C
 #define PMC_WAKE_DELAY         0xe0
 #define PMC_DPD_SAMPLE         0x20
+#ifdef CONFIG_ARCH_TEGRA_14x_SOC
+#define PMC_DPD_ENABLE         0x24
+#endif
+#define PMC_IO_DPD_REQ          0x1B8
+#define PMC_IO_DPD2_REQ         0x1C0
+
 
 #define PMC_WAKE_STATUS                0x14
 #define PMC_SW_WAKE_STATUS     0x18
 #define PMC_COREPWRGOOD_TIMER  0x3c
-#define PMC_SCRATCH0           0x50
-#define PMC_SCRATCH1           0x54
 #define PMC_CPUPWRGOOD_TIMER   0xc8
 #define PMC_CPUPWROFF_TIMER    0xcc
 #define PMC_COREPWROFF_TIMER   PMC_WAKE_DELAY
 
+#define PMC_PWRGATE_TOGGLE     0x30
+#define PWRGATE_TOGGLE_START   (1 << 8)
+#define UN_PWRGATE_CPU         \
+       (PWRGATE_TOGGLE_START | TEGRA_CPU_POWERGATE_ID(TEGRA_POWERGATE_CPU))
+
+#ifdef CONFIG_TEGRA_CLUSTER_CONTROL
+#define PMC_SCRATCH4_WAKE_CLUSTER_MASK (1<<31)
+#endif
+
 #define CLK_RESET_CCLK_BURST   0x20
 #define CLK_RESET_CCLK_DIVIDER  0x24
 #define CLK_RESET_PLLC_BASE    0x80
@@ -153,6 +174,10 @@ struct suspend_context tegra_sctx;
 #define CLK_RESET_SOURCE_CSITE 0x1d4
 
 #define CLK_RESET_CCLK_BURST_POLICY_SHIFT 28
+#define CLK_RESET_CCLK_RUN_POLICY_SHIFT    4
+#define CLK_RESET_CCLK_IDLE_POLICY_SHIFT   0
+#define CLK_RESET_CCLK_IDLE_POLICY        1
+#define CLK_RESET_CCLK_RUN_POLICY         2
 #define CLK_RESET_CCLK_BURST_POLICY_PLLM   3
 #define CLK_RESET_CCLK_BURST_POLICY_PLLX   8
 
@@ -164,17 +189,13 @@ struct suspend_context tegra_sctx;
 #define MC_SECURITY_SIZE       0x70
 #define MC_SECURITY_CFG2       0x7c
 
+#ifdef CONFIG_ARCH_TEGRA_HAS_CL_DVFS
+static struct clk *tegra_dfll;
+#endif
 static struct clk *tegra_pclk;
 static const struct tegra_suspend_platform_data *pdata;
 static enum tegra_suspend_mode current_suspend_mode = TEGRA_SUSPEND_NONE;
 
-static const char *tegra_suspend_name[TEGRA_MAX_SUSPEND_MODE] = {
-       [TEGRA_SUSPEND_NONE]    = "none",
-       [TEGRA_SUSPEND_LP2]     = "lp2",
-       [TEGRA_SUSPEND_LP1]     = "lp1",
-       [TEGRA_SUSPEND_LP0]     = "lp0",
-};
-
 #if defined(CONFIG_TEGRA_CLUSTER_CONTROL) && INSTRUMENT_CLUSTER_SWITCH
 enum tegra_cluster_switch_time_id {
        tegra_cluster_switch_time_id_start = 0,
@@ -204,6 +225,13 @@ static unsigned long
 #endif
 
 #ifdef CONFIG_PM_SLEEP
+static const char *tegra_suspend_name[TEGRA_MAX_SUSPEND_MODE] = {
+       [TEGRA_SUSPEND_NONE]    = "none",
+       [TEGRA_SUSPEND_LP2]     = "lp2",
+       [TEGRA_SUSPEND_LP1]     = "lp1",
+       [TEGRA_SUSPEND_LP0]     = "lp0",
+};
+
 unsigned long tegra_cpu_power_good_time(void)
 {
        if (WARN_ON_ONCE(!pdata))
@@ -228,6 +256,33 @@ unsigned long tegra_cpu_lp2_min_residency(void)
        return pdata->cpu_lp2_min_residency;
 }
 
+#ifdef CONFIG_ARCH_TEGRA_HAS_SYMMETRIC_CPU_PWR_GATE
+unsigned long tegra_min_residency_crail(void)
+{
+       return pdata->min_residency_crail;
+}
+#endif
+
+static void suspend_cpu_dfll_mode(void)
+{
+#ifdef CONFIG_ARCH_TEGRA_HAS_CL_DVFS
+       /* If DFLL is used as CPU clock source go to open loop mode */
+       if (!is_lp_cluster() && tegra_dfll &&
+           tegra_dvfs_rail_is_dfll_mode(tegra_cpu_rail))
+               tegra_clk_cfg_ex(tegra_dfll, TEGRA_CLK_DFLL_LOCK, 0);
+#endif
+}
+
+static void resume_cpu_dfll_mode(void)
+{
+#ifdef CONFIG_ARCH_TEGRA_HAS_CL_DVFS
+       /* If DFLL is used as CPU clock source restore closed loop mode */
+       if (!is_lp_cluster() && tegra_dfll &&
+           tegra_dvfs_rail_is_dfll_mode(tegra_cpu_rail))
+               tegra_clk_cfg_ex(tegra_dfll, TEGRA_CLK_DFLL_LOCK, 1);
+#endif
+}
+
 /*
  * create_suspend_pgtable
  *
@@ -240,8 +295,9 @@ static __init int create_suspend_pgtable(void)
        if (!tegra_pgd)
                return -ENOMEM;
 
+       /* Only identity-map size of lowmem (high_memory - PAGE_OFFSET) */
        identity_mapping_add(tegra_pgd, phys_to_virt(PHYS_OFFSET),
-               phys_to_virt(PHYS_OFFSET) + memblock_phys_mem_size(), 0);
+               high_memory, 0);
        identity_mapping_add(tegra_pgd, IO_IRAM_VIRT,
                IO_IRAM_VIRT + SECTION_SIZE, 0);
 
@@ -251,63 +307,6 @@ static __init int create_suspend_pgtable(void)
        return 0;
 }
 
-/*
- * alloc_suspend_context
- *
- * Allocate a non-cacheable page to hold the CPU contexts.
- * The standard ARM CPU context save functions don't work if there's
- * an external L2 cache controller (like a PL310) in system.
- */
-static __init int alloc_suspend_context(void)
-{
-#if USE_TEGRA_CPU_SUSPEND
-       pgprot_t prot = __pgprot_modify(pgprot_kernel, L_PTE_MT_MASK,
-                                       L_PTE_MT_BUFFERABLE | L_PTE_XN);
-       struct page *ctx_page;
-       unsigned long ctx_virt = 0;
-       pgd_t *pgd;
-       pmd_t *pmd;
-       pte_t *pte;
-
-       ctx_page = alloc_pages(GFP_KERNEL, 0);
-       if (IS_ERR_OR_NULL(ctx_page))
-               goto fail;
-
-       tegra_cpu_context = vm_map_ram(&ctx_page, 1, -1, prot);
-       if (IS_ERR_OR_NULL(tegra_cpu_context))
-               goto fail;
-
-       /* Add the context page to our private pgd. */
-       ctx_virt = (unsigned long)tegra_cpu_context;
-
-       pgd = tegra_pgd + pgd_index(ctx_virt);
-       if (!pgd_present(*pgd))
-               goto fail;
-       pmd = pmd_offset(pgd, ctx_virt);
-       if (!pmd_none(*pmd))
-               goto fail;
-       pte = pte_alloc_kernel(pmd, ctx_virt);
-       if (!pte)
-               goto fail;
-
-       set_pte_ext(pte, mk_pte(ctx_page, prot), 0);
-
-       outer_clean_range(__pa(pmd), __pa(pmd + 1));
-
-       return 0;
-
-fail:
-       if (ctx_page)
-               __free_page(ctx_page);
-       if (ctx_virt)
-               vm_unmap_ram((void*)ctx_virt, 1);
-       tegra_cpu_context = NULL;
-       return -ENOMEM;
-#else
-       return 0;
-#endif
-}
-
 /* ensures that sufficient time is passed for a register write to
  * serialize into the 32KHz domain */
 static void pmc_32kwritel(u32 val, unsigned long offs)
@@ -351,66 +350,85 @@ static void set_power_timers(unsigned long us_on, unsigned long us_off,
  */
 static void restore_cpu_complex(u32 mode)
 {
-       int cpu = smp_processor_id();
+       int cpu = cpu_logical_map(smp_processor_id());
        unsigned int reg;
+#if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
+       unsigned int policy;
+#endif
 
-       BUG_ON(cpu != 0);
-
-       /* restore original PLL settings */
-       writel(tegra_sctx.pllx_misc, clk_rst + CLK_RESET_PLLX_MISC);
-       writel(tegra_sctx.pllx_base, clk_rst + CLK_RESET_PLLX_BASE);
-       writel(tegra_sctx.pllp_misc, clk_rst + CLK_RESET_PLLP_MISC);
-       writel(tegra_sctx.pllp_base, clk_rst + CLK_RESET_PLLP_BASE);
-       writel(tegra_sctx.pllp_outa, clk_rst + CLK_RESET_PLLP_OUTA);
-       writel(tegra_sctx.pllp_outb, clk_rst + CLK_RESET_PLLP_OUTB);
-
+/*
+ * On Tegra11x PLLX and CPU burst policy is either preserved across LP2,
+ * or restored by common clock suspend/resume procedures. Hence, we don't
+ * need it here.
+ */
+#if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
        /* Is CPU complex already running on PLLX? */
        reg = readl(clk_rst + CLK_RESET_CCLK_BURST);
-       reg &= 0xF;
-       if (reg != 0x8) {
-               /* restore original burst policy setting; PLLX state restored
-                * by CPU boot-up code - wait for PLL stabilization if PLLX
-                * was enabled */
+       policy = (reg >> CLK_RESET_CCLK_BURST_POLICY_SHIFT) & 0xF;
+
+       if (policy == CLK_RESET_CCLK_IDLE_POLICY)
+               reg = (reg >> CLK_RESET_CCLK_IDLE_POLICY_SHIFT) & 0xF;
+       else if (policy == CLK_RESET_CCLK_RUN_POLICY)
+               reg = (reg >> CLK_RESET_CCLK_RUN_POLICY_SHIFT) & 0xF;
+       else
+               BUG();
 
-               reg = readl(clk_rst + CLK_RESET_PLLX_BASE);
-               /* mask out bit 27 - not to check PLL lock bit */
-               BUG_ON((reg & (~(1 << 27))) !=
-                               (tegra_sctx.pllx_base & (~(1 << 27))));
+       if (reg != CLK_RESET_CCLK_BURST_POLICY_PLLX) {
+               /* restore PLLX settings if CPU is on different PLL */
+               writel(tegra_sctx.pllx_misc, clk_rst + CLK_RESET_PLLX_MISC);
+               writel(tegra_sctx.pllx_base, clk_rst + CLK_RESET_PLLX_BASE);
 
+               /* wait for PLL stabilization if PLLX was enabled */
                if (tegra_sctx.pllx_base & (1<<30)) {
 #if USE_PLL_LOCK_BITS
                        /* Enable lock detector */
                        reg = readl(clk_rst + CLK_RESET_PLLX_MISC);
                        reg |= 1<<18;
                        writel(reg, clk_rst + CLK_RESET_PLLX_MISC);
-                       while (!(readl(clk_rst + CLK_RESET_PLLX_BASE) &&
+                       while (!(readl(clk_rst + CLK_RESET_PLLX_BASE) &
                                 (1<<27)))
                                cpu_relax();
+
+                       udelay(PLL_POST_LOCK_DELAY);
 #else
                        udelay(300);
 #endif
                }
+       }
+
+       /* Restore original burst policy setting for calls resulting from CPU
+          LP2 in idle or system suspend; keep cluster switch prolog setting
+          intact. */
+       if (!(mode & TEGRA_POWER_CLUSTER_MASK)) {
                writel(tegra_sctx.cclk_divider, clk_rst +
                       CLK_RESET_CCLK_DIVIDER);
                writel(tegra_sctx.cpu_burst, clk_rst +
                       CLK_RESET_CCLK_BURST);
        }
-
+#endif
        writel(tegra_sctx.clk_csite_src, clk_rst + CLK_RESET_SOURCE_CSITE);
 
        /* Do not power-gate CPU 0 when flow controlled */
-       reg = flowctrl_read_cpu_csr(cpu);
+       reg = readl(FLOW_CTRL_CPU_CSR(cpu));
        reg &= ~FLOW_CTRL_CSR_WFE_BITMAP;       /* clear wfe bitmap */
        reg &= ~FLOW_CTRL_CSR_WFI_BITMAP;       /* clear wfi bitmap */
        reg &= ~FLOW_CTRL_CSR_ENABLE;           /* clear enable */
        reg |= FLOW_CTRL_CSR_INTR_FLAG;         /* clear intr */
        reg |= FLOW_CTRL_CSR_EVENT_FLAG;        /* clear event */
-       flowctrl_write_cpu_csr(cpu, reg);
+       flowctrl_writel(reg, FLOW_CTRL_CPU_CSR(cpu));
 
        /* If an immedidate cluster switch is being perfomed, restore the
-          local timer registers. See save_cpu_complex() for the details. */
-       if (mode & (TEGRA_POWER_CLUSTER_MASK | TEGRA_POWER_CLUSTER_IMMEDIATE))
-               tegra_twd_resume(&tegra_sctx.twd);
+          local timer registers. For calls resulting from CPU LP2 in
+          idle or system suspend, the local timer was shut down and
+          timekeeping switched over to the global system timer. In this
+          case keep local timer disabled, and restore only periodic load. */
+#ifdef CONFIG_HAVE_ARM_TWD
+       if (!(mode & (TEGRA_POWER_CLUSTER_MASK |
+                     TEGRA_POWER_CLUSTER_IMMEDIATE))) {
+               tegra_sctx.twd.twd_ctrl = 0;
+       }
+       tegra_twd_resume(&tegra_sctx.twd);
+#endif
 }
 
 /*
@@ -423,7 +441,7 @@ static void restore_cpu_complex(u32 mode)
  */
 static void suspend_cpu_complex(u32 mode)
 {
-       int cpu = smp_processor_id();
+       int cpu = cpu_logical_map(smp_processor_id());
        unsigned int reg;
        int i;
 
@@ -442,14 +460,11 @@ static void suspend_cpu_complex(u32 mode)
        tegra_sctx.pllp_misc = readl(clk_rst + CLK_RESET_PLLP_MISC);
        tegra_sctx.cclk_divider = readl(clk_rst + CLK_RESET_CCLK_DIVIDER);
 
-       /* If an immedidate cluster switch is being perfomed, save the
-          local timer registers. For calls resulting from CPU LP2 in
-          idle or system suspend, the local timer is shut down and
-          timekeeping switches over to the global system timer. */
-       if (mode & (TEGRA_POWER_CLUSTER_MASK | TEGRA_POWER_CLUSTER_IMMEDIATE))
-               tegra_twd_suspend(&tegra_sctx.twd);
+#ifdef CONFIG_HAVE_ARM_TWD
+       tegra_twd_suspend(&tegra_sctx.twd);
+#endif
 
-       reg = flowctrl_read_cpu_csr(cpu);
+       reg = readl(FLOW_CTRL_CPU_CSR(cpu));
        reg &= ~FLOW_CTRL_CSR_WFE_BITMAP;       /* clear wfe bitmap */
        reg &= ~FLOW_CTRL_CSR_WFI_BITMAP;       /* clear wfi bitmap */
        reg |= FLOW_CTRL_CSR_INTR_FLAG;         /* clear intr flag */
@@ -460,27 +475,21 @@ static void suspend_cpu_complex(u32 mode)
        reg |= FLOW_CTRL_CSR_WFI_CPU0 << cpu;   /* enable power gating on wfi */
 #endif
        reg |= FLOW_CTRL_CSR_ENABLE;            /* enable power gating */
-       flowctrl_write_cpu_csr(cpu, reg);
+       flowctrl_writel(reg, FLOW_CTRL_CPU_CSR(cpu));
 
        for (i = 0; i < num_possible_cpus(); i++) {
                if (i == cpu)
                        continue;
-               reg = flowctrl_read_cpu_csr(i);
+               reg = readl(FLOW_CTRL_CPU_CSR(i));
                reg |= FLOW_CTRL_CSR_EVENT_FLAG;
                reg |= FLOW_CTRL_CSR_INTR_FLAG;
-               flowctrl_write_cpu_csr(i, reg);
+               flowctrl_writel(reg, FLOW_CTRL_CPU_CSR(i));
        }
 
-       tegra_gic_cpu_disable();
-#ifndef CONFIG_ARCH_TEGRA_2x_SOC
-       /* Tegra3 enters LPx states via WFI - do not propagate legacy IRQs
-          to CPU core to avoid fall through WFI (IRQ-to-flow controller wake
-          path is not affected). */
-       tegra_gic_pass_through_disable();
-#endif
+       tegra_gic_cpu_disable(true);
 }
 
-void tegra_clear_cpu_in_lp2(int cpu)
+void tegra_clear_cpu_in_pd(int cpu)
 {
        spin_lock(&tegra_lp2_lock);
        BUG_ON(!cpumask_test_cpu(cpu, &tegra_in_lp2));
@@ -496,7 +505,7 @@ void tegra_clear_cpu_in_lp2(int cpu)
        spin_unlock(&tegra_lp2_lock);
 }
 
-bool tegra_set_cpu_in_lp2(int cpu)
+bool tegra_set_cpu_in_pd(int cpu)
 {
        bool last_cpu = false;
 
@@ -514,7 +523,7 @@ bool tegra_set_cpu_in_lp2(int cpu)
        if ((cpu == 0) && cpumask_equal(&tegra_in_lp2, cpu_online_mask))
                last_cpu = true;
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
-       else
+       else if (cpu == 1)
                tegra2_cpu_set_resettable_soon();
 #endif
 
@@ -522,18 +531,59 @@ bool tegra_set_cpu_in_lp2(int cpu)
        return last_cpu;
 }
 
-unsigned int tegra_idle_lp2_last(unsigned int sleep_time, unsigned int flags)
+static void tegra_sleep_core(enum tegra_suspend_mode mode,
+                            unsigned long v2p)
 {
-       u32 mode;       /* hardware + software power mode flags */
+#ifdef CONFIG_TRUSTED_FOUNDATIONS
+       outer_flush_range(__pa(&tegra_resume_timestamps_start),
+                         __pa(&tegra_resume_timestamps_end));
+
+       if (mode == TEGRA_SUSPEND_LP0) {
+               trace_smc_sleep_core(NVSEC_SMC_START);
+
+               tegra_generic_smc(0xFFFFFFFC, 0xFFFFFFE3,
+                                 virt_to_phys(tegra_resume));
+       } else {
+               trace_smc_sleep_core(NVSEC_SMC_START);
+
+               tegra_generic_smc(0xFFFFFFFC, 0xFFFFFFE6,
+                                 (TEGRA_RESET_HANDLER_BASE +
+                                  tegra_cpu_reset_handler_offset));
+       }
+
+       trace_smc_sleep_core(NVSEC_SMC_DONE);
+#endif
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+       cpu_suspend(v2p, tegra2_sleep_core_finish);
+#else
+       cpu_suspend(v2p, tegra3_sleep_core_finish);
+#endif
+}
+
+static inline void tegra_sleep_cpu(unsigned long v2p)
+{
+       cpu_suspend(v2p, tegra_sleep_cpu_finish);
+}
+
+unsigned int tegra_idle_power_down_last(unsigned int sleep_time,
+                                       unsigned int flags)
+{
+       u32 reg;
        unsigned int remain;
+#if defined(CONFIG_CACHE_L2X0) && !defined(CONFIG_ARCH_TEGRA_14x_SOC)
+       pgd_t *pgd;
+#endif
 
        /* Only the last cpu down does the final suspend steps */
-       mode = readl(pmc + PMC_CTRL);
-       mode |= TEGRA_POWER_CPU_PWRREQ_OE;
-       mode |= TEGRA_POWER_PWRREQ_OE;
-       mode &= ~TEGRA_POWER_EFFECT_LP0;
-       pmc_32kwritel(mode, PMC_CTRL);
-       mode |= flags;
+       reg = readl(pmc + PMC_CTRL);
+       reg |= TEGRA_POWER_CPU_PWRREQ_OE;
+       if (pdata->combined_req)
+               reg &= ~TEGRA_POWER_PWRREQ_OE;
+       else
+               reg |= TEGRA_POWER_PWRREQ_OE;
+
+       reg &= ~TEGRA_POWER_EFFECT_LP0;
+       writel(reg, pmc + PMC_CTRL);
 
        tegra_cluster_switch_time(flags, tegra_cluster_switch_time_id_start);
 
@@ -542,40 +592,106 @@ unsigned int tegra_idle_lp2_last(unsigned int sleep_time, unsigned int flags)
         * are in LP2 state and irqs are disabled
         */
        if (flags & TEGRA_POWER_CLUSTER_MASK) {
-               set_power_timers(pdata->cpu_timer, 0,
+               trace_nvcpu_cluster(NVPOWER_CPU_CLUSTER_START);
+               set_power_timers(pdata->cpu_timer, 2,
                        clk_get_rate_all_locked(tegra_pclk));
-               tegra_cluster_switch_prolog(mode);
+               if (flags & TEGRA_POWER_CLUSTER_G) {
+                       /*
+                        * To reduce the vdd_cpu up latency when LP->G
+                        * transition. Before the transition, enable
+                        * the vdd_cpu rail.
+                        */
+                       if (is_lp_cluster()) {
+#if defined(CONFIG_ARCH_TEGRA_HAS_SYMMETRIC_CPU_PWR_GATE)
+                               reg = readl(FLOW_CTRL_CPU_PWR_CSR);
+                               reg |= FLOW_CTRL_CPU_PWR_CSR_RAIL_ENABLE;
+                               writel(reg, FLOW_CTRL_CPU_PWR_CSR);
+#else
+                               writel(UN_PWRGATE_CPU,
+                                      pmc + PMC_PWRGATE_TOGGLE);
+#endif
+                       }
+               }
+               tegra_cluster_switch_prolog(flags);
        } else {
+               suspend_cpu_dfll_mode();
                set_power_timers(pdata->cpu_timer, pdata->cpu_off_timer,
                        clk_get_rate_all_locked(tegra_pclk));
+#if defined(CONFIG_ARCH_TEGRA_HAS_SYMMETRIC_CPU_PWR_GATE)
+               reg = readl(FLOW_CTRL_CPU_CSR(0));
+               reg &= ~FLOW_CTRL_CSR_ENABLE_EXT_MASK;
+               if (is_lp_cluster()) {
+                       /* for LP cluster, there is no option for rail gating */
+                       if ((flags & TEGRA_POWER_CLUSTER_PART_MASK) ==
+                                               TEGRA_POWER_CLUSTER_PART_MASK)
+                               reg |= FLOW_CTRL_CSR_ENABLE_EXT_EMU;
+                       else if (flags)
+                               reg |= FLOW_CTRL_CSR_ENABLE_EXT_NCPU;
+               }
+               else {
+                       if (flags & TEGRA_POWER_CLUSTER_PART_CRAIL)
+                               reg |= FLOW_CTRL_CSR_ENABLE_EXT_CRAIL;
+                       if (flags & TEGRA_POWER_CLUSTER_PART_NONCPU)
+                               reg |= FLOW_CTRL_CSR_ENABLE_EXT_NCPU;
+               }
+               writel(reg, FLOW_CTRL_CPU_CSR(0));
+#endif
        }
 
        if (sleep_time)
-               tegra_lp2_set_trigger(sleep_time);
+               tegra_pd_set_trigger(sleep_time);
 
        cpu_cluster_pm_enter();
-       suspend_cpu_complex(mode);
+       suspend_cpu_complex(flags);
        tegra_cluster_switch_time(flags, tegra_cluster_switch_time_id_prolog);
+#ifdef CONFIG_CACHE_L2X0
        flush_cache_all();
+#ifdef CONFIG_ARCH_TEGRA_14x_SOC
        outer_flush_all();
+#else
+       /*
+        * No need to flush complete L2. Cleaning kernel and IO mappings
+        * is enough for the LP code sequence that has L2 disabled but
+        * MMU on.
+        */
+       pgd = cpu_get_pgd();
+       outer_clean_range(__pa(pgd + USER_PTRS_PER_PGD),
+                         __pa(pgd + PTRS_PER_PGD));
+#endif
        outer_disable();
-
+#endif
        tegra_sleep_cpu(PHYS_OFFSET - PAGE_OFFSET);
 
-#ifdef CONFIG_CACHE_L2X0
-       l2x0_enable();
+#ifdef CONFIG_ARCH_TEGRA_14x_SOC
+       tegra_init_cache(true);
+#else
+       tegra_init_cache(false);
 #endif
+
+#ifdef CONFIG_TRUSTED_FOUNDATIONS
+#ifndef CONFIG_ARCH_TEGRA_11x_SOC
+       trace_smc_wake(tegra_resume_smc_entry_time, NVSEC_SMC_START);
+       trace_smc_wake(tegra_resume_smc_exit_time, NVSEC_SMC_DONE);
+#endif
+#endif
+
        tegra_cluster_switch_time(flags, tegra_cluster_switch_time_id_switch);
-       restore_cpu_complex(mode);
+       restore_cpu_complex(flags);
        cpu_cluster_pm_exit();
 
-       remain = tegra_lp2_timer_remain();
+       remain = tegra_pd_timer_remain();
        if (sleep_time)
-               tegra_lp2_set_trigger(0);
-
-       if (flags & TEGRA_POWER_CLUSTER_MASK)
-               tegra_cluster_switch_epilog(mode);
+               tegra_pd_set_trigger(0);
 
+       if (flags & TEGRA_POWER_CLUSTER_MASK) {
+               tegra_cluster_switch_epilog(flags);
+               if (is_idle_task(current))
+                       trace_nvcpu_cluster_rcuidle(NVPOWER_CPU_CLUSTER_DONE);
+               else
+                       trace_nvcpu_cluster(NVPOWER_CPU_CLUSTER_DONE);
+       } else {
+               resume_cpu_dfll_mode();
+       }
        tegra_cluster_switch_time(flags, tegra_cluster_switch_time_id_epilog);
 
 #if INSTRUMENT_CLUSTER_SWITCH
@@ -617,8 +733,10 @@ static void tegra_common_resume(void)
        void __iomem *emc = IO_ADDRESS(TEGRA_EMC_BASE);
 #endif
 
-       /* Clear DPD sample */
-       writel(0x0, pmc + PMC_DPD_SAMPLE);
+#ifdef CONFIG_ARCH_TEGRA_14x_SOC
+       /* Clear DPD Enable */
+       writel(0x0, pmc + PMC_DPD_ENABLE);
+#endif
 
        writel(tegra_sctx.mc[0], mc + MC_SECURITY_START);
        writel(tegra_sctx.mc[1], mc + MC_SECURITY_SIZE);
@@ -626,9 +744,9 @@ static void tegra_common_resume(void)
 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
        /* trigger emc mode write */
        writel(EMC_MRW_DEV_NONE, emc + EMC_MRW_0);
-#endif
        /* clear scratch registers shared by suspend and the reset pen */
        writel(0x0, pmc + PMC_SCRATCH39);
+#endif
        writel(0x0, pmc + PMC_SCRATCH41);
 
        /* restore IRAM */
@@ -657,21 +775,43 @@ static void tegra_pm_set(enum tegra_suspend_mode mode)
 
        reg = readl(pmc + PMC_CTRL);
        reg |= TEGRA_POWER_CPU_PWRREQ_OE;
-       reg |= TEGRA_POWER_PWRREQ_OE;
+       if (pdata->combined_req)
+               reg &= ~TEGRA_POWER_PWRREQ_OE;
+       else
+               reg |= TEGRA_POWER_PWRREQ_OE;
        reg &= ~TEGRA_POWER_EFFECT_LP0;
 
        switch (mode) {
        case TEGRA_SUSPEND_LP0:
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+               rate = clk_get_rate_all_locked(tegra_pclk);
+#endif
+               if (pdata->combined_req) {
+                       reg |= TEGRA_POWER_PWRREQ_OE;
+                       reg &= ~TEGRA_POWER_CPU_PWRREQ_OE;
+               }
+
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
                /*
                 * LP0 boots through the AVP, which then resumes the AVP to
                 * the address in scratch 39, and the cpu to the address in
                 * scratch 41 to tegra_resume
                 */
                writel(0x0, pmc + PMC_SCRATCH39);
+#endif
 
                /* Enable DPD sample to trigger sampling pads data and direction
                 * in which pad will be driven during lp0 mode*/
                writel(0x1, pmc + PMC_DPD_SAMPLE);
+#if !defined(CONFIG_ARCH_TEGRA_3x_SOC) && !defined(CONFIG_ARCH_TEGRA_2x_SOC)
+               writel(0x800fdfff, pmc + PMC_IO_DPD_REQ);
+               writel(0x80001fff, pmc + PMC_IO_DPD2_REQ);
+#endif
+
+#ifdef CONFIG_ARCH_TEGRA_11x_SOC
+               /* this is needed only for T11x, not for other chips */
+               reg &= ~TEGRA_POWER_CPUPWRGOOD_EN;
+#endif
 
                /* Set warmboot flag */
                boot_flag = readl(pmc + PMC_SCRATCH0);
@@ -709,12 +849,33 @@ static const char *lp_state[TEGRA_MAX_SUSPEND_MODE] = {
 static int tegra_suspend_enter(suspend_state_t state)
 {
        int ret;
+       ktime_t delta;
+       struct timespec ts_entry, ts_exit;
 
        if (pdata && pdata->board_suspend)
                pdata->board_suspend(current_suspend_mode, TEGRA_SUSPEND_BEFORE_PERIPHERAL);
 
+       read_persistent_clock(&ts_entry);
+
        ret = tegra_suspend_dram(current_suspend_mode, 0);
+       if (ret) {
+               pr_info("Aborting suspend, tegra_suspend_dram error=%d\n", ret);
+               goto abort_suspend;
+       }
+
+       read_persistent_clock(&ts_exit);
 
+       if (timespec_compare(&ts_exit, &ts_entry) > 0) {
+               delta = timespec_to_ktime(timespec_sub(ts_exit, ts_entry));
+
+               tegra_dvfs_rail_pause(tegra_cpu_rail, delta, false);
+               if (current_suspend_mode == TEGRA_SUSPEND_LP0)
+                       tegra_dvfs_rail_pause(tegra_core_rail, delta, false);
+               else
+                       tegra_dvfs_rail_pause(tegra_core_rail, delta, true);
+       }
+
+abort_suspend:
        if (pdata && pdata->board_resume)
                pdata->board_resume(current_suspend_mode, TEGRA_RESUME_AFTER_PERIPHERAL);
 
@@ -738,17 +899,35 @@ static void tegra_suspend_check_pwr_stats(void)
 
        int partid;
 
-       for_each_set_bit(partid, &pwrgate_partid_mask, BITS_PER_LONG)
-               if (tegra_powergate_is_powered(partid) == 1)
-                       pr_warning("partition %s is left on before suspend\n",
-                               tegra_powergate_get_name(partid));
+       for (partid = 0; partid < TEGRA_NUM_POWERGATE; partid++)
+               if ((1 << partid) & pwrgate_partid_mask)
+                       if (tegra_powergate_is_powered(partid))
+                               pr_warning("partition %s is left on before suspend\n",
+                                       tegra_powergate_get_name(partid));
 
        return;
 }
 
 int tegra_suspend_dram(enum tegra_suspend_mode mode, unsigned int flags)
 {
-       BUG_ON(mode < 0 || mode >= TEGRA_MAX_SUSPEND_MODE);
+       int err = 0;
+       u32 scratch37 = 0xDEADBEEF;
+       u32 reg;
+
+       if (WARN_ON(mode <= TEGRA_SUSPEND_NONE ||
+               mode >= TEGRA_MAX_SUSPEND_MODE)) {
+               err = -ENXIO;
+               goto fail;
+       }
+
+       if (tegra_is_voice_call_active()) {
+               /* backup the current value of scratch37 */
+               scratch37 = readl(pmc + PMC_SCRATCH37);
+
+               /* If voice call is active, set a flag in PMC_SCRATCH37 */
+               reg = TEGRA_POWER_LP1_AUDIO;
+               pmc_32kwritel(reg, PMC_SCRATCH37);
+       }
 
        if ((mode == TEGRA_SUSPEND_LP0) && !tegra_pm_irq_lp0_allowed()) {
                pr_info("LP0 not used due to unsupported wakeup events\n");
@@ -760,8 +939,6 @@ int tegra_suspend_dram(enum tegra_suspend_mode mode, unsigned int flags)
 
        tegra_common_suspend();
 
-       pr_info("Entering suspend state %s\n", lp_state[mode]);
-
        tegra_pm_set(mode);
 
        if (pdata && pdata->board_suspend)
@@ -769,19 +946,41 @@ int tegra_suspend_dram(enum tegra_suspend_mode mode, unsigned int flags)
 
        local_fiq_disable();
 
-       cpu_pm_enter();
-       cpu_cluster_pm_enter();
+       trace_cpu_suspend(CPU_SUSPEND_START, tegra_rtc_read_ms());
 
        if (mode == TEGRA_SUSPEND_LP0) {
-               tegra_lp0_cpu_mode(true);
+#ifdef CONFIG_TEGRA_CLUSTER_CONTROL
+               reg = readl(pmc + PMC_SCRATCH4);
+               if (is_lp_cluster())
+                       reg |= PMC_SCRATCH4_WAKE_CLUSTER_MASK;
+               else
+                       reg &= (~PMC_SCRATCH4_WAKE_CLUSTER_MASK);
+               pmc_32kwritel(reg, PMC_SCRATCH4);
+#endif
+               tegra_tsc_suspend();
                tegra_lp0_suspend_mc();
                tegra_cpu_reset_handler_save();
+               tegra_tsc_wait_for_suspend();
+#ifndef CONFIG_TEGRA_SIMULATION_PLATFORM
+               tegra_smp_clear_power_mask();
+#endif
        }
+       else if (mode == TEGRA_SUSPEND_LP1)
+               *iram_cpu_lp1_mask = 1;
 
        suspend_cpu_complex(flags);
 
-       if (mode == TEGRA_SUSPEND_LP1)
-               *iram_cpu_lp1_mask = 1;
+#if defined(CONFIG_ARCH_TEGRA_HAS_SYMMETRIC_CPU_PWR_GATE)
+       /* In case of LP0/1, program external power gating accordinly */
+       if (mode == TEGRA_SUSPEND_LP0 || mode == TEGRA_SUSPEND_LP1) {
+               reg = readl(FLOW_CTRL_CPU_CSR(0));
+               if (is_lp_cluster())
+                       reg |= FLOW_CTRL_CSR_ENABLE_EXT_NCPU; /* Non CPU */
+               else
+                       reg |= FLOW_CTRL_CSR_ENABLE_EXT_CRAIL;  /* CRAIL */
+               flowctrl_writel(reg, FLOW_CTRL_CPU_CSR(0));
+       }
+#endif
 
        flush_cache_all();
        outer_flush_all();
@@ -790,32 +989,69 @@ int tegra_suspend_dram(enum tegra_suspend_mode mode, unsigned int flags)
        if (mode == TEGRA_SUSPEND_LP2)
                tegra_sleep_cpu(PHYS_OFFSET - PAGE_OFFSET);
        else
-               tegra_sleep_core(PHYS_OFFSET - PAGE_OFFSET);
+               tegra_sleep_core(mode, PHYS_OFFSET - PAGE_OFFSET);
+
+       tegra_init_cache(true);
+
+#ifdef CONFIG_TRUSTED_FOUNDATIONS
+#ifndef CONFIG_ARCH_TEGRA_11x_SOC
+       trace_smc_wake(tegra_resume_smc_entry_time, NVSEC_SMC_START);
+       trace_smc_wake(tegra_resume_smc_exit_time, NVSEC_SMC_DONE);
+#endif
 
-       tegra_init_cache();
+       if (mode == TEGRA_SUSPEND_LP0) {
+               trace_secureos_init(tegra_resume_entry_time,
+                       NVSEC_SUSPEND_EXIT_DONE);
+       }
+#endif
 
        if (mode == TEGRA_SUSPEND_LP0) {
+
+               /* CPUPWRGOOD_EN is not enabled in HW so disabling this, *
+               * Otherwise it is creating issue in cluster switch after LP0 *
+#ifdef CONFIG_ARCH_TEGRA_11x_SOC
+               reg = readl(pmc+PMC_CTRL);
+               reg |= TEGRA_POWER_CPUPWRGOOD_EN;
+               pmc_32kwritel(reg, PMC_CTRL);
+#endif
+               */
+
+               tegra_tsc_resume();
                tegra_cpu_reset_handler_restore();
                tegra_lp0_resume_mc();
-               tegra_lp0_cpu_mode(false);
+               tegra_tsc_wait_for_resume();
        } else if (mode == TEGRA_SUSPEND_LP1)
                *iram_cpu_lp1_mask = 0;
 
+       /* if scratch37 was clobbered during LP1, restore it */
+       if (scratch37 != 0xDEADBEEF)
+               pmc_32kwritel(scratch37, PMC_SCRATCH37);
+
        restore_cpu_complex(flags);
 
-       cpu_cluster_pm_exit();
-       cpu_pm_exit();
+       /* for platforms where the core & CPU power requests are
+        * combined as a single request to the PMU, transition out
+        * of LP0 state by temporarily enabling both requests
+        */
+       if (mode == TEGRA_SUSPEND_LP0 && pdata->combined_req) {
+               reg = readl(pmc + PMC_CTRL);
+               reg |= TEGRA_POWER_CPU_PWRREQ_OE;
+               pmc_32kwritel(reg, PMC_CTRL);
+               reg &= ~TEGRA_POWER_PWRREQ_OE;
+               pmc_32kwritel(reg, PMC_CTRL);
+       }
 
        if (pdata && pdata->board_resume)
                pdata->board_resume(mode, TEGRA_RESUME_AFTER_CPU);
 
+       trace_cpu_suspend(CPU_SUSPEND_DONE, tegra_rtc_read_ms());
+
        local_fiq_enable();
 
        tegra_common_resume();
 
-       pr_info("Exited suspend state %s\n", lp_state[mode]);
-
-       return 0;
+fail:
+       return err;
 }
 
 /*
@@ -833,6 +1069,12 @@ static int tegra_suspend_prepare(void)
 
 static void tegra_suspend_finish(void)
 {
+       if (pdata && pdata->cpu_resume_boost) {
+               int ret = tegra_suspended_target(pdata->cpu_resume_boost);
+               pr_info("Tegra: resume CPU boost to %u KHz: %s (%d)\n",
+                       pdata->cpu_resume_boost, ret ? "Failed" : "OK", ret);
+       }
+
        if ((current_suspend_mode == TEGRA_SUSPEND_LP0) && tegra_deep_sleep)
                tegra_deep_sleep(0);
 }
@@ -873,6 +1115,12 @@ static ssize_t suspend_mode_store(struct kobject *kobj,
        len = name_ptr - buf;
        if (!len)
                goto bad_name;
+       /* TEGRA_SUSPEND_NONE not allowed as suspend state */
+       if (!(strncmp(buf, tegra_suspend_name[TEGRA_SUSPEND_NONE], len))
+               || !(strncmp(buf, tegra_suspend_name[TEGRA_SUSPEND_LP2], len))) {
+               pr_info("Illegal tegra suspend state: %s\n", buf);
+               goto bad_name;
+       }
 
        for (new_mode = TEGRA_SUSPEND_NONE; \
                        new_mode < TEGRA_MAX_SUSPEND_MODE; ++new_mode) {
@@ -890,6 +1138,33 @@ static struct kobj_attribute suspend_mode_attribute =
        __ATTR(mode, 0644, suspend_mode_show, suspend_mode_store);
 
 static struct kobject *suspend_kobj;
+
+static int tegra_pm_enter_suspend(void)
+{
+       pr_info("Entering suspend state %s\n", lp_state[current_suspend_mode]);
+       if (current_suspend_mode == TEGRA_SUSPEND_LP0)
+               tegra_lp0_cpu_mode(true);
+       return 0;
+}
+
+static void tegra_pm_enter_resume(void)
+{
+       if (current_suspend_mode == TEGRA_SUSPEND_LP0)
+               tegra_lp0_cpu_mode(false);
+       pr_info("Exited suspend state %s\n", lp_state[current_suspend_mode]);
+}
+
+static struct syscore_ops tegra_pm_enter_syscore_ops = {
+       .suspend = tegra_pm_enter_suspend,
+       .resume = tegra_pm_enter_resume,
+};
+
+static __init int tegra_pm_enter_syscore_init(void)
+{
+       register_syscore_ops(&tegra_pm_enter_syscore_ops);
+       return 0;
+}
+subsys_initcall(tegra_pm_enter_syscore_init);
 #endif
 
 void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat)
@@ -897,12 +1172,19 @@ void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat)
        u32 reg;
        u32 mode;
 
+#ifdef CONFIG_ARCH_TEGRA_HAS_CL_DVFS
+       tegra_dfll = clk_get_sys(NULL, "dfll_cpu");
+       BUG_ON(IS_ERR(tegra_dfll));
+#endif
        tegra_pclk = clk_get_sys(NULL, "pclk");
        BUG_ON(IS_ERR(tegra_pclk));
        pdata = plat;
        (void)reg;
        (void)mode;
 
+       if (plat->suspend_mode == TEGRA_SUSPEND_LP2)
+               plat->suspend_mode = TEGRA_SUSPEND_LP0;
+
 #ifndef CONFIG_PM_SLEEP
        if (plat->suspend_mode != TEGRA_SUSPEND_NONE) {
                pr_warning("%s: Suspend requires CONFIG_PM_SLEEP -- "
@@ -917,14 +1199,7 @@ void __init tegra_init_suspend(struct tegra_suspend_platform_data *plat)
                goto fail;
        }
 
-       if (alloc_suspend_context() < 0) {
-               pr_err("%s: CPU context alloc failed -- LP0/LP1/LP2 unavailable\n",
-                               __func__);
-               plat->suspend_mode = TEGRA_SUSPEND_NONE;
-               goto fail;
-       }
-
-       if ((tegra_chip_id == TEGRA30) &&
+       if ((tegra_get_chipid() == TEGRA_CHIPID_TEGRA3) &&
            (tegra_revision == TEGRA_REVISION_A01) &&
            (plat->suspend_mode == TEGRA_SUSPEND_LP0)) {
                /* Tegra 3 A01 supports only LP1 */
@@ -980,11 +1255,28 @@ out:
                plat->suspend_mode = TEGRA_SUSPEND_LP2;
        }
 
+#ifdef CONFIG_TEGRA_LP1_950
+       if (pdata->lp1_lowvolt_support) {
+               u32 lp1_core_lowvolt, lp1_core_highvolt;
+               memcpy(tegra_lp1_register_pmuslave_addr(), &pdata->pmuslave_addr, 4);
+               memcpy(tegra_lp1_register_i2c_base_addr(), &pdata->i2c_base_addr, 4);
+
+               lp1_core_lowvolt = 0;
+               lp1_core_lowvolt = (pdata->lp1_core_volt_low << 8) | pdata->core_reg_addr;
+               memcpy(tegra_lp1_register_core_lowvolt(), &lp1_core_lowvolt, 4);
+
+               lp1_core_highvolt = 0;
+               lp1_core_highvolt = (pdata->lp1_core_volt_high << 8) | pdata->core_reg_addr;
+               memcpy(tegra_lp1_register_core_highvolt(), &lp1_core_highvolt, 4);
+       }
+#endif
        /* !!!FIXME!!! THIS IS TEGRA2 ONLY */
        /* Initialize scratch registers used for CPU LP2 synchronization */
        writel(0, pmc + PMC_SCRATCH37);
        writel(0, pmc + PMC_SCRATCH38);
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
        writel(0, pmc + PMC_SCRATCH39);
+#endif
        writel(0, pmc + PMC_SCRATCH41);
 
        /* Always enable CPU power request; just normal polarity is supported */
@@ -1015,7 +1307,8 @@ out:
 
        /* now enable requests */
        reg |= TEGRA_POWER_SYSCLK_OE;
-       reg |= TEGRA_POWER_PWRREQ_OE;
+       if (!pdata->combined_req)
+               reg |= TEGRA_POWER_PWRREQ_OE;
        pmc_32kwritel(reg, PMC_CTRL);
 
        if (pdata->suspend_mode == TEGRA_SUSPEND_LP0)
@@ -1034,10 +1327,14 @@ out:
 
        iram_cpu_lp2_mask = tegra_cpu_lp2_mask;
        iram_cpu_lp1_mask = tegra_cpu_lp1_mask;
+
+       /* clear io dpd settings before kernel */
+       tegra_bl_io_dpd_cleanup();
+
 fail:
 #endif
        if (plat->suspend_mode == TEGRA_SUSPEND_NONE)
-               tegra_lp2_in_idle(false);
+               tegra_pd_in_idle(false);
 
        current_suspend_mode = plat->suspend_mode;
 }
@@ -1093,6 +1390,9 @@ static void tegra_debug_uart_resume(void)
        /* DLAB = 0 */
        writeb(lcr & ~UART_LCR_DLAB, uart + UART_LCR * 4);
 
+       writeb(UART_FCR_ENABLE_FIFO | UART_FCR_T_TRIG_01 | UART_FCR_R_TRIG_01,
+                       uart + UART_FCR * 4);
+
        writeb(tegra_sctx.uart[2], uart + UART_IER * 4);
 
        /* DLAB = 1 */
@@ -1115,13 +1415,13 @@ EXPORT_SYMBOL(debug_uart_clk);
 void tegra_console_uart_suspend(void)
 {
        if (console_suspend_enabled && debug_uart_clk)
-               clk_disable(debug_uart_clk);
+               tegra_clk_disable_unprepare(debug_uart_clk);
 }
 
 void tegra_console_uart_resume(void)
 {
        if (console_suspend_enabled && debug_uart_clk)
-               clk_enable(debug_uart_clk);
+               tegra_clk_prepare_enable(debug_uart_clk);
 }
 
 static int tegra_debug_uart_syscore_init(void)
@@ -1130,67 +1430,3 @@ static int tegra_debug_uart_syscore_init(void)
        return 0;
 }
 arch_initcall(tegra_debug_uart_syscore_init);
-
-#ifdef CONFIG_DEBUG_FS
-static int tegra_suspend_debug_show(struct seq_file *s, void *data)
-{
-       seq_printf(s, "%s\n", tegra_suspend_name[*(int *)s->private]);
-       return 0;
-}
-
-static int tegra_suspend_debug_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, tegra_suspend_debug_show, inode->i_private);
-}
-
-static int tegra_suspend_debug_write(struct file *file,
-       const char __user *user_buf, size_t count, loff_t *ppos)
-{
-       char buf[32];
-       int buf_size;
-       int i;
-       struct seq_file *s = file->private_data;
-       enum tegra_suspend_mode *val = s->private;
-
-       memset(buf, 0x00, sizeof(buf));
-       buf_size = min(count, (sizeof(buf)-1));
-       if (copy_from_user(buf, user_buf, buf_size))
-               return -EFAULT;
-
-       for (i = 0; i < TEGRA_MAX_SUSPEND_MODE; i++) {
-               if (!strnicmp(buf, tegra_suspend_name[i],
-                   strlen(tegra_suspend_name[i]))) {
-                       if (i > pdata->suspend_mode)
-                               return -EINVAL;
-                       *val = i;
-                       return count;
-               }
-       }
-
-       return -EINVAL;
-}
-
-static const struct file_operations tegra_suspend_debug_fops = {
-       .open           = tegra_suspend_debug_open,
-       .write          = tegra_suspend_debug_write,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-};
-
-static int __init tegra_suspend_debug_init(void)
-{
-       struct dentry *d;
-
-       d = debugfs_create_file("suspend_mode", 0755, NULL,
-               (void *)&current_suspend_mode, &tegra_suspend_debug_fops);
-       if (!d) {
-               pr_info("Failed to create suspend_mode debug file\n");
-               return -ENOMEM;
-       }
-
-       return 0;
-}
-
-late_initcall(tegra_suspend_debug_init);
-#endif