arm: tegra: t11x power gate tables
Bitan Biswas [Mon, 3 Sep 2012 15:17:51 +0000 (20:17 +0530)]
Tegra11x power gate table update

bug 1032690
bug 1007784

Change-Id: Ib44543268b5f7b6443aaf61c61ff1e0b8120747c
Signed-off-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-on: http://git-master/r/132720
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Bo Yan <byan@nvidia.com>
(cherry picked from commit ea4552c400343ede914d6ec0ef277a681e611b79)
Reviewed-on: http://git-master/r/142019
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Tested-by: Bharat Nihalani <bnihalani@nvidia.com>

Rebase-Id: R767585452fc87999f9d52bdb693c7df1b8ff97af

arch/arm/mach-tegra/iomap.h
arch/arm/mach-tegra/powergate.c

index b98f507..72abd91 100644 (file)
 #if defined(CONFIG_ARCH_TEGRA_11x_SOC)
 #define TEGRA_SOCTHERM_BASE            0x700E2000
 #define TEGRA_SOCTHERM_SIZE            SZ_4K
+
+#define TEGRA_MIPI_CAL_BASE            0x700E3000
+#define TEGRA_MIPI_CAL_SIZE            SZ_256
 #endif
 
 #if defined(CONFIG_ARCH_TEGRA_2x_SOC)
index ade757a..abefada 100644 (file)
 #include "fuse.h"
 #include "iomap.h"
 
+#if defined(DEBUG_T11x_POWERGATE)
+static void test_powergate_parts(void);
+#endif
+#if defined(DEBUG_T11x_POWERUNGATE)
+static void test_powerungate_parts(void);
+#endif
+#if defined(DEBUG_T11x_POWERGATE_CLK_OFF)
+static void test_powergate_clk_off_parts(void);
+#endif
+#if defined(DEBUG_T11x_POWERUNGATE_CLK_OFF)
+static void test_unpowergate_clk_on_parts(void);
+#endif
+
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+static int tegra11x_check_partition_pug_seq(int id);
+#endif
+
 #define PWRGATE_TOGGLE         0x30
 #define PWRGATE_TOGGLE_START   (1 << 8)
 
@@ -44,7 +61,7 @@
 
 #define PWRGATE_STATUS         0x38
 
