blob: ae18a18623f91e08974b04ece28eddf0e5c126da [file] [log] [blame]
Erik Gillingc5f80062010-01-21 16:53:02 -08001/*
Todd Poynor433cb7f2010-09-02 15:10:29 -07002 * arch/arm/mach-tegra/common.c
Erik Gillingc5f80062010-01-21 16:53:02 -08003 *
4 * Copyright (C) 2010 Google, Inc.
Alex Fride818b6e2012-01-12 20:27:55 -08005 * Copyright (C) 2010-2012 NVIDIA Corporation
Erik Gillingc5f80062010-01-21 16:53:02 -08006 *
7 * Author:
8 * Colin Cross <ccross@android.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -070021#include <linux/platform_device.h>
Dima Zavin7e158ac2010-11-11 15:28:46 -080022#include <linux/console.h>
Erik Gillingc5f80062010-01-21 16:53:02 -080023#include <linux/init.h>
24#include <linux/io.h>
Colin Cross4de3a8f2010-04-05 13:16:42 -070025#include <linux/clk.h>
26#include <linux/delay.h>
Colin Cross115467a2010-10-19 21:09:29 -070027#include <linux/highmem.h>
Colin Cross8e437c22010-11-28 22:36:08 -080028#include <linux/memblock.h>
Rakesh Bodla1ad210a2011-05-31 15:18:00 +053029#include <linux/bitops.h>
Chris Johnson644d1fb2011-11-18 16:14:07 -080030#include <linux/sched.h>
Erik Gillingc5f80062010-01-21 16:53:02 -080031
32#include <asm/hardware/cache-l2x0.h>
Dima Zavin7e158ac2010-11-11 15:28:46 -080033#include <asm/system.h>
Erik Gillingc5f80062010-01-21 16:53:02 -080034
Colin Cross45a1ca02011-03-28 17:47:31 -070035#include <mach/gpio.h>
Erik Gillingc5f80062010-01-21 16:53:02 -080036#include <mach/iomap.h>
Colin Cross120c3562011-03-28 17:48:56 -070037#include <mach/pinmux.h>
Dima Zavin7db7cbc2010-09-16 17:58:05 -070038#include <mach/powergate.h>
Colin Cross699fe142010-08-23 18:37:25 -070039#include <mach/system.h>
Hiroshi DOYU6ebf00f2012-01-09 08:52:47 +020040#include <mach/tegra_smmu.h>
Erik Gillingc5f80062010-01-21 16:53:02 -080041
Jon Mayo6ae77a92010-12-21 15:09:33 -080042#include "apbio.h"
Erik Gillingc5f80062010-01-21 16:53:02 -080043#include "board.h"
Colin Crossd8611962010-01-28 16:40:29 -080044#include "clock.h"
Colin Cross73625e32010-06-23 15:49:17 -070045#include "fuse.h"
Colin Cross8e437c22010-11-28 22:36:08 -080046#include "pm.h"
Scott Williams45376ca2011-08-17 11:47:58 -070047#include "reset.h"
Colin Cross8e437c22010-11-28 22:36:08 -080048
Scott Williams816ab052010-12-07 11:19:20 -080049#define MC_SECURITY_CFG2 0x7c
Colin Crossf9c9bde2010-10-19 16:12:33 -070050
Rakesh Bodla1ad210a2011-05-31 15:18:00 +053051#define AHB_ARBITRATION_PRIORITY_CTRL 0x4
52#define AHB_PRIORITY_WEIGHT(x) (((x) & 0x7) << 29)
53#define PRIORITY_SELECT_USB BIT(6)
54#define PRIORITY_SELECT_USB2 BIT(18)
55#define PRIORITY_SELECT_USB3 BIT(17)
56
57#define AHB_GIZMO_AHB_MEM 0xc
58#define ENB_FAST_REARBITRATE BIT(2)
Jay Chengce4a7df2011-06-09 17:34:35 -040059#define DONT_SPLIT_AHB_WR BIT(7)
Rakesh Bodla1ad210a2011-05-31 15:18:00 +053060
61#define AHB_GIZMO_USB 0x1c
62#define AHB_GIZMO_USB2 0x78
63#define AHB_GIZMO_USB3 0x7c
64#define IMMEDIATE BIT(18)
65
66#define AHB_MEM_PREFETCH_CFG3 0xe0
67#define AHB_MEM_PREFETCH_CFG4 0xe4
68#define AHB_MEM_PREFETCH_CFG1 0xec
69#define AHB_MEM_PREFETCH_CFG2 0xf0
70#define PREFETCH_ENB BIT(31)
71#define MST_ID(x) (((x) & 0x1f) << 26)
72#define AHBDMA_MST_ID MST_ID(5)
73#define USB_MST_ID MST_ID(6)
74#define USB2_MST_ID MST_ID(18)
75#define USB3_MST_ID MST_ID(17)
76#define ADDR_BNDRY(x) (((x) & 0xf) << 21)
77#define INACTIVITY_TIMEOUT(x) (((x) & 0xffff) << 0)
78
Colin Cross838d7d62010-10-19 14:45:50 -070079unsigned long tegra_bootloader_fb_start;
80unsigned long tegra_bootloader_fb_size;
81unsigned long tegra_fb_start;
82unsigned long tegra_fb_size;
83unsigned long tegra_fb2_start;
84unsigned long tegra_fb2_size;
85unsigned long tegra_carveout_start;
86unsigned long tegra_carveout_size;
Krishna Reddyb7d5a862011-10-05 12:23:37 -070087unsigned long tegra_vpr_start;
88unsigned long tegra_vpr_size;
Colin Cross8e437c22010-11-28 22:36:08 -080089unsigned long tegra_lp0_vec_start;
90unsigned long tegra_lp0_vec_size;
Prashant Gaikwadff192312011-08-03 14:49:20 +053091bool tegra_lp0_vec_relocate;
Scott Williams03122532011-01-13 14:30:20 -080092unsigned long tegra_grhost_aperture = ~0ul;
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +053093static bool is_tegra_debug_uart_hsport;
Laxman Dewangan87d07ce2011-06-15 00:48:57 +053094static struct board_info pmu_board_info;
Hyungwoo Yang187ada82011-10-24 15:06:17 -070095static struct board_info display_board_info;
Jihoon Bangea8fd162011-12-12 11:00:14 -080096static struct board_info camera_board_info;
Colin Crossd8611962010-01-28 16:40:29 -080097
Alex Frid3a5fc7c2011-05-11 16:01:44 -070098static int pmu_core_edp = 1200; /* default 1.2V EDP limit */
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +053099static int board_panel_type;
Laxman Dewangan8644fc02011-09-04 17:10:13 +0530100static enum power_supply_type pow_supply_type = POWER_SUPPLY_TYPE_MAINS;
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530101
Colin Cross699fe142010-08-23 18:37:25 -0700102void (*arch_reset)(char mode, const char *cmd) = tegra_assert_system_reset;
103
Scott Williamsae811c32011-02-10 15:45:06 -0800104#define NEVER_RESET 0
Scott Williams9bc40532011-01-28 03:26:28 -0800105
Colin Cross699fe142010-08-23 18:37:25 -0700106void tegra_assert_system_reset(char mode, const char *cmd)
107{
Scott Williams9bc40532011-01-28 03:26:28 -0800108#if defined(CONFIG_TEGRA_FPGA_PLATFORM) || NEVER_RESET
Scott Williamsae811c32011-02-10 15:45:06 -0800109 printk("tegra_assert_system_reset() ignored.....");
Scott Williams9bc40532011-01-28 03:26:28 -0800110 do { } while (1);
111#else
Deepesh Gujarathi43921782010-12-07 14:09:22 +0530112 void __iomem *reset = IO_ADDRESS(TEGRA_PMC_BASE + 0x00);
Colin Cross699fe142010-08-23 18:37:25 -0700113 u32 reg;
114
Simon Glass375b19c2011-02-17 08:13:57 -0800115 /* use *_related to avoid spinlock since caches are off */
116 reg = readl_relaxed(reset);
Deepesh Gujarathi43921782010-12-07 14:09:22 +0530117 reg |= 0x10;
Simon Glass375b19c2011-02-17 08:13:57 -0800118 writel_relaxed(reg, reset);
Scott Williams4ad5ff12011-01-07 20:43:13 -0800119#endif
Colin Cross699fe142010-08-23 18:37:25 -0700120}
Steve Lind2f4e4d2011-07-11 12:45:06 -0700121static int modem_id;
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530122static int debug_uart_port_id;
Laxman Dewangan57b08762011-09-18 16:49:10 +0530123static enum audio_codec_type audio_codec_name;
Laxman Dewangan1f8be3d2011-10-15 15:44:04 +0530124static int max_cpu_current;
Colin Cross699fe142010-08-23 18:37:25 -0700125
Laxman Dewangan844407d2011-04-27 19:11:08 +0530126/* WARNING: There is implicit client of pllp_out3 like i2c, uart, dsi
127 * and so this clock (pllp_out3) should never be disabled.
128 */
Colin Crossd8611962010-01-28 16:40:29 -0800129static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
130 /* name parent rate enabled */
131 { "clk_m", NULL, 0, true },
Yudong Tanf8cd6292011-07-01 11:26:17 -0700132#ifdef CONFIG_TEGRA_SILICON_PLATFORM
Alex Fridc86c2252011-05-28 00:21:30 -0700133#ifdef CONFIG_ARCH_TEGRA_2x_SOC
Scott Williams816ab052010-12-07 11:19:20 -0800134 { "pll_p", NULL, 216000000, true },
Colin Crossd8611962010-01-28 16:40:29 -0800135 { "pll_p_out1", "pll_p", 28800000, true },
Prashant Gaikwad1529b8e2012-01-23 12:43:28 +0530136 { "pll_p_out2", "pll_p", 48000000, false },
Colin Crossd8611962010-01-28 16:40:29 -0800137 { "pll_p_out3", "pll_p", 72000000, true },
Prashant Gaikwad1529b8e2012-01-23 12:43:28 +0530138 { "pll_p_out4", "pll_p", 108000000, false },
Prashant Gaikwad9a975332011-11-01 18:16:47 +0530139 { "pll_m", "clk_m", 0, true },
Pritesh Raithathabb1d62b2011-11-11 16:52:11 +0530140 { "pll_m_out1", "pll_m", 120000000, true },
Prashant Gaikwad9a975332011-11-01 18:16:47 +0530141 { "sclk", "pll_c_out1", 40000000, true },
Scott Williams07fc3312011-05-23 22:08:42 -0700142 { "hclk", "sclk", 40000000, true },
143 { "pclk", "hclk", 40000000, true },
Prashant Gaikwad9a975332011-11-01 18:16:47 +0530144 { "mpe", "pll_c", 0, false },
145 { "epp", "pll_c", 0, false },
146 { "vi_sensor", "pll_c", 0, false },
147 { "vi", "pll_c", 0, false },
148 { "2d", "pll_c", 0, false },
149 { "3d", "pll_c", 0, false },
Scott Williams07fc3312011-05-23 22:08:42 -0700150#else
Alex Fride818b6e2012-01-12 20:27:55 -0800151 { "pll_p", NULL, 0, true },
152 { "pll_p_out1", "pll_p", 0, false },
ScottPetersonfde0dd42011-12-28 13:40:20 -0800153 { "pll_p_out2", "pll_p", 48000000, false },
Alex Fride818b6e2012-01-12 20:27:55 -0800154 { "pll_p_out3", "pll_p", 0, true },
Alex Frid58af6ba2011-10-24 18:51:32 -0700155 { "pll_m_out1", "pll_m", 275000000, false },
ScottPetersonfde0dd42011-12-28 13:40:20 -0800156 { "pll_p_out4", "pll_p", 102000000, false },
Alex Fridc86c2252011-05-28 00:21:30 -0700157 { "sclk", "pll_p_out4", 102000000, true },
158 { "hclk", "sclk", 102000000, true },
159 { "pclk", "hclk", 51000000, true },
Wen Yidd455522012-01-23 22:54:21 -0800160 { "wake.sclk", NULL, 40000000, true },
Alex Frid8b5ce662011-01-31 10:07:57 -0800161#endif
Scott Williams0aac1552011-06-10 12:58:11 -0700162#else
163 { "pll_p", NULL, 216000000, true },
ScottPetersonfde0dd42011-12-28 13:40:20 -0800164 { "pll_p_out1", "pll_p", 28800000, false },
165 { "pll_p_out2", "pll_p", 48000000, false },
Scott Williams0aac1552011-06-10 12:58:11 -0700166 { "pll_p_out3", "pll_p", 72000000, true },
167 { "pll_m_out1", "pll_m", 275000000, true },
168 { "pll_c", NULL, ULONG_MAX, false },
169 { "pll_c_out1", "pll_c", 208000000, false },
ScottPetersonfde0dd42011-12-28 13:40:20 -0800170 { "pll_p_out4", "pll_p", 108000000, false },
Scott Williams0aac1552011-06-10 12:58:11 -0700171 { "sclk", "pll_p_out4", 108000000, true },
172 { "hclk", "sclk", 108000000, true },
173 { "pclk", "hclk", 54000000, true },
174#endif
ScottPetersonf8b15a82012-01-19 11:27:07 -0800175#ifdef CONFIG_TEGRA_SLOW_CSITE
176 { "csite", "clk_m", 1000000, true },
177#else
178 { "csite", NULL, 0, true },
179#endif
Colin Crosscd51d0e2011-02-21 17:05:36 -0800180 { "emc", NULL, 0, true },
181 { "cpu", NULL, 0, true },
Alex Fridd3b4e362011-05-26 22:58:21 -0700182 { "kfuse", NULL, 0, true },
Varun Wadekar0e0ccdb2011-06-25 16:42:37 +0530183 { "fuse", NULL, 0, true },
Scott Williams816ab052010-12-07 11:19:20 -0800184 { "pll_u", NULL, 480000000, false },
Alex Fridc86c2252011-05-28 00:21:30 -0700185 { "sdmmc1", "pll_p", 48000000, false},
Pavan Kunapuli0a420462011-03-16 19:29:42 +0530186 { "sdmmc3", "pll_p", 48000000, false},
Pavan Kunapuli4a743e72011-11-08 18:02:52 +0530187 { "sdmmc4", "pll_p", 48000000, false},
ScottPetersonc9a567732012-01-17 16:37:09 -0800188 { "pll_a", "pll_p_out1", 0, false},
189 { "pll_a_out0", "pll_a", 0, false},
Scott Williams07fc3312011-05-23 22:08:42 -0700190#ifndef CONFIG_ARCH_TEGRA_2x_SOC
Alex Frid5be85392011-06-28 20:50:29 -0700191 { "cbus", "pll_c", 416000000, false },
Alex Frid7359d832011-05-13 23:58:33 -0700192 { "pll_c_out1", "pll_c", 208000000, false },
Alex Frid67982942012-01-19 22:05:45 -0800193 { "mselect", "pll_p", 102000000, true },
Alex Frid7f970e72011-02-04 12:04:14 -0800194#endif
Colin Crossd8611962010-01-28 16:40:29 -0800195 { NULL, NULL, 0, 0},
196};
Erik Gillingc5f80062010-01-21 16:53:02 -0800197
Scott Williams70d70472012-02-02 18:55:00 -0800198#ifdef CONFIG_CACHE_L2X0
199#ifdef CONFIG_TRUSTED_FOUNDATIONS
Chris Johnson644d1fb2011-11-18 16:14:07 -0800200static void tegra_cache_smc(bool enable, u32 arg)
201{
202 void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
203 bool need_affinity_switch;
204 bool can_switch_affinity;
205 bool l2x0_enabled;
206 cpumask_t local_cpu_mask;
207 cpumask_t saved_cpu_mask;
208 unsigned long flags;
209 long ret;
210
211 /*
212 * ISSUE : Some registers of PL310 controler must be written
213 * from Secure context (and from CPU0)!
214 *
215 * When called form Normal we obtain an abort or do nothing.
216 * Instructions that must be called in Secure:
217 * - Write to Control register (L2X0_CTRL==0x100)
218 * - Write in Auxiliary controler (L2X0_AUX_CTRL==0x104)
219 * - Invalidate all entries (L2X0_INV_WAY==0x77C),
220 * mandatory at boot time.
221 * - Tag and Data RAM Latency Control Registers
222 * (0x108 & 0x10C) must be written in Secure.
223 */
224 need_affinity_switch = (smp_processor_id() != 0);
225 can_switch_affinity = !irqs_disabled();
226
227 WARN_ON(need_affinity_switch && !can_switch_affinity);
228 if (need_affinity_switch && can_switch_affinity) {
229 cpu_set(0, local_cpu_mask);
230 sched_getaffinity(0, &saved_cpu_mask);
231 ret = sched_setaffinity(0, &local_cpu_mask);
232 WARN_ON(ret != 0);
233 }
234
235 local_irq_save(flags);
236 l2x0_enabled = readl_relaxed(p + L2X0_CTRL) & 1;
237 if (enable && !l2x0_enabled)
238 tegra_generic_smc(0xFFFFF100, 0x00000001, arg);
239 else if (!enable && l2x0_enabled)
240 tegra_generic_smc(0xFFFFF100, 0x00000002, arg);
241 local_irq_restore(flags);
242
243 if (need_affinity_switch && can_switch_affinity) {
244 ret = sched_setaffinity(0, &saved_cpu_mask);
245 WARN_ON(ret != 0);
246 }
247}
248
249static void tegra_l2x0_disable(void)
250{
251 unsigned long flags;
252 static u32 l2x0_way_mask;
253
254 if (!l2x0_way_mask) {
255 void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
256 u32 aux_ctrl;
257 u32 ways;
258
259 aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
260 ways = (aux_ctrl & (1 << 16)) ? 16 : 8;
261 l2x0_way_mask = (1 << ways) - 1;
262 }
263
264 local_irq_save(flags);
265 tegra_cache_smc(false, l2x0_way_mask);
266 local_irq_restore(flags);
267}
Scott Williams70d70472012-02-02 18:55:00 -0800268#endif /* CONFIG_TRUSTED_FOUNDATIONS */
Chris Johnson644d1fb2011-11-18 16:14:07 -0800269
Krishna Reddy1212eb82011-12-01 15:32:36 -0800270void tegra_init_cache(bool init)
Erik Gillingc5f80062010-01-21 16:53:02 -0800271{
Erik Gillingc5f80062010-01-21 16:53:02 -0800272 void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
Scott Williams191914c2010-12-27 19:03:57 -0800273 u32 aux_ctrl;
Diwakar Tundlamf4ca2962011-12-02 15:49:42 -0800274 u32 speedo;
Krishna Reddy58eb2d02011-12-05 12:57:07 -0800275 u32 tmp;
Erik Gillingc5f80062010-01-21 16:53:02 -0800276
Chris Johnson644d1fb2011-11-18 16:14:07 -0800277#ifdef CONFIG_TRUSTED_FOUNDATIONS
278 /* issue the SMC to enable the L2 */
279 aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
280 tegra_cache_smc(true, aux_ctrl);
281
282 /* after init, reread aux_ctrl and register handlers */
283 aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
284 l2x0_init(p, aux_ctrl, 0xFFFFFFFF);
285
286 /* override outer_disable() with our disable */
287 outer_cache.disable = tegra_l2x0_disable;
288#else
Scott Williams816ab052010-12-07 11:19:20 -0800289#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
Colin Cross535371c2011-01-22 00:36:14 -0800290 writel_relaxed(0x331, p + L2X0_TAG_LATENCY_CTRL);
291 writel_relaxed(0x441, p + L2X0_DATA_LATENCY_CTRL);
Erik Gillingc5f80062010-01-21 16:53:02 -0800292
Scott Williams816ab052010-12-07 11:19:20 -0800293#elif defined(CONFIG_ARCH_TEGRA_3x_SOC)
Yudong Tanf8cd6292011-07-01 11:26:17 -0700294#ifdef CONFIG_TEGRA_SILICON_PLATFORM
Scott Williams1245c8e2011-01-05 17:53:39 -0800295 /* PL310 RAM latency is CPU dependent. NOTE: Changes here
296 must also be reflected in __cortex_a9_l2x0_restart */
297
298 if (is_lp_cluster()) {
299 writel(0x221, p + L2X0_TAG_LATENCY_CTRL);
300 writel(0x221, p + L2X0_DATA_LATENCY_CTRL);
301 } else {
Diwakar Tundlamf4ca2962011-12-02 15:49:42 -0800302 /* relax l2-cache latency for speedos 4,5,6 (T33's chips) */
303 speedo = tegra_cpu_speedo_id();
Alex Fridd83fa392012-01-23 13:40:48 -0800304 if (speedo == 4 || speedo == 5 || speedo == 6 ||
305 speedo == 12 || speedo == 13) {
Diwakar Tundlamf4ca2962011-12-02 15:49:42 -0800306 writel(0x442, p + L2X0_TAG_LATENCY_CTRL);
307 writel(0x552, p + L2X0_DATA_LATENCY_CTRL);
308 } else {
309 writel(0x441, p + L2X0_TAG_LATENCY_CTRL);
310 writel(0x551, p + L2X0_DATA_LATENCY_CTRL);
311 }
Scott Williams1245c8e2011-01-05 17:53:39 -0800312 }
Yudong Tanf8cd6292011-07-01 11:26:17 -0700313#else
314 writel(0x770, p + L2X0_TAG_LATENCY_CTRL);
315 writel(0x770, p + L2X0_DATA_LATENCY_CTRL);
Scott Williams816ab052010-12-07 11:19:20 -0800316#endif
Scott Williams816ab052010-12-07 11:19:20 -0800317#endif
Krishna Reddy58eb2d02011-12-05 12:57:07 -0800318 aux_ctrl = readl(p + L2X0_CACHE_TYPE);
319 aux_ctrl = (aux_ctrl & 0x700) << (17-8);
320 aux_ctrl |= 0x7C000001;
Krishna Reddy1212eb82011-12-01 15:32:36 -0800321 if (init) {
Krishna Reddy1212eb82011-12-01 15:32:36 -0800322 l2x0_init(p, aux_ctrl, 0x8200c3fe);
Krishna Reddy58eb2d02011-12-05 12:57:07 -0800323 } else {
324 tmp = aux_ctrl;
325 aux_ctrl = readl(p + L2X0_AUX_CTRL);
326 aux_ctrl &= 0x8200c3fe;
327 aux_ctrl |= tmp;
328 writel(aux_ctrl, p + L2X0_AUX_CTRL);
Krishna Reddy1212eb82011-12-01 15:32:36 -0800329 }
Chris Johnson644d1fb2011-11-18 16:14:07 -0800330 l2x0_enable();
331#endif
Erik Gillingc5f80062010-01-21 16:53:02 -0800332}
Scott Williams70d70472012-02-02 18:55:00 -0800333#endif
Erik Gillingc5f80062010-01-21 16:53:02 -0800334
Dima Zavin7db7cbc2010-09-16 17:58:05 -0700335static void __init tegra_init_power(void)
336{
Scott Williams1a536c32011-09-01 16:20:47 -0700337#ifdef CONFIG_ARCH_TEGRA_HAS_SATA
Karan Jhavar49adefb2011-06-09 14:50:35 -0700338 tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_SATA);
Karan Jhavar93962282011-05-16 17:00:43 -0700339#endif
Scott Williams1a536c32011-09-01 16:20:47 -0700340#ifdef CONFIG_ARCH_TEGRA_HAS_PCIE
Karan Jhavar93962282011-05-16 17:00:43 -0700341 tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_PCIE);
Scott Williams1a536c32011-09-01 16:20:47 -0700342#endif
Dima Zavin7db7cbc2010-09-16 17:58:05 -0700343}
344
Rakesh Bodla1ad210a2011-05-31 15:18:00 +0530345static inline unsigned long gizmo_readl(unsigned long offset)
346{
347 return readl(IO_TO_VIRT(TEGRA_AHB_GIZMO_BASE + offset));
348}
349
350static inline void gizmo_writel(unsigned long value, unsigned long offset)
351{
352 writel(value, IO_TO_VIRT(TEGRA_AHB_GIZMO_BASE + offset));
353}
354
355static void __init tegra_init_ahb_gizmo_settings(void)
356{
357 unsigned long val;
358
359 val = gizmo_readl(AHB_GIZMO_AHB_MEM);
Jay Chengce4a7df2011-06-09 17:34:35 -0400360 val |= ENB_FAST_REARBITRATE | IMMEDIATE | DONT_SPLIT_AHB_WR;
Rakesh Bodla1ad210a2011-05-31 15:18:00 +0530361 gizmo_writel(val, AHB_GIZMO_AHB_MEM);
362
363 val = gizmo_readl(AHB_GIZMO_USB);
364 val |= IMMEDIATE;
365 gizmo_writel(val, AHB_GIZMO_USB);
366
367 val = gizmo_readl(AHB_GIZMO_USB2);
368 val |= IMMEDIATE;
369 gizmo_writel(val, AHB_GIZMO_USB2);
370
371 val = gizmo_readl(AHB_GIZMO_USB3);
372 val |= IMMEDIATE;
373 gizmo_writel(val, AHB_GIZMO_USB3);
374
375 val = gizmo_readl(AHB_ARBITRATION_PRIORITY_CTRL);
376 val |= PRIORITY_SELECT_USB | PRIORITY_SELECT_USB2 | PRIORITY_SELECT_USB3
377 | AHB_PRIORITY_WEIGHT(7);
378 gizmo_writel(val, AHB_ARBITRATION_PRIORITY_CTRL);
379
380 val = gizmo_readl(AHB_MEM_PREFETCH_CFG1);
381 val &= ~MST_ID(~0);
382 val |= PREFETCH_ENB | AHBDMA_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
383 gizmo_writel(val, AHB_MEM_PREFETCH_CFG1);
384
385 val = gizmo_readl(AHB_MEM_PREFETCH_CFG2);
386 val &= ~MST_ID(~0);
387 val |= PREFETCH_ENB | USB_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
388 gizmo_writel(val, AHB_MEM_PREFETCH_CFG2);
389
390 val = gizmo_readl(AHB_MEM_PREFETCH_CFG3);
391 val &= ~MST_ID(~0);
392 val |= PREFETCH_ENB | USB3_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
393 gizmo_writel(val, AHB_MEM_PREFETCH_CFG3);
394
395 val = gizmo_readl(AHB_MEM_PREFETCH_CFG4);
396 val &= ~MST_ID(~0);
397 val |= PREFETCH_ENB | USB2_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
398 gizmo_writel(val, AHB_MEM_PREFETCH_CFG4);
399}
400
Dima Zavin7e158ac2010-11-11 15:28:46 -0800401static bool console_flushed;
402
Bo Yan9f309002011-08-11 15:03:08 -0700403static void tegra_pm_flush_console(void)
Dima Zavin7e158ac2010-11-11 15:28:46 -0800404{
405 if (console_flushed)
Bo Yan9f309002011-08-11 15:03:08 -0700406 return;
Dima Zavin7e158ac2010-11-11 15:28:46 -0800407 console_flushed = true;
408
Dima Zavin7e158ac2010-11-11 15:28:46 -0800409 pr_emerg("Restarting %s\n", linux_banner);
Colin Crossfec84b22011-04-07 14:40:23 -0700410 if (console_trylock()) {
411 console_unlock();
Bo Yan9f309002011-08-11 15:03:08 -0700412 return;
Dima Zavin7e158ac2010-11-11 15:28:46 -0800413 }
414
415 mdelay(50);
416
417 local_irq_disable();
Colin Crossfec84b22011-04-07 14:40:23 -0700418 if (!console_trylock())
Mayuresh Kulkarniabce6622011-06-17 19:47:05 +0530419 pr_emerg("%s: Console was locked! Busting\n", __func__);
Dima Zavin7e158ac2010-11-11 15:28:46 -0800420 else
Mayuresh Kulkarniabce6622011-06-17 19:47:05 +0530421 pr_emerg("%s: Console was locked!\n", __func__);
Colin Crossfec84b22011-04-07 14:40:23 -0700422 console_unlock();
Dima Zavin7e158ac2010-11-11 15:28:46 -0800423}
424
Bo Yan9f309002011-08-11 15:03:08 -0700425static void tegra_pm_restart(char mode, const char *cmd)
426{
427 tegra_pm_flush_console();
428 arm_machine_restart(mode, cmd);
429}
Bo Yandf2009a2011-04-18 17:04:47 -0700430
Colin Cross0cf62302011-02-21 17:10:14 -0800431void __init tegra_init_early(void)
Erik Gillingc5f80062010-01-21 16:53:02 -0800432{
Bo Yan9f309002011-08-11 15:03:08 -0700433 arm_pm_restart = tegra_pm_restart;
Scott Williams55f67602011-07-27 20:10:06 -0700434#ifndef CONFIG_SMP
435 /* For SMP system, initializing the reset handler here is too
436 late. For non-SMP systems, the function that calls the reset
437 handler initializer is not called, so do it here for non-SMP. */
438 tegra_cpu_reset_handler_init();
439#endif
Colin Cross73625e32010-06-23 15:49:17 -0700440 tegra_init_fuse();
Colin Cross45a1ca02011-03-28 17:47:31 -0700441 tegra_gpio_resume_init();
Colin Crossd8611962010-01-28 16:40:29 -0800442 tegra_init_clock();
Colin Cross120c3562011-03-28 17:48:56 -0700443 tegra_init_pinmux();
Colin Crossd8611962010-01-28 16:40:29 -0800444 tegra_clk_init_from_table(common_clk_init_table);
Dima Zavin7db7cbc2010-09-16 17:58:05 -0700445 tegra_init_power();
Krishna Reddy1212eb82011-12-01 15:32:36 -0800446 tegra_init_cache(true);
Rakesh Bodla1ad210a2011-05-31 15:18:00 +0530447 tegra_init_ahb_gizmo_settings();
Erik Gillingc5f80062010-01-21 16:53:02 -0800448}
Colin Cross8e437c22010-11-28 22:36:08 -0800449
450static int __init tegra_lp0_vec_arg(char *options)
451{
452 char *p = options;
453
454 tegra_lp0_vec_size = memparse(p, &p);
455 if (*p == '@')
456 tegra_lp0_vec_start = memparse(p+1, &p);
Scott Williams03122532011-01-13 14:30:20 -0800457 if (!tegra_lp0_vec_size || !tegra_lp0_vec_start) {
458 tegra_lp0_vec_size = 0;
459 tegra_lp0_vec_start = 0;
460 }
Colin Cross8e437c22010-11-28 22:36:08 -0800461
462 return 0;
463}
464early_param("lp0_vec", tegra_lp0_vec_arg);
465
Colin Cross838d7d62010-10-19 14:45:50 -0700466static int __init tegra_bootloader_fb_arg(char *options)
467{
468 char *p = options;
469
470 tegra_bootloader_fb_size = memparse(p, &p);
471 if (*p == '@')
472 tegra_bootloader_fb_start = memparse(p+1, &p);
473
474 pr_info("Found tegra_fbmem: %08lx@%08lx\n",
475 tegra_bootloader_fb_size, tegra_bootloader_fb_start);
476
477 return 0;
478}
479early_param("tegra_fbmem", tegra_bootloader_fb_arg);
480
Krishna Reddyb7d5a862011-10-05 12:23:37 -0700481static int __init tegra_vpr_arg(char *options)
482{
483 char *p = options;
484
485 tegra_vpr_size = memparse(p, &p);
486 if (*p == '@')
487 tegra_vpr_start = memparse(p+1, &p);
488 pr_info("Found vpr, start=0x%lx size=%lx",
489 tegra_vpr_start, tegra_vpr_size);
Colin Patrick McCabe997f4282011-11-09 13:44:27 -0800490 return 0;
Krishna Reddyb7d5a862011-10-05 12:23:37 -0700491}
492early_param("vpr", tegra_vpr_arg);
493
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530494enum panel_type get_panel_type(void)
495{
496 return board_panel_type;
497}
498static int __init tegra_board_panel_type(char *options)
499{
500 if (!strcmp(options, "lvds"))
501 board_panel_type = panel_type_lvds;
502 else if (!strcmp(options, "dsi"))
503 board_panel_type = panel_type_dsi;
504 else
505 return 0;
506 return 1;
507}
508__setup("panel=", tegra_board_panel_type);
509
Laxman Dewangan8644fc02011-09-04 17:10:13 +0530510enum power_supply_type get_power_supply_type(void)
511{
512 return pow_supply_type;
513}
514static int __init tegra_board_power_supply_type(char *options)
515{
516 if (!strcmp(options, "Adapter"))
517 pow_supply_type = POWER_SUPPLY_TYPE_MAINS;
518 if (!strcmp(options, "Mains"))
519 pow_supply_type = POWER_SUPPLY_TYPE_MAINS;
520 else if (!strcmp(options, "Battery"))
521 pow_supply_type = POWER_SUPPLY_TYPE_BATTERY;
522 else
523 return 0;
524 return 1;
525}
526__setup("power_supply=", tegra_board_power_supply_type);
527
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530528int get_core_edp(void)
529{
530 return pmu_core_edp;
531}
532static int __init tegra_pmu_core_edp(char *options)
533{
534 char *p = options;
Alex Frid3a5fc7c2011-05-11 16:01:44 -0700535 int core_edp = memparse(p, &p);
536 if (core_edp != 0)
537 pmu_core_edp = core_edp;
Deepesh Gujarathi9f73e312011-10-07 15:18:30 +0530538 return 0;
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530539}
Deepesh Gujarathiab7815e2011-09-15 13:57:02 +0530540early_param("core_edp_mv", tegra_pmu_core_edp);
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530541
Laxman Dewangan1f8be3d2011-10-15 15:44:04 +0530542int get_maximum_cpu_current_supported(void)
543{
544 return max_cpu_current;
545}
546static int __init tegra_max_cpu_current(char *options)
547{
548 char *p = options;
549 max_cpu_current = memparse(p, &p);
550 return 1;
551}
552__setup("max_cpu_cur_ma=", tegra_max_cpu_current);
553
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530554static int __init tegra_debug_uartport(char *info)
555{
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530556 char *p = info;
Laxman Dewanganc032ab22011-09-28 14:42:49 +0530557 unsigned long long port_id;
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530558 if (!strncmp(p, "hsport", 6))
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530559 is_tegra_debug_uart_hsport = true;
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530560 else if (!strncmp(p, "lsport", 6))
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530561 is_tegra_debug_uart_hsport = false;
562
Laxman Dewanganc032ab22011-09-28 14:42:49 +0530563 if (p[6] == ',') {
564 if (p[7] == '-') {
565 debug_uart_port_id = -1;
566 } else {
567 port_id = memparse(p + 7, &p);
568 debug_uart_port_id = (int) port_id;
569 }
570 } else {
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530571 debug_uart_port_id = -1;
Laxman Dewanganc032ab22011-09-28 14:42:49 +0530572 }
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530573
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530574 return 1;
575}
576
577bool is_tegra_debug_uartport_hs(void)
578{
579 return is_tegra_debug_uart_hsport;
580}
581
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530582int get_tegra_uart_debug_port_id(void)
583{
584 return debug_uart_port_id;
585}
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530586__setup("debug_uartport=", tegra_debug_uartport);
587
Laxman Dewangan57b08762011-09-18 16:49:10 +0530588static int __init tegra_audio_codec_type(char *info)
589{
590 char *p = info;
591 if (!strncmp(p, "wm8903", 6))
592 audio_codec_name = audio_codec_wm8903;
593 else
594 audio_codec_name = audio_codec_none;
595
596 return 1;
597}
598
599enum audio_codec_type get_audio_codec_type(void)
600{
601 return audio_codec_name;
602}
603__setup("audio_codec=", tegra_audio_codec_type);
604
605
Nitin Kumbhar637ced42010-12-10 15:16:37 +0530606void tegra_get_board_info(struct board_info *bi)
607{
Laxman Dewanganc0f18022011-02-05 16:26:42 +0530608 bi->board_id = (system_serial_high >> 16) & 0xFFFF;
609 bi->sku = (system_serial_high) & 0xFFFF;
610 bi->fab = (system_serial_low >> 24) & 0xFF;
611 bi->major_revision = (system_serial_low >> 16) & 0xFF;
612 bi->minor_revision = (system_serial_low >> 8) & 0xFF;
Nitin Kumbhar637ced42010-12-10 15:16:37 +0530613}
614
Laxman Dewangan87d07ce2011-06-15 00:48:57 +0530615static int __init tegra_pmu_board_info(char *info)
616{
617 char *p = info;
618 pmu_board_info.board_id = memparse(p, &p);
619 pmu_board_info.sku = memparse(p+1, &p);
620 pmu_board_info.fab = memparse(p+1, &p);
621 pmu_board_info.major_revision = memparse(p+1, &p);
622 pmu_board_info.minor_revision = memparse(p+1, &p);
623 return 1;
624}
625
626void tegra_get_pmu_board_info(struct board_info *bi)
627{
628 memcpy(bi, &pmu_board_info, sizeof(struct board_info));
629}
630
631__setup("pmuboard=", tegra_pmu_board_info);
632
Hyungwoo Yang187ada82011-10-24 15:06:17 -0700633static int __init tegra_display_board_info(char *info)
634{
635 char *p = info;
636 display_board_info.board_id = memparse(p, &p);
637 display_board_info.sku = memparse(p+1, &p);
638 display_board_info.fab = memparse(p+1, &p);
639 display_board_info.major_revision = memparse(p+1, &p);
640 display_board_info.minor_revision = memparse(p+1, &p);
641 return 1;
642}
643
644void tegra_get_display_board_info(struct board_info *bi)
645{
646 memcpy(bi, &display_board_info, sizeof(struct board_info));
647}
648
649__setup("displayboard=", tegra_display_board_info);
650
Jihoon Bangea8fd162011-12-12 11:00:14 -0800651static int __init tegra_camera_board_info(char *info)
652{
653 char *p = info;
654 camera_board_info.board_id = memparse(p, &p);
655 camera_board_info.sku = memparse(p+1, &p);
656 camera_board_info.fab = memparse(p+1, &p);
657 camera_board_info.major_revision = memparse(p+1, &p);
658 camera_board_info.minor_revision = memparse(p+1, &p);
659 return 1;
660}
661
662void tegra_get_camera_board_info(struct board_info *bi)
663{
664 memcpy(bi, &camera_board_info, sizeof(struct board_info));
665}
666
667__setup("cameraboard=", tegra_camera_board_info);
668
Steve Lind2f4e4d2011-07-11 12:45:06 -0700669static int __init tegra_modem_id(char *id)
670{
671 char *p = id;
672
673 modem_id = memparse(p, &p);
674 return 1;
675}
676
677int tegra_get_modem_id(void)
678{
679 return modem_id;
680}
681
682__setup("modem_id=", tegra_modem_id);
Laxman Dewangan87d07ce2011-06-15 00:48:57 +0530683
Jihoon Bangea8fd162011-12-12 11:00:14 -0800684
685
Colin Crossf9c9bde2010-10-19 16:12:33 -0700686/*
687 * Tegra has a protected aperture that prevents access by most non-CPU
688 * memory masters to addresses above the aperture value. Enabling it
689 * secures the CPU's memory from the GPU, except through the GART.
690 */
691void __init tegra_protected_aperture_init(unsigned long aperture)
692{
693#ifndef CONFIG_NVMAP_ALLOW_SYSMEM
694 void __iomem *mc_base = IO_ADDRESS(TEGRA_MC_BASE);
695 pr_info("Enabling Tegra protected aperture at 0x%08lx\n", aperture);
696 writel(aperture, mc_base + MC_SECURITY_CFG2);
697#else
698 pr_err("Tegra protected aperture disabled because nvmap is using "
699 "system memory\n");
700#endif
701}
702
Colin Cross115467a2010-10-19 21:09:29 -0700703/*
704 * Due to conflicting restrictions on the placement of the framebuffer,
705 * the bootloader is likely to leave the framebuffer pointed at a location
706 * in memory that is outside the grhost aperture. This function will move
707 * the framebuffer contents from a physical address that is anywher (lowmem,
708 * highmem, or outside the memory map) to a physical address that is outside
709 * the memory map.
710 */
711void tegra_move_framebuffer(unsigned long to, unsigned long from,
712 unsigned long size)
713{
714 struct page *page;
715 void __iomem *to_io;
716 void *from_virt;
717 unsigned long i;
718
719 BUG_ON(PAGE_ALIGN((unsigned long)to) != (unsigned long)to);
720 BUG_ON(PAGE_ALIGN(from) != from);
721 BUG_ON(PAGE_ALIGN(size) != size);
722
723 to_io = ioremap(to, size);
724 if (!to_io) {
725 pr_err("%s: Failed to map target framebuffer\n", __func__);
726 return;
727 }
728
Colin Cross115467a2010-10-19 21:09:29 -0700729 if (pfn_valid(page_to_pfn(phys_to_page(from)))) {
730 for (i = 0 ; i < size; i += PAGE_SIZE) {
731 page = phys_to_page(from + i);
732 from_virt = kmap(page);
Jon Mayoa8553a42011-08-29 18:09:16 -0700733 memcpy(to_io + i, from_virt, PAGE_SIZE);
Colin Cross115467a2010-10-19 21:09:29 -0700734 kunmap(page);
735 }
736 } else {
737 void __iomem *from_io = ioremap(from, size);
738 if (!from_io) {
739 pr_err("%s: Failed to map source framebuffer\n",
740 __func__);
741 goto out;
742 }
743
Kevin Huangece493d2011-07-05 18:27:43 -0700744 for (i = 0; i < size; i += 4)
Colin Cross115467a2010-10-19 21:09:29 -0700745 writel(readl(from_io + i), to_io + i);
746
747 iounmap(from_io);
748 }
749out:
750 iounmap(to_io);
751}
752
Hiro Sugawara510eb102011-12-13 09:12:26 -0800753#ifdef CONFIG_TEGRA_SMMU_BASE_AT_E0000000
754#define FORCE_SMMU_BASE_FOR_TEGRA3_A01 1
755#else
756#define FORCE_SMMU_BASE_FOR_TEGRA3_A01 0
757#endif
758#if FORCE_SMMU_BASE_FOR_TEGRA3_A01 || \
759 (defined(CONFIG_TEGRA_IOVMM_SMMU) && defined(CONFIG_ARCH_TEGRA_3x_SOC))
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700760/* Support for Tegra3 A01 chip mask that needs to have SMMU IOVA reside in
761 * the upper half of 4GB IOVA space. A02 and after use the bottom 1GB and
762 * do not need to reserve memory.
763 */
Hiro Sugawara510eb102011-12-13 09:12:26 -0800764#define SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700765#endif
766
Colin Cross838d7d62010-10-19 14:45:50 -0700767void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size,
768 unsigned long fb2_size)
769{
Hiro Sugawara510eb102011-12-13 09:12:26 -0800770#ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700771 int smmu_reserved = 0;
Hiro Sugawara10f14812011-09-13 17:20:35 -0700772 struct tegra_smmu_window *smmu_window = tegra_smmu_window(0);
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700773#endif
Colin Cross838d7d62010-10-19 14:45:50 -0700774
Scott Williams03122532011-01-13 14:30:20 -0800775 if (carveout_size) {
776 tegra_carveout_start = memblock_end_of_DRAM() - carveout_size;
777 if (memblock_remove(tegra_carveout_start, carveout_size)) {
778 pr_err("Failed to remove carveout %08lx@%08lx "
779 "from memory map\n",
Hiro Sugawara5cb430a2011-03-10 15:19:03 -0800780 carveout_size, tegra_carveout_start);
Scott Williams03122532011-01-13 14:30:20 -0800781 tegra_carveout_start = 0;
782 tegra_carveout_size = 0;
Kevin Huangece493d2011-07-05 18:27:43 -0700783 } else
Scott Williams03122532011-01-13 14:30:20 -0800784 tegra_carveout_size = carveout_size;
785 }
Colin Cross838d7d62010-10-19 14:45:50 -0700786
Scott Williams03122532011-01-13 14:30:20 -0800787 if (fb2_size) {
788 tegra_fb2_start = memblock_end_of_DRAM() - fb2_size;
789 if (memblock_remove(tegra_fb2_start, fb2_size)) {
Kevin Huangece493d2011-07-05 18:27:43 -0700790 pr_err("Failed to remove second framebuffer "
791 "%08lx@%08lx from memory map\n",
Hiro Sugawaradc1d2812011-04-29 11:59:37 -0700792 fb2_size, tegra_fb2_start);
Scott Williams03122532011-01-13 14:30:20 -0800793 tegra_fb2_start = 0;
794 tegra_fb2_size = 0;
795 } else
796 tegra_fb2_size = fb2_size;
797 }
Colin Cross838d7d62010-10-19 14:45:50 -0700798
Scott Williams03122532011-01-13 14:30:20 -0800799 if (fb_size) {
800 tegra_fb_start = memblock_end_of_DRAM() - fb_size;
801 if (memblock_remove(tegra_fb_start, fb_size)) {
802 pr_err("Failed to remove framebuffer %08lx@%08lx "
803 "from memory map\n",
Hiro Sugawara5cb430a2011-03-10 15:19:03 -0800804 fb_size, tegra_fb_start);
Scott Williams03122532011-01-13 14:30:20 -0800805 tegra_fb_start = 0;
806 tegra_fb_size = 0;
807 } else
808 tegra_fb_size = fb_size;
809 }
Colin Cross838d7d62010-10-19 14:45:50 -0700810
Colin Crossf9c9bde2010-10-19 16:12:33 -0700811 if (tegra_fb_size)
812 tegra_grhost_aperture = tegra_fb_start;
813
814 if (tegra_fb2_size && tegra_fb2_start < tegra_grhost_aperture)
815 tegra_grhost_aperture = tegra_fb2_start;
816
817 if (tegra_carveout_size && tegra_carveout_start < tegra_grhost_aperture)
818 tegra_grhost_aperture = tegra_carveout_start;
819
Hiro Sugawara510eb102011-12-13 09:12:26 -0800820#ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700821 if (!smmu_window) {
Hiro Sugawara10f14812011-09-13 17:20:35 -0700822 pr_err("No SMMU resource\n");
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700823 } else {
Hiro Sugawara0d218182011-04-08 13:21:02 -0700824 size_t smmu_window_size;
825
Hiro Sugawara510eb102011-12-13 09:12:26 -0800826 if (FORCE_SMMU_BASE_FOR_TEGRA3_A01 ||
827 (tegra_get_chipid() == TEGRA_CHIPID_TEGRA3 &&
828 tegra_get_revision() == TEGRA_REVISION_A01)) {
829 smmu_window->start = TEGRA_SMMU_BASE_TEGRA3_A01;
830 smmu_window->end = TEGRA_SMMU_BASE_TEGRA3_A01 +
831 TEGRA_SMMU_SIZE_TEGRA3_A01 - 1;
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700832 }
833 smmu_window_size = smmu_window->end + 1 - smmu_window->start;
834 if (smmu_window->start >= 0x80000000) {
835 if (memblock_reserve(smmu_window->start,
836 smmu_window_size))
837 pr_err(
838 "Failed to reserve SMMU I/O VA window %08lx@%08lx\n",
Hiro Sugawara0d218182011-04-08 13:21:02 -0700839 (unsigned long)smmu_window_size,
840 (unsigned long)smmu_window->start);
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700841 else
842 smmu_reserved = 1;
843 }
Scott Williams599c1122011-02-10 14:35:32 -0800844 }
845#endif
846
Prashant Gaikwadff192312011-08-03 14:49:20 +0530847 if (tegra_lp0_vec_size &&
848 (tegra_lp0_vec_start < memblock_end_of_DRAM())) {
849 if (memblock_reserve(tegra_lp0_vec_start, tegra_lp0_vec_size)) {
850 pr_err("Failed to reserve lp0_vec %08lx@%08lx\n",
851 tegra_lp0_vec_size, tegra_lp0_vec_start);
852 tegra_lp0_vec_start = 0;
853 tegra_lp0_vec_size = 0;
854 }
855 tegra_lp0_vec_relocate = false;
856 } else
857 tegra_lp0_vec_relocate = true;
858
Colin Cross838d7d62010-10-19 14:45:50 -0700859 /*
Kevin Huangece493d2011-07-05 18:27:43 -0700860 * We copy the bootloader's framebuffer to the framebuffer allocated
861 * above, and then free this one.
862 * */
863 if (tegra_bootloader_fb_size) {
864 tegra_bootloader_fb_size = PAGE_ALIGN(tegra_bootloader_fb_size);
Colin Cross838d7d62010-10-19 14:45:50 -0700865 if (memblock_reserve(tegra_bootloader_fb_start,
Scott Williams03122532011-01-13 14:30:20 -0800866 tegra_bootloader_fb_size)) {
Kevin Huangece493d2011-07-05 18:27:43 -0700867 pr_err("Failed to reserve bootloader frame buffer "
868 "%08lx@%08lx\n", tegra_bootloader_fb_size,
869 tegra_bootloader_fb_start);
Scott Williams03122532011-01-13 14:30:20 -0800870 tegra_bootloader_fb_start = 0;
871 tegra_bootloader_fb_size = 0;
872 }
Kevin Huangece493d2011-07-05 18:27:43 -0700873 }
Colin Cross838d7d62010-10-19 14:45:50 -0700874
875 pr_info("Tegra reserved memory:\n"
876 "LP0: %08lx - %08lx\n"
877 "Bootloader framebuffer: %08lx - %08lx\n"
878 "Framebuffer: %08lx - %08lx\n"
Scott Williams22d51692011-01-11 10:50:52 -0800879 "2nd Framebuffer: %08lx - %08lx\n"
Krishna Reddyb7d5a862011-10-05 12:23:37 -0700880 "Carveout: %08lx - %08lx\n"
881 "Vpr: %08lx - %08lx\n",
Colin Cross838d7d62010-10-19 14:45:50 -0700882 tegra_lp0_vec_start,
Scott Williams03122532011-01-13 14:30:20 -0800883 tegra_lp0_vec_size ?
884 tegra_lp0_vec_start + tegra_lp0_vec_size - 1 : 0,
Colin Cross838d7d62010-10-19 14:45:50 -0700885 tegra_bootloader_fb_start,
Scott Williams03122532011-01-13 14:30:20 -0800886 tegra_bootloader_fb_size ?
887 tegra_bootloader_fb_start + tegra_bootloader_fb_size - 1 : 0,
Colin Cross838d7d62010-10-19 14:45:50 -0700888 tegra_fb_start,
Scott Williams03122532011-01-13 14:30:20 -0800889 tegra_fb_size ?
890 tegra_fb_start + tegra_fb_size - 1 : 0,
Colin Cross838d7d62010-10-19 14:45:50 -0700891 tegra_fb2_start,
Scott Williams03122532011-01-13 14:30:20 -0800892 tegra_fb2_size ?
893 tegra_fb2_start + tegra_fb2_size - 1 : 0,
Colin Cross838d7d62010-10-19 14:45:50 -0700894 tegra_carveout_start,
Scott Williams03122532011-01-13 14:30:20 -0800895 tegra_carveout_size ?
Krishna Reddyb7d5a862011-10-05 12:23:37 -0700896 tegra_carveout_start + tegra_carveout_size - 1 : 0,
897 tegra_vpr_start,
898 tegra_vpr_size ?
899 tegra_vpr_start + tegra_vpr_size - 1 : 0);
Scott Williams599c1122011-02-10 14:35:32 -0800900
Hiro Sugawara510eb102011-12-13 09:12:26 -0800901#ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700902 if (smmu_reserved)
Hiro Sugawara10f14812011-09-13 17:20:35 -0700903 pr_info("SMMU: %08lx - %08lx\n",
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700904 smmu_window->start, smmu_window->end);
Scott Williams599c1122011-02-10 14:35:32 -0800905#endif
Colin Cross838d7d62010-10-19 14:45:50 -0700906}
Kevin Huangece493d2011-07-05 18:27:43 -0700907
Haley Teng290e96f2011-09-27 12:20:32 +0800908static struct resource ram_console_resources[] = {
909 {
910 .flags = IORESOURCE_MEM,
911 },
912};
913
914static struct platform_device ram_console_device = {
915 .name = "ram_console",
916 .id = -1,
917 .num_resources = ARRAY_SIZE(ram_console_resources),
918 .resource = ram_console_resources,
919};
920
921void __init tegra_ram_console_debug_reserve(unsigned long ram_console_size)
922{
923 struct resource *res;
924 long ret;
925
926 res = platform_get_resource(&ram_console_device, IORESOURCE_MEM, 0);
927 if (!res)
928 goto fail;
929 res->start = memblock_end_of_DRAM() - ram_console_size;
930 res->end = res->start + ram_console_size - 1;
931 ret = memblock_remove(res->start, ram_console_size);
932 if (ret)
933 goto fail;
934
935 return;
936
937fail:
938 ram_console_device.resource = NULL;
939 ram_console_device.num_resources = 0;
940 pr_err("Failed to reserve memory block for ram console\n");
941}
942
943void __init tegra_ram_console_debug_init(void)
944{
945 int err;
946
947 err = platform_device_register(&ram_console_device);
948 if (err) {
949 pr_err("%s: ram console registration failed (%d)!\n", __func__, err);
950 }
951}
952
Kevin Huangece493d2011-07-05 18:27:43 -0700953void __init tegra_release_bootloader_fb(void)
954{
955 /* Since bootloader fb is reserved in common.c, it is freed here. */
956 if (tegra_bootloader_fb_size)
957 if (memblock_free(tegra_bootloader_fb_start,
958 tegra_bootloader_fb_size))
959 pr_err("Failed to free bootloader fb.\n");
960}
Victor(Weiguo) Pan5ab70782011-08-23 14:48:30 -0700961
Bharat Nihalani50e7bec2011-05-19 20:09:14 +0530962#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
Wen Yifd9bfde2011-04-18 14:21:25 -0700963static char cpufreq_gov_default[32];
964static char *cpufreq_gov_conservative = "conservative";
965static char *cpufreq_sysfs_place_holder="/sys/devices/system/cpu/cpu%i/cpufreq/scaling_governor";
Wen Yi10027352011-06-06 13:51:12 -0700966static char *cpufreq_gov_conservative_param="/sys/devices/system/cpu/cpufreq/conservative/%s";
Wen Yifd9bfde2011-04-18 14:21:25 -0700967
968static void cpufreq_set_governor(char *governor)
969{
970 struct file *scaling_gov = NULL;
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -0700971 mm_segment_t old_fs;
Wen Yifd9bfde2011-04-18 14:21:25 -0700972 char buf[128];
Diwakar Tundlam47719fe2012-01-30 15:53:05 -0800973 int i = 0;
Wen Yifd9bfde2011-04-18 14:21:25 -0700974 loff_t offset = 0;
975
976 if (governor == NULL)
977 return;
978
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -0700979 /* change to KERNEL_DS address limit */
980 old_fs = get_fs();
981 set_fs(KERNEL_DS);
Prashant Gaikwad8d1e39c2011-12-26 16:41:29 +0530982#ifndef CONFIG_TEGRA_AUTO_HOTPLUG
Sang-Hun Lee00535522011-12-22 11:06:29 -0800983 for_each_online_cpu(i)
984#endif
985 {
Wen Yifd9bfde2011-04-18 14:21:25 -0700986 sprintf(buf, cpufreq_sysfs_place_holder, i);
987 scaling_gov = filp_open(buf, O_RDWR, 0);
Wen Yi50582972012-01-06 16:29:00 -0800988 if (scaling_gov != NULL) {
Wen Yifd9bfde2011-04-18 14:21:25 -0700989 if (scaling_gov->f_op != NULL &&
990 scaling_gov->f_op->write != NULL)
991 scaling_gov->f_op->write(scaling_gov,
992 governor,
993 strlen(governor),
994 &offset);
995 else
996 pr_err("f_op might be null\n");
997
998 filp_close(scaling_gov, NULL);
Wen Yi50582972012-01-06 16:29:00 -0800999 } else {
1000 pr_err("%s. Can't open %s\n", __func__, buf);
Wen Yifd9bfde2011-04-18 14:21:25 -07001001 }
1002 }
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001003 set_fs(old_fs);
Wen Yifd9bfde2011-04-18 14:21:25 -07001004}
1005
1006void cpufreq_save_default_governor(void)
1007{
1008 struct file *scaling_gov = NULL;
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001009 mm_segment_t old_fs;
Wen Yifd9bfde2011-04-18 14:21:25 -07001010 char buf[128];
1011 loff_t offset = 0;
1012
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001013 /* change to KERNEL_DS address limit */
1014 old_fs = get_fs();
1015 set_fs(KERNEL_DS);
1016
Wen Yifd9bfde2011-04-18 14:21:25 -07001017 buf[127] = 0;
1018 sprintf(buf, cpufreq_sysfs_place_holder,0);
1019 scaling_gov = filp_open(buf, O_RDONLY, 0);
Wen Yi50582972012-01-06 16:29:00 -08001020 if (scaling_gov != NULL) {
Wen Yifd9bfde2011-04-18 14:21:25 -07001021 if (scaling_gov->f_op != NULL &&
1022 scaling_gov->f_op->read != NULL)
1023 scaling_gov->f_op->read(scaling_gov,
1024 cpufreq_gov_default,
Wen Yi10027352011-06-06 13:51:12 -07001025 32,
Wen Yifd9bfde2011-04-18 14:21:25 -07001026 &offset);
1027 else
1028 pr_err("f_op might be null\n");
1029
1030 filp_close(scaling_gov, NULL);
Wen Yi50582972012-01-06 16:29:00 -08001031 } else {
1032 pr_err("%s. Can't open %s\n", __func__, buf);
Wen Yifd9bfde2011-04-18 14:21:25 -07001033 }
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001034 set_fs(old_fs);
Wen Yifd9bfde2011-04-18 14:21:25 -07001035}
1036
1037void cpufreq_restore_default_governor(void)
1038{
1039 cpufreq_set_governor(cpufreq_gov_default);
1040}
1041
Wen Yi50582972012-01-06 16:29:00 -08001042void cpufreq_set_conservative_governor_param(char *name, int value)
Wen Yi10027352011-06-06 13:51:12 -07001043{
1044 struct file *gov_param = NULL;
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001045 mm_segment_t old_fs;
Wen Yi50582972012-01-06 16:29:00 -08001046 static char buf[128], param_value[8];
1047 loff_t offset = 0;
Wen Yi10027352011-06-06 13:51:12 -07001048
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001049 /* change to KERNEL_DS address limit */
1050 old_fs = get_fs();
1051 set_fs(KERNEL_DS);
1052
Wen Yi50582972012-01-06 16:29:00 -08001053 sprintf(param_value, "%d", value);
1054 sprintf(buf, cpufreq_gov_conservative_param, name);
1055 gov_param = filp_open(buf, O_RDWR, 0);
1056 if (gov_param != NULL) {
Wen Yi10027352011-06-06 13:51:12 -07001057 if (gov_param->f_op != NULL &&
1058 gov_param->f_op->write != NULL)
1059 gov_param->f_op->write(gov_param,
Wen Yi50582972012-01-06 16:29:00 -08001060 param_value,
1061 strlen(param_value),
Wen Yi10027352011-06-06 13:51:12 -07001062 &offset);
1063 else
1064 pr_err("f_op might be null\n");
1065
1066 filp_close(gov_param, NULL);
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001067 } else {
Wen Yi50582972012-01-06 16:29:00 -08001068 pr_err("%s. Can't open %s\n", __func__, buf);
Wen Yi10027352011-06-06 13:51:12 -07001069 }
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001070 set_fs(old_fs);
Wen Yi10027352011-06-06 13:51:12 -07001071}
1072
Wen Yifd9bfde2011-04-18 14:21:25 -07001073void cpufreq_set_conservative_governor(void)
1074{
1075 cpufreq_set_governor(cpufreq_gov_conservative);
1076}
Bharat Nihalani50e7bec2011-05-19 20:09:14 +05301077#endif /* CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND */