ARM: tegra14x: Copy SDRAM params to Scratch regs
Prashant Malani [Wed, 30 Jan 2013 23:24:17 +0000 (15:24 -0800)]
Copy the packed SDRAM parameters for a particular
MC/EMC frequency setting into PMC SCRATCH
registers for use during LP0BB.

Bug 1025839
Bug 1234031

Change-Id: I34980029ca6bec71d3b36562749c15eba6886a5e
Signed-off-by: Prashant Malani <pmalani@nvidia.com>
Reviewed-on: http://git-master/r/207714
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Bo Yan <byan@nvidia.com>

arch/arm/mach-tegra/pm.c
arch/arm/mach-tegra/tegra14_scratch.h [new file with mode: 0644]

index 7ecb310..974b4b2 100644 (file)
@@ -76,6 +76,9 @@
 #include "timer.h"
 #include "dvfs.h"
 #include "cpu-tegra.h"
+#if defined(CONFIG_ARCH_TEGRA_14x_SOC)
+#include "tegra14_scratch.h"
+#endif
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/nvpower.h>
@@ -127,6 +130,10 @@ static u64 suspend_time;
 static u64 suspend_entry_time;
 #endif
 
+#if defined(CONFIG_ARCH_TEGRA_14x_SOC)
+static void update_pmc_registers(int instance);
+#endif
+
 struct suspend_context tegra_sctx;
 
 #define TEGRA_POWER_PWRREQ_POLARITY    (1 << 8)   /* core power request polarity */
@@ -1121,6 +1128,10 @@ int tegra_suspend_dram(enum tegra_suspend_mode mode, unsigned int flags)
                goto fail;
        }
 
+#if defined(CONFIG_ARCH_TEGRA_14x_SOC)
+       update_pmc_registers(1);
+#endif
+
        if (tegra_is_voice_call_active()) {
                /* backup the current value of scratch37 */
                scratch37 = readl(pmc + PMC_SCRATCH37);
@@ -1718,3 +1729,50 @@ static int tegra_debug_uart_syscore_init(void)
        return 0;
 }
 arch_initcall(tegra_debug_uart_syscore_init);
+
+#if defined(CONFIG_ARCH_TEGRA_14x_SOC)
+static inline bool pmc_write_check(int index, int bit_position)
+{
+       if (pmc_write_bitmap[index] & (1 << bit_position))
+               return true;
+       else
+               return false;
+}
+
+static void update_pmc_registers(int instance)
+{
+       u32 i, j;
+
+       /* Based on index, we select that block of scratches */
+       u32 base2 = (tegra_wb0_params_address + (instance - 1) *
+               tegra_wb0_params_block_size);
+       void __iomem *base = ioremap(base2, tegra_wb0_params_block_size);
+
+#define copy_dram_to_pmc(index, bit)   \
+       pmc_32kwritel(readl(base + PMC_REGISTER_OFFSET(index, bit)), \
+               PMC_REGISTER_OFFSET(index, bit) + PMC_SCRATCH0)
+
+
+       /* Iterate through the bitmap, and copy those registers
+        * which are marked in the bitmap
+        */
+       for (i = 0, j = 0; j < ARRAY_SIZE(pmc_write_bitmap);) {
+               if (pmc_write_bitmap[j] == 0) {
+                       j++;
+                       i = 0;
+                       continue;
+               }
+
+               if (pmc_write_check(j, i))
+                       copy_dram_to_pmc(j, i);
+
+               if (++i > (sizeof(pmc_write_bitmap[0]) * 8)) {
+                       i = 0;
+                       j++;
+               }
+       }
+
+#undef copy_dram_to_pmc
+       iounmap(base);
+}
+#endif
diff --git a/arch/arm/mach-tegra/tegra14_scratch.h b/arch/arm/mach-tegra/tegra14_scratch.h
new file mode 100644 (file)
index 0000000..881a5b8
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/mach-tegra/tegra14_scratch.h
+ *
+ * Bitmap definitions for pmc scratch register writes
+ *
+ * Copyright (c) 2010-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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _MACH_TEGRA_TEGRA14_SCRATCH_H
+#define _MACH_TEGRA_TEGRA14_SCRATCH_H
+
+/* Bitmap which tells us which of the PMC_SCRATCH registers need to be
+ * written.
+ */
+static u8 pmc_write_bitmap[] = {
+       0xFC, 0xFF, 0xCF, 0x00, 0x00,
+       0xF8, 0xDF, 0x28, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00,
+       0xDF, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0xF0, 0xFF,
+       0xFF, 0xFF, 0xFF, 0xFF, 0x03,
+};
+
+#define PMC_REGISTER_OFFSET(index, bit) \
+       (((index * sizeof(pmc_write_bitmap[0]) * 8) + bit) * \
+       sizeof(u32))
+
+#endif