-#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
+#if defined(CONFIG_ARCH_TEGRA_3x_SOC)
 enum mc_client {
        MC_CLIENT_AFI           = 0,
        MC_CLIENT_AVPC          = 1,
@@ -66,7 +83,7 @@ enum mc_client {
        MC_CLIENT_VI            = 17,
        MC_CLIENT_LAST          = -1,
 };
-#else
+#elif defined(CONFIG_ARCH_TEGRA_2x_SOC)
 enum mc_client {
        MC_CLIENT_AVPC          = 0,
        MC_CLIENT_DC            = 1,
@@ -86,9 +103,37 @@ enum mc_client {
        MC_CLIENT_LAST          = -1,
        MC_CLIENT_AFI           = MC_CLIENT_LAST,
 };
+#else
+/* bit positions are specific to chip */
+enum mc_client {
+       MC_CLIENT_AVPC          = 1,
+       MC_CLIENT_DC            = 2,
+       MC_CLIENT_DCB           = 3,
+       MC_CLIENT_EPP           = 4,
+       MC_CLIENT_G2            = 5,
+       MC_CLIENT_HC            = 6,
+       MC_CLIENT_HDA           = 7,
+       MC_CLIENT_ISP           = 8,
+       MC_CLIENT_MPCORE        = 9,
+       MC_CLIENT_MPCORELP      = 10,
+       MC_CLIENT_MSENC         = 11,
+       MC_CLIENT_NV            = 12,
+       MC_CLIENT_PPCS          = 14,
+       MC_CLIENT_VDE           = 16,
+       MC_CLIENT_VI            = 17,
+       MC_CLIENT_XUSB_HOST     = 19,
+       MC_CLIENT_XUSB_DEV      = 20,
+       MC_CLIENT_EMUCIF        = 21,
+       MC_CLIENT_TSEC          = 22,
+       MC_CLIENT_LAST          = -1,
+       MC_CLIENT_AFI           = MC_CLIENT_LAST,
+       MC_CLIENT_MPE           = MC_CLIENT_LAST,
+       MC_CLIENT_NV2           = MC_CLIENT_LAST,
+       MC_CLIENT_SATA          = MC_CLIENT_LAST,
+};
 #endif
 
-#define MAX_CLK_EN_NUM                 4
+#define MAX_CLK_EN_NUM                 9
 
 static int tegra_num_powerdomains;
 static int tegra_num_cpu_domains;
@@ -126,9 +171,15 @@ struct powergate_partition {
 static struct powergate_partition powergate_partition_info[TEGRA_NUM_POWERGATE] = {
        [TEGRA_POWERGATE_CPU]   = { "cpu0",     {MC_CLIENT_LAST}, },
        [TEGRA_POWERGATE_L2]    = { "l2",       {MC_CLIENT_LAST}, },
+#if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
        [TEGRA_POWERGATE_3D]    = { "3d0",
+#else
+       [TEGRA_POWERGATE_3D]    = { "3d",
+#endif
                                                {MC_CLIENT_NV, MC_CLIENT_LAST},
                                                {{"3d", CLK_AND_RST} }, },
+/* T11x does not have pcie */
+#if !defined(CONFIG_ARCH_TEGRA_11x_SOC)
 #ifdef CONFIG_ARCH_TEGRA_HAS_PCIE
        [TEGRA_POWERGATE_PCIE]  = { "pcie",
                                                {MC_CLIENT_AFI, MC_CLIENT_LAST},
@@ -139,27 +190,53 @@ static struct powergate_partition powergate_partition_info[TEGRA_NUM_POWERGATE]
 #endif
                                                {"pciex", RST_ONLY} }, },
 #endif
+#endif
        [TEGRA_POWERGATE_VDEC]  = { "vde",
                                                {MC_CLIENT_VDE, MC_CLIENT_LAST},
                                                {{"vde", CLK_AND_RST} }, },
        [TEGRA_POWERGATE_MPE]   = { "mpe",
-#ifndef CONFIG_ARCH_TEGRA_2x_SOC
-                                               {MC_CLIENT_MPE, MC_CLIENT_LAST},
-#else
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+                                       {
+                                               MC_CLIENT_MPE,
+                                               MC_CLIENT_LAST
+                                       },
+#elif defined(CONFIG_ARCH_TEGRA_2x_SOC)
                                                {MC_CLIENT_MPEA, MC_CLIENT_MPEB,
                                                 MC_CLIENT_MPEC, MC_CLIENT_LAST},
+#else
+                                       {
+                                               MC_CLIENT_MSENC,
+                                               MC_CLIENT_LAST
+                                       },
+#endif
+#if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
+                                       {
+                                               {"mpe", CLK_AND_RST}
+                                       },
+#else
+                                       {
+                                               {"msenc", CLK_AND_RST}
+                                       },
 #endif
-                                               {{"mpe", CLK_AND_RST} }, },
+                               },
        [TEGRA_POWERGATE_VENC]  = { "ve",
-                                               {MC_CLIENT_ISP, MC_CLIENT_VI, MC_CLIENT_LAST},
-                                               {{"isp", CLK_AND_RST},
+                                       {
+                                               MC_CLIENT_ISP,
+                                               MC_CLIENT_VI,
+                                               MC_CLIENT_LAST
+                                       },
+                                       {
+                                               {"isp", CLK_AND_RST},
                                                {"vi", CLK_AND_RST},
-                                               {"csi", CLK_AND_RST} }, },
+                                               {"csi", CLK_AND_RST}
+                                       },
+                               },
 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
        [TEGRA_POWERGATE_CPU1]  = { "cpu1",     {MC_CLIENT_LAST}, },
        [TEGRA_POWERGATE_CPU2]  = { "cpu2",     {MC_CLIENT_LAST}, },
        [TEGRA_POWERGATE_CPU3]  = { "cpu3",     {MC_CLIENT_LAST}, },
        [TEGRA_POWERGATE_CELP]  = { "celp",     {MC_CLIENT_LAST}, },
+#if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
 #ifdef CONFIG_ARCH_TEGRA_HAS_SATA
        [TEGRA_POWERGATE_SATA]  = { "sata",     {MC_CLIENT_SATA, MC_CLIENT_LAST},
                                                {{"sata", CLK_AND_RST},
@@ -172,30 +249,104 @@ static struct powergate_partition powergate_partition_info[TEGRA_NUM_POWERGATE]
                                                {MC_CLIENT_NV2, MC_CLIENT_LAST},
                                                {{"3d2", CLK_AND_RST} }, },
 #endif
+#endif
        [TEGRA_POWERGATE_HEG]   = { "heg",
-                                               {MC_CLIENT_G2, MC_CLIENT_EPP,
-                                                       MC_CLIENT_HC,
-                                                       MC_CLIENT_LAST},
-                                               {{"2d", CLK_AND_RST},
+                                       {
+                                               MC_CLIENT_G2,
+                                               MC_CLIENT_EPP,
+#if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
+                                               MC_CLIENT_HC,
+#endif
+                                               MC_CLIENT_LAST
+                                       },
+                                       {
+                                               {"2d", CLK_AND_RST},
                                                {"epp", CLK_AND_RST},
+#if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
                                                {"host1x", CLK_AND_RST},
-                                               {"3d", RST_ONLY} }, },
+                                               {"3d", RST_ONLY}
+#endif
+                                       },
+                               },
 #endif
 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
        [TEGRA_POWERGATE_CRAIL] = { "crail",    {MC_CLIENT_LAST}, },
        [TEGRA_POWERGATE_C0NC]  = { "c0nc",     {MC_CLIENT_LAST}, },
        [TEGRA_POWERGATE_C1NC]  = { "c1nc",     {MC_CLIENT_LAST}, },
-       [TEGRA_POWERGATE_DISA]  = { "disa",     {MC_CLIENT_LAST}, },
-       [TEGRA_POWERGATE_DISB]  = { "disb",     {MC_CLIENT_LAST}, },
-       [TEGRA_POWERGATE_XUSBA] = { "xusba",    {MC_CLIENT_LAST}, },
-       [TEGRA_POWERGATE_XUSBB] = { "xusbb",    {MC_CLIENT_LAST}, },
-       [TEGRA_POWERGATE_XUSBC] = { "xusbc",    {MC_CLIENT_LAST}, },
+       [TEGRA_POWERGATE_DISA]  = { "disa",
+                                       {
+                                               MC_CLIENT_DC,
+                                               MC_CLIENT_LAST
+                                       },
+                                       {
+                                               {"disp1", CLK_AND_RST},
+                                               {"dsia", CLK_AND_RST},
+                                               {"dsib", CLK_AND_RST},
+                                               {"csi", CLK_AND_RST},
+                                               {"mipi-cal", CLK_AND_RST}
+                                       },
+                               },
+       [TEGRA_POWERGATE_DISB]  = { "disb",
+                                       {
+                                               MC_CLIENT_DCB,
+                                               MC_CLIENT_LAST
+                                       },
+                                       {
+                                               {"disp2", CLK_AND_RST},
+                                               {"hdmi", CLK_AND_RST}
+                                       },
+                               },
+       [TEGRA_POWERGATE_XUSBA] = { "xusba",
+                                       { MC_CLIENT_LAST },
+                                       {
+                                               {"xusb_ss", CLK_AND_RST}
+                                       },
+                               },
+       [TEGRA_POWERGATE_XUSBB] = { "xusbb",
+                                       {
+                                               MC_CLIENT_XUSB_DEV,
+                                               MC_CLIENT_LAST
+                                       },
+                                       {
+                                               {"xusb_dev", CLK_AND_RST},
+                                       },
+                               },
+       [TEGRA_POWERGATE_XUSBC] = { "xusbc",
+                                       {
+                                               MC_CLIENT_XUSB_HOST,
+                                               MC_CLIENT_LAST
+                                       },
+                                       {
+                                               {"xusb_host", CLK_AND_RST},
+                                       },
+                               },
 #endif
 
 };
 
 static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
 
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+static void __iomem *mipi_cal = IO_ADDRESS(TEGRA_MIPI_CAL_BASE);
+
+static u32 mipi_cal_read(unsigned long reg)
+{
+       return readl(mipi_cal + reg);
+}
+
+static void mipi_cal_write(u32 val, unsigned long reg)
+{
+       writel(val, mipi_cal + reg);
+}
+
+static void __iomem *clk_rst = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
+
+static u32 clk_rst_read(unsigned long reg)
+{
+       return readl(clk_rst + reg);
+}
+#endif
+
 static u32 pmc_read(unsigned long reg)
 {
        return readl(pmc + reg);
@@ -224,16 +375,49 @@ static void mc_write(u32 val, unsigned long reg)
 #define MC_CLIENT_HOTRESET_CTRL        0x200
 #define MC_CLIENT_HOTRESET_STAT        0x204
 
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && \
+       !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+/* FIXME: this is sw workaround for unstable hotreset status
+ * for T11x.
+ */
+#define HOTRESET_READ_COUNT 5
+static bool tegra11x_stable_hotreset_check(u32 *stat)
+{
+       int i;
+       u32 cur_stat;
+       u32 prv_stat;
+       unsigned long flags;
+
+       spin_lock_irqsave(&tegra_powergate_lock, flags);
+       prv_stat = mc_read(MC_CLIENT_HOTRESET_STAT);
+       for (i = 0; i < HOTRESET_READ_COUNT; i++) {
+               cur_stat = mc_read(MC_CLIENT_HOTRESET_STAT);
+               if (cur_stat != prv_stat) {
+                       spin_unlock_irqrestore(&tegra_powergate_lock, flags);
+                       return false;
+               }
+       }
+       *stat = cur_stat;
+       spin_unlock_irqrestore(&tegra_powergate_lock, flags);
+       return true;
+}
+#endif
+
 static void mc_flush(int id)
 {
        u32 idx, rst_ctrl, rst_stat;
        enum mc_client mcClientBit;
        unsigned long flags;
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && \
+       !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+       bool ret;
+#endif
 
        BUG_ON(id < 0 || id >= TEGRA_NUM_POWERGATE);
 
        for (idx = 0; idx < MAX_HOTRESET_CLIENT_NUM; idx++) {
-               mcClientBit = powergate_partition_info[id].hot_reset_clients[idx];
+               mcClientBit =
+                       powergate_partition_info[id].hot_reset_clients[idx];
                if (mcClientBit == MC_CLIENT_LAST)
                        break;
 
@@ -246,7 +430,14 @@ static void mc_flush(int id)
 
                do {
                        udelay(10);
+#if defined(CONFIG_ARCH_TEGRA_2x_SOC) || defined(CONFIG_ARCH_TEGRA_3x_SOC)
                        rst_stat = mc_read(MC_CLIENT_HOTRESET_STAT);
+#else
+                       rst_stat = 0;
+                       ret = tegra11x_stable_hotreset_check(&rst_stat);
+                       if (!ret)
+                               continue;
+#endif
                } while (!(rst_stat & (1 << mcClientBit)));
        }
 }
@@ -260,7 +451,8 @@ static void mc_flush_done(int id)
        BUG_ON(id < 0 || id >= TEGRA_NUM_POWERGATE);
 
        for (idx = 0; idx < MAX_HOTRESET_CLIENT_NUM; idx++) {
-               mcClientBit = powergate_partition_info[id].hot_reset_clients[idx];
+               mcClientBit =
+                       powergate_partition_info[id].hot_reset_clients[idx];
                if (mcClientBit == MC_CLIENT_LAST)
                        break;
 
@@ -499,6 +691,51 @@ static int tegra_powergate_set(int id, bool new_state)
        return 0;
 }
 
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+static bool tegra11x_check_plld_plld2_disable(void)
+{
+       /* FIXME:
+        * add check for plld and plld2 disable
+        */
+#define CLK_RST_CONTROLLER_PLLD_BASE_0 0xd0
+#define CLK_RST_CONTROLLER_PLLD_BASE_0_PLLD_ENABLE_LSB 30
+#define CLK_RST_CONTROLLER_PLLD2_BASE_0 0x4b8
+#define CLK_RST_CONTROLLER_PLLD2_BASE_0_PLLD2_ENABLE_LSB 30
+       u32 status;
+       status = clk_rst_read(CLK_RST_CONTROLLER_PLLD_BASE_0);
+       if (status & (1 << CLK_RST_CONTROLLER_PLLD_BASE_0_PLLD_ENABLE_LSB))
+               return false;
+       status = clk_rst_read(CLK_RST_CONTROLLER_PLLD2_BASE_0);
+       if (status & (1 << CLK_RST_CONTROLLER_PLLD2_BASE_0_PLLD2_ENABLE_LSB))
+               return false;
+       return true;
+}
+
+static bool tegra11x_pg_sw_war_missing(int id)
+{
+       bool ret;
+
+       switch (id) {
+       case TEGRA_POWERGATE_DISA:
+               /* FIXME:
+                * [SW WAR bug 954988]:
+                * Disable PLLD and PLLD2 by clearing bits:
+a.     CLK_RST_CONTROLLER_PLLD_BASE_0_PLLD_ENABLE
+b.     CLK_RST_CONTROLLER_PLLD2_BASE_0_PLLD2_ENABLE
+                * We should not need to disable PLLD and PLLD2
+                * for linux/android implementation
+                * adding check in case PLLD or PLLD2 is/are ON
+                */
+               ret = tegra11x_check_plld_plld2_disable();
+               if (!ret)
+                       return true;
+
+               break;
+       }
+       return false;
+}
+#endif
+
 static int unpowergate_module(int id)
 {
        if (id < 0 || id >= tegra_num_powerdomains)
@@ -508,10 +745,21 @@ static int unpowergate_module(int id)
 
 static int powergate_module(int id)
 {
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+       bool need_sw_war;
+#endif
        if (id < 0 || id >= tegra_num_powerdomains)
                return -EINVAL;
 
        mc_flush(id);
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+       need_sw_war = tegra11x_pg_sw_war_missing(id);
+       if (need_sw_war) {
+               pr_err("Error: missing powergate sw war in file: %s, func: %s, line=%d\n",
+               __FILE__, __func__, __LINE__);
+               return -1;
+       }
+#endif
        return tegra_powergate_set(id, false);
 }
 
@@ -564,16 +812,55 @@ static void get_clk_info(int id)
        }
 }
 
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+static bool tegra11x_pug_clk_n_rst_skip(int id, u32 idx)
+{
+       switch (id) {
+       case TEGRA_POWERGATE_VENC:
+               if ((!powergate_partition_info[id].clk_info[idx].clk_name) &&
+                       (!(strncmp("csi",
+                       powergate_partition_info[id].clk_info[idx].clk_name,
+                       3)))) {
+                               /* DIS powered ON then do clk enable CSI */
+                               if (!tegra_powergate_is_powered(
+                                               TEGRA_POWERGATE_DISA))
+                                       return true;
+               }
+               break;
+       case TEGRA_POWERGATE_DISA:
+               if ((!powergate_partition_info[id].clk_info[idx].clk_name) &&
+                       (!(strncmp("csi",
+                       powergate_partition_info[id].clk_info[idx].clk_name,
+                       3)))) {
+                               /* DIS powered ON then do clk enable CSI */
+                               if (!tegra_powergate_is_powered(
+                                               TEGRA_POWERGATE_VENC))
+                                       return true;
+               }
+               break;
+       }
+       return false;
+}
+#endif
+
 static int partition_clk_enable(int id)
 {
        int ret;
        u32 idx;
        struct clk *clk;
        struct partition_clk_info *clk_info;
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+       bool skip_enable;
+#endif
 
        BUG_ON(id < 0 || id >= TEGRA_NUM_POWERGATE);
 
        for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+               skip_enable = tegra11x_pug_clk_n_rst_skip(id, idx);
+               if (skip_enable)
+                       continue;
+#endif
                clk_info = &powergate_partition_info[id].clk_info[idx];
                clk = clk_info->clk_ptr;
                if (!clk)
@@ -630,10 +917,20 @@ static void partition_clk_disable(int id)
        u32 idx;
        struct clk *clk;
        struct partition_clk_info *clk_info;
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+       bool skip_disable;
+#endif
 
        BUG_ON(id < 0 || id >= TEGRA_NUM_POWERGATE);
 
        for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+               if (id == TEGRA_POWERGATE_DISA) {
+                       skip_disable = tegra11x_pug_clk_n_rst_skip(id, idx);
+                       if (skip_disable)
+                               continue;
+               }
+#endif
                clk_info = &powergate_partition_info[id].clk_info[idx];
                clk = clk_info->clk_ptr;
                if (!clk)
@@ -649,10 +946,20 @@ static void powergate_partition_assert_reset(int id)
        u32 idx;
        struct clk *clk_ptr;
        struct partition_clk_info *clk_info;
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+       bool skip_reset;
+#endif
 
        BUG_ON(id < 0 || id >= TEGRA_NUM_POWERGATE);
 
        for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+               if (id == TEGRA_POWERGATE_DISA) {
+                       skip_reset = tegra11x_pug_clk_n_rst_skip(id, idx);
+                       if (skip_reset)
+                               continue;
+               }
+#endif
                clk_info = &powergate_partition_info[id].clk_info[idx];
                clk_ptr = clk_info->clk_ptr;
                if (!clk_ptr)
@@ -667,10 +974,18 @@ static void powergate_partition_deassert_reset(int id)
        u32 idx;
        struct clk *clk_ptr;
        struct partition_clk_info *clk_info;
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+       bool skip_reset;
+#endif
 
        BUG_ON(id < 0 || id >= TEGRA_NUM_POWERGATE);
 
        for (idx = 0; idx < MAX_CLK_EN_NUM; idx++) {
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+               skip_reset = tegra11x_pug_clk_n_rst_skip(id, idx);
+               if (skip_reset)
+                       continue;
+#endif
                clk_info = &powergate_partition_info[id].clk_info[idx];
                clk_ptr = clk_info->clk_ptr;
                if (!clk_ptr)
@@ -702,6 +1017,61 @@ static int tegra_powergate_reset_module(int id)
        return 0;
 }
 
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+/*
+ * FIXME: sw war for mipi-cal calibration when unpowergating DISA partition
+ */
+static void tegra11x_mipical_calibrate(void)
+{
+       struct reg_offset_val {
+               u32 offset;
+               u32 por_value;
+       };
+       u32 status;
+       unsigned long flags;
+#define MIPI_CAL_MIPI_CAL_CTRL_0 0x0
+#define MIPI_CAL_CIL_MIPI_CAL_STATUS_0 0x8
+#define MIPI_CAL_CILA_MIPI_CAL_CONFIG_0 0x14
+#define MIPI_CAL_CILB_MIPI_CAL_CONFIG_0 0x18
+#define MIPI_CAL_CILC_MIPI_CAL_CONFIG_0 0x1c
+#define MIPI_CAL_CILD_MIPI_CAL_CONFIG_0 0x20
+#define MIPI_CAL_CILE_MIPI_CAL_CONFIG_0 0x24
+#define MIPI_CAL_DSIA_MIPI_CAL_CONFIG_0 0x38
+#define MIPI_CAL_DSIB_MIPI_CAL_CONFIG_0 0x3c
+#define MIPI_CAL_DSIC_MIPI_CAL_CONFIG_0 0x40
+#define MIPI_CAL_DSID_MIPI_CAL_CONFIG_0 0x44
+       static struct reg_offset_val mipi_cal_por_values[] = {
+               { MIPI_CAL_MIPI_CAL_CTRL_0, 0x2a000000 },
+               { MIPI_CAL_CILA_MIPI_CAL_CONFIG_0, 0x00200000 },
+               { MIPI_CAL_CILB_MIPI_CAL_CONFIG_0, 0x00200000 },
+               { MIPI_CAL_CILC_MIPI_CAL_CONFIG_0, 0x00200000 },
+               { MIPI_CAL_CILD_MIPI_CAL_CONFIG_0, 0x00200000 },
+               { MIPI_CAL_CILE_MIPI_CAL_CONFIG_0, 0x00000000 },
+               { MIPI_CAL_DSIA_MIPI_CAL_CONFIG_0, 0x00200000 },
+               { MIPI_CAL_DSIB_MIPI_CAL_CONFIG_0, 0x00200000 },
+               { MIPI_CAL_DSIC_MIPI_CAL_CONFIG_0, 0x00200000 },
+               { MIPI_CAL_DSID_MIPI_CAL_CONFIG_0, 0x00200000 },
+       };
+       int i;
+
+       spin_lock_irqsave(&tegra_powergate_lock, flags);
+       /* mipi cal por restore */
+       for (i = 0; i < ARRAY_SIZE(mipi_cal_por_values); i++) {
+               mipi_cal_write(mipi_cal_por_values[i].por_value,
+                       mipi_cal_por_values[i].offset);
+       }
+       /* mipi cal status clear */
+       status = mipi_cal_read(MIPI_CAL_CIL_MIPI_CAL_STATUS_0);
+       mipi_cal_write(status, MIPI_CAL_CIL_MIPI_CAL_STATUS_0);
+       /* mipi cal status read - to flush writes */
+       status = mipi_cal_read(MIPI_CAL_CIL_MIPI_CAL_STATUS_0);
+       spin_unlock_irqrestore(&tegra_powergate_lock, flags);
+       if (status)
+               pr_err("Error: mipi_cal calibration failed at file: %s, func: %s, line=%d\n",
+               __FILE__, __func__, __LINE__);
+}
+#endif
+
 /*
  * Must be called with clk disabled, and returns with clk disabled
  * Drivers should enable clks for partition. Unpowergates only the
@@ -711,6 +1081,11 @@ int tegra_unpowergate_partition(int id)
 {
        int ret;
 
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+       ret = tegra11x_check_partition_pug_seq(id);
+       if (ret)
+               return ret;
+#endif
        /* If first clk_ptr is null, fill clk info for the partition */
        if (!powergate_partition_info[id].clk_info[0].clk_ptr)
                get_clk_info(id);
@@ -736,6 +1111,10 @@ int tegra_unpowergate_partition(int id)
                goto err_clamp;
 
        udelay(10);
+
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+       tegra11x_mipical_calibrate();
+#endif
        powergate_partition_deassert_reset(id);
 
        mc_flush_done(id);
@@ -784,6 +1163,18 @@ int __init tegra_powergate_init(void)
                break;
        }
 
+#if defined(DEBUG_T11x_POWERGATE)
+       test_powergate_parts();
+#endif
+#if defined(DEBUG_T11x_POWERUNGATE)
+       test_unpowergate_parts();
+#endif
+#if defined(DEBUG_T11x_POWERGATE_CLK_OFF)
+       test_powergate_clk_off_parts();
+#endif
+#if defined(DEBUG_T11x_POWERUNGATE_CLK_ON)
+       test_unpowergate_clk_on_parts();
+#endif
        return 0;
 }
 
@@ -795,10 +1186,10 @@ int tegra_unpowergate_partition_with_clk_on(int id)
 {
        int ret = 0;
 
-#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+#if defined(CONFIG_ARCH_TEGRA_3x_SOC)
        /* Restrict this functions use to few partitions */
        BUG_ON(id != TEGRA_POWERGATE_SATA && id != TEGRA_POWERGATE_PCIE);
-#else
+#elif defined(CONFIG_ARCH_TEGRA_2x_SOC)
        /* Restrict this functions use to few partitions */
        BUG_ON(id != TEGRA_POWERGATE_PCIE);
 #endif
@@ -822,6 +1213,82 @@ err_unpowergating:
        return ret;
 }
 
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+static int tegra11x_powergate_partition(int id)
+{
+       int ret;
+
+       if (tegra_powergate_is_powered(id)) {
+               ret = is_partition_clk_disabled(id);
+               if (ret < 0) {
+                       /* clock enabled */
+                       ret = tegra_powergate_partition_with_clk_off(id);
+                       if (ret < 0)
+                               return ret;
+               } else {
+                       ret = tegra_powergate_partition(id);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+       return 0;
+}
+
+static int tegra11x_unpowergate_partition(int id)
+{
+       int ret;
+
+       if (!tegra_powergate_is_powered(id)) {
+               ret = is_partition_clk_disabled(id);
+               if (ret) {
+                       /* clock disabled */
+                       ret = tegra_unpowergate_partition_with_clk_on(id);
+                       if (ret < 0)
+                               return ret;
+               } else {
+                       ret = tegra_unpowergate_partition(id);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+       return 0;
+}
+
+static int tegra11x_check_partition_pg_seq(int id)
+{
+       int ret;
+
+       switch (id) {
+       case TEGRA_POWERGATE_DISA:
+               ret = tegra11x_powergate_partition(TEGRA_POWERGATE_VENC);
+               if (ret < 0)
+                       return ret;
+               ret = tegra11x_powergate_partition(TEGRA_POWERGATE_DISB);
+               if (ret < 0)
+                       return ret;
+
+               break;
+       }
+       return 0;
+}
+
+static int tegra11x_check_partition_pug_seq(int id)
+{
+       int ret;
+
+       switch (id) {
+       case TEGRA_POWERGATE_DISB:
+       case TEGRA_POWERGATE_VENC:
+               ret = tegra11x_unpowergate_partition(TEGRA_POWERGATE_DISA);
+               if (ret < 0)
+                       return ret;
+
+               break;
+       }
+       return 0;
+}
+#endif
+
 /*
  * Must be called with clk disabled. Powergates the partition only
  */
@@ -829,6 +1296,11 @@ int tegra_powergate_partition(int id)
 {
        int ret;
 
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC) && !defined(CONFIG_ARCH_TEGRA_3x_SOC)
+       ret = tegra11x_check_partition_pg_seq(id);
+       if (ret)
+               return ret;
+#endif
        /* If first clk_ptr is null, fill clk info for the partition */
        if (powergate_partition_info[id].clk_info[0].clk_ptr)
                get_clk_info(id);
@@ -856,10 +1328,10 @@ int tegra_powergate_partition_with_clk_off(int id)
 {
        int ret = 0;
 
-#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+#if defined(CONFIG_ARCH_TEGRA_3x_SOC)
        /* Restrict functions use to selected partitions */
        BUG_ON(id != TEGRA_POWERGATE_PCIE && id != TEGRA_POWERGATE_SATA);
-#else
+#elif defined(CONFIG_ARCH_TEGRA_2x_SOC)
        /* Restrict functions use to selected partitions */
        BUG_ON(id != TEGRA_POWERGATE_PCIE);
 #endif
@@ -884,6 +1356,46 @@ err_powergating:
        return ret;
 }
 
+#if defined(DEBUG_T11x_POWERGATE)
+static void test_powergate_parts(void)
+{
+       int i;
+
+       for (i = 0; i < TEGRA_NUM_POWERGATE; i++)
+               tegra_powergate_partition(i);
+}
+#endif
+
+#if defined(DEBUG_T11x_POWERUNGATE)
+static void test_powerungate_parts(void)
+{
+       int i;
+
+       for (i = 0; i < TEGRA_NUM_POWERGATE; i++)
+               tegra_unpowergate_partition(i);
+}
+#endif
+
+#if defined(DEBUG_T11x_POWERGATE_CLK_OFF)
+static void test_powergate_clk_off_parts(void)
+{
+       int i;
+
+       for (i = 0; i < TEGRA_NUM_POWERGATE; i++)
+               tegra_powergate_partition_with_clk_off(i);
+}
+#endif
+
+#if defined(DEBUG_T11x_POWERUNGATE_CLK_OFF)
+static void test_unpowergate_clk_on_parts(void)
+{
+       int i;
+
+       for (i = 0; i < TEGRA_NUM_POWERGATE; i++)
+               tegra_unpowergate_partition_with_clk_on(i);
+}
+#endif
+
 const char *tegra_powergate_get_name(int id)
 {
        if (id < 0 || id >= TEGRA_NUM_POWERGATE)