blob: f9902cf333ef586ff487e4635f0903e94041189b [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"
Laxman Dewangan97d41432012-02-22 17:35:38 +053048#include "devices.h"
Colin Cross8e437c22010-11-28 22:36:08 -080049
Scott Williams816ab052010-12-07 11:19:20 -080050#define MC_SECURITY_CFG2 0x7c
Colin Crossf9c9bde2010-10-19 16:12:33 -070051
Rakesh Bodla1ad210a2011-05-31 15:18:00 +053052#define AHB_ARBITRATION_PRIORITY_CTRL 0x4
53#define AHB_PRIORITY_WEIGHT(x) (((x) & 0x7) << 29)
54#define PRIORITY_SELECT_USB BIT(6)
55#define PRIORITY_SELECT_USB2 BIT(18)
56#define PRIORITY_SELECT_USB3 BIT(17)
57
58#define AHB_GIZMO_AHB_MEM 0xc
59#define ENB_FAST_REARBITRATE BIT(2)
Jay Chengce4a7df2011-06-09 17:34:35 -040060#define DONT_SPLIT_AHB_WR BIT(7)
Rakesh Bodla1ad210a2011-05-31 15:18:00 +053061
Gaurav Sarode7e782c02012-02-27 21:54:30 +053062#define RECOVERY_MODE BIT(31)
63#define BOOTLOADER_MODE BIT(30)
Gaurav Sarodec2723e92012-03-02 18:30:19 +053064#define FORCED_RECOVERY_MODE BIT(1)
Gaurav Sarode7e782c02012-02-27 21:54:30 +053065
Rakesh Bodla1ad210a2011-05-31 15:18:00 +053066#define AHB_GIZMO_USB 0x1c
67#define AHB_GIZMO_USB2 0x78
68#define AHB_GIZMO_USB3 0x7c
69#define IMMEDIATE BIT(18)
70
71#define AHB_MEM_PREFETCH_CFG3 0xe0
72#define AHB_MEM_PREFETCH_CFG4 0xe4
73#define AHB_MEM_PREFETCH_CFG1 0xec
74#define AHB_MEM_PREFETCH_CFG2 0xf0
75#define PREFETCH_ENB BIT(31)
76#define MST_ID(x) (((x) & 0x1f) << 26)
77#define AHBDMA_MST_ID MST_ID(5)
78#define USB_MST_ID MST_ID(6)
79#define USB2_MST_ID MST_ID(18)
80#define USB3_MST_ID MST_ID(17)
81#define ADDR_BNDRY(x) (((x) & 0xf) << 21)
82#define INACTIVITY_TIMEOUT(x) (((x) & 0xffff) << 0)
83
Colin Cross838d7d62010-10-19 14:45:50 -070084unsigned long tegra_bootloader_fb_start;
85unsigned long tegra_bootloader_fb_size;
86unsigned long tegra_fb_start;
87unsigned long tegra_fb_size;
88unsigned long tegra_fb2_start;
89unsigned long tegra_fb2_size;
90unsigned long tegra_carveout_start;
91unsigned long tegra_carveout_size;
Krishna Reddyb7d5a862011-10-05 12:23:37 -070092unsigned long tegra_vpr_start;
93unsigned long tegra_vpr_size;
Colin Cross8e437c22010-11-28 22:36:08 -080094unsigned long tegra_lp0_vec_start;
95unsigned long tegra_lp0_vec_size;
Prashant Gaikwadff192312011-08-03 14:49:20 +053096bool tegra_lp0_vec_relocate;
Scott Williams03122532011-01-13 14:30:20 -080097unsigned long tegra_grhost_aperture = ~0ul;
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +053098static bool is_tegra_debug_uart_hsport;
Laxman Dewangan87d07ce2011-06-15 00:48:57 +053099static struct board_info pmu_board_info;
Hyungwoo Yang187ada82011-10-24 15:06:17 -0700100static struct board_info display_board_info;
Jihoon Bangea8fd162011-12-12 11:00:14 -0800101static struct board_info camera_board_info;
Colin Crossd8611962010-01-28 16:40:29 -0800102
Alex Frid3a5fc7c2011-05-11 16:01:44 -0700103static int pmu_core_edp = 1200; /* default 1.2V EDP limit */
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530104static int board_panel_type;
Laxman Dewangan8644fc02011-09-04 17:10:13 +0530105static enum power_supply_type pow_supply_type = POWER_SUPPLY_TYPE_MAINS;
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530106
Colin Cross699fe142010-08-23 18:37:25 -0700107void (*arch_reset)(char mode, const char *cmd) = tegra_assert_system_reset;
108
Scott Williamsae811c32011-02-10 15:45:06 -0800109#define NEVER_RESET 0
Scott Williams9bc40532011-01-28 03:26:28 -0800110
Colin Cross699fe142010-08-23 18:37:25 -0700111void tegra_assert_system_reset(char mode, const char *cmd)
112{
Scott Williams9bc40532011-01-28 03:26:28 -0800113#if defined(CONFIG_TEGRA_FPGA_PLATFORM) || NEVER_RESET
Scott Williamsae811c32011-02-10 15:45:06 -0800114 printk("tegra_assert_system_reset() ignored.....");
Scott Williams9bc40532011-01-28 03:26:28 -0800115 do { } while (1);
116#else
Deepesh Gujarathi43921782010-12-07 14:09:22 +0530117 void __iomem *reset = IO_ADDRESS(TEGRA_PMC_BASE + 0x00);
Colin Cross699fe142010-08-23 18:37:25 -0700118 u32 reg;
119
Gaurav Sarode7e782c02012-02-27 21:54:30 +0530120 reg = readl_relaxed(reset + PMC_SCRATCH0);
Gaurav Sarodec2723e92012-03-02 18:30:19 +0530121 /* Writing recovery kernel or Bootloader mode in SCRATCH0 31:30:1 */
Gaurav Sarode7e782c02012-02-27 21:54:30 +0530122 if (cmd) {
123 if (!strcmp(cmd, "recovery"))
124 reg |= RECOVERY_MODE;
125 else if (!strcmp(cmd, "bootloader"))
126 reg |= BOOTLOADER_MODE;
Gaurav Sarodec2723e92012-03-02 18:30:19 +0530127 else if (!strcmp(cmd, "forced-recovery"))
128 reg |= FORCED_RECOVERY_MODE;
129 else
130 reg &= ~(BOOTLOADER_MODE | RECOVERY_MODE | FORCED_RECOVERY_MODE);
Gaurav Sarode7e782c02012-02-27 21:54:30 +0530131 }
132 else {
Gaurav Sarodec2723e92012-03-02 18:30:19 +0530133 /* Clearing SCRATCH0 31:30:1 on default reboot */
134 reg &= ~(BOOTLOADER_MODE | RECOVERY_MODE | FORCED_RECOVERY_MODE);
Gaurav Sarode7e782c02012-02-27 21:54:30 +0530135 }
136 writel_relaxed(reg, reset + PMC_SCRATCH0);
Simon Glass375b19c2011-02-17 08:13:57 -0800137 /* use *_related to avoid spinlock since caches are off */
138 reg = readl_relaxed(reset);
Deepesh Gujarathi43921782010-12-07 14:09:22 +0530139 reg |= 0x10;
Simon Glass375b19c2011-02-17 08:13:57 -0800140 writel_relaxed(reg, reset);
Scott Williams4ad5ff12011-01-07 20:43:13 -0800141#endif
Colin Cross699fe142010-08-23 18:37:25 -0700142}
Steve Lind2f4e4d2011-07-11 12:45:06 -0700143static int modem_id;
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530144static int debug_uart_port_id;
Laxman Dewangan57b08762011-09-18 16:49:10 +0530145static enum audio_codec_type audio_codec_name;
Ashwini Ghuge6bf2a5b2012-03-19 17:21:38 +0530146static enum image_type board_image_type = system_image;
Laxman Dewangan1f8be3d2011-10-15 15:44:04 +0530147static int max_cpu_current;
Colin Cross699fe142010-08-23 18:37:25 -0700148
Laxman Dewangan844407d2011-04-27 19:11:08 +0530149/* WARNING: There is implicit client of pllp_out3 like i2c, uart, dsi
150 * and so this clock (pllp_out3) should never be disabled.
151 */
Colin Crossd8611962010-01-28 16:40:29 -0800152static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
153 /* name parent rate enabled */
154 { "clk_m", NULL, 0, true },
Yudong Tanf8cd6292011-07-01 11:26:17 -0700155#ifdef CONFIG_TEGRA_SILICON_PLATFORM
Alex Fridc86c2252011-05-28 00:21:30 -0700156#ifdef CONFIG_ARCH_TEGRA_2x_SOC
Scott Williams816ab052010-12-07 11:19:20 -0800157 { "pll_p", NULL, 216000000, true },
Colin Crossd8611962010-01-28 16:40:29 -0800158 { "pll_p_out1", "pll_p", 28800000, true },
Prashant Gaikwad1529b8e2012-01-23 12:43:28 +0530159 { "pll_p_out2", "pll_p", 48000000, false },
Colin Crossd8611962010-01-28 16:40:29 -0800160 { "pll_p_out3", "pll_p", 72000000, true },
Prashant Gaikwad1529b8e2012-01-23 12:43:28 +0530161 { "pll_p_out4", "pll_p", 108000000, false },
Prashant Gaikwad9a975332011-11-01 18:16:47 +0530162 { "pll_m", "clk_m", 0, true },
Pritesh Raithathabb1d62b2011-11-11 16:52:11 +0530163 { "pll_m_out1", "pll_m", 120000000, true },
Prashant Gaikwad9a975332011-11-01 18:16:47 +0530164 { "sclk", "pll_c_out1", 40000000, true },
Scott Williams07fc3312011-05-23 22:08:42 -0700165 { "hclk", "sclk", 40000000, true },
166 { "pclk", "hclk", 40000000, true },
Prashant Gaikwad9a975332011-11-01 18:16:47 +0530167 { "mpe", "pll_c", 0, false },
168 { "epp", "pll_c", 0, false },
169 { "vi_sensor", "pll_c", 0, false },
170 { "vi", "pll_c", 0, false },
171 { "2d", "pll_c", 0, false },
172 { "3d", "pll_c", 0, false },
Scott Williams07fc3312011-05-23 22:08:42 -0700173#else
Alex Fride818b6e2012-01-12 20:27:55 -0800174 { "pll_p", NULL, 0, true },
175 { "pll_p_out1", "pll_p", 0, false },
ScottPetersonfde0dd42011-12-28 13:40:20 -0800176 { "pll_p_out2", "pll_p", 48000000, false },
Alex Fride818b6e2012-01-12 20:27:55 -0800177 { "pll_p_out3", "pll_p", 0, true },
Alex Frid58af6ba2011-10-24 18:51:32 -0700178 { "pll_m_out1", "pll_m", 275000000, false },
Peter Zu590fd1f2012-02-05 22:10:42 -0800179 { "pll_p_out4", "pll_p", 102000000, true },
Alex Fridc86c2252011-05-28 00:21:30 -0700180 { "sclk", "pll_p_out4", 102000000, true },
181 { "hclk", "sclk", 102000000, true },
182 { "pclk", "hclk", 51000000, true },
Laxman Dewangance8ac372012-03-12 23:03:55 +0530183 { "sbc5.sclk", NULL, 40000000, false},
184 { "sbc6.sclk", NULL, 40000000, false},
Alex Frid8b5ce662011-01-31 10:07:57 -0800185#endif
Laxman Dewangance8ac372012-03-12 23:03:55 +0530186 { "sbc1.sclk", NULL, 40000000, false},
187 { "sbc2.sclk", NULL, 40000000, false},
188 { "sbc3.sclk", NULL, 40000000, false},
189 { "sbc4.sclk", NULL, 40000000, false},
Scott Williams0aac1552011-06-10 12:58:11 -0700190#else
191 { "pll_p", NULL, 216000000, true },
ScottPetersonfde0dd42011-12-28 13:40:20 -0800192 { "pll_p_out1", "pll_p", 28800000, false },
193 { "pll_p_out2", "pll_p", 48000000, false },
Scott Williams0aac1552011-06-10 12:58:11 -0700194 { "pll_p_out3", "pll_p", 72000000, true },
195 { "pll_m_out1", "pll_m", 275000000, true },
196 { "pll_c", NULL, ULONG_MAX, false },
197 { "pll_c_out1", "pll_c", 208000000, false },
ScottPetersonfde0dd42011-12-28 13:40:20 -0800198 { "pll_p_out4", "pll_p", 108000000, false },
Scott Williams0aac1552011-06-10 12:58:11 -0700199 { "sclk", "pll_p_out4", 108000000, true },
200 { "hclk", "sclk", 108000000, true },
201 { "pclk", "hclk", 54000000, true },
202#endif
ScottPetersonf8b15a82012-01-19 11:27:07 -0800203#ifdef CONFIG_TEGRA_SLOW_CSITE
204 { "csite", "clk_m", 1000000, true },
205#else
206 { "csite", NULL, 0, true },
207#endif
Colin Crosscd51d0e2011-02-21 17:05:36 -0800208 { "emc", NULL, 0, true },
209 { "cpu", NULL, 0, true },
Alex Fridd3b4e362011-05-26 22:58:21 -0700210 { "kfuse", NULL, 0, true },
Varun Wadekar0e0ccdb2011-06-25 16:42:37 +0530211 { "fuse", NULL, 0, true },
Scott Williams816ab052010-12-07 11:19:20 -0800212 { "pll_u", NULL, 480000000, false },
Alex Fridc86c2252011-05-28 00:21:30 -0700213 { "sdmmc1", "pll_p", 48000000, false},
Pavan Kunapuli0a420462011-03-16 19:29:42 +0530214 { "sdmmc3", "pll_p", 48000000, false},
Pavan Kunapuli4a743e72011-11-08 18:02:52 +0530215 { "sdmmc4", "pll_p", 48000000, false},
ScottPetersonc9a567732012-01-17 16:37:09 -0800216 { "pll_a", "pll_p_out1", 0, false},
217 { "pll_a_out0", "pll_a", 0, false},
Scott Williams07fc3312011-05-23 22:08:42 -0700218#ifndef CONFIG_ARCH_TEGRA_2x_SOC
Alex Frid5be85392011-06-28 20:50:29 -0700219 { "cbus", "pll_c", 416000000, false },
Alex Frid7359d832011-05-13 23:58:33 -0700220 { "pll_c_out1", "pll_c", 208000000, false },
Alex Frid67982942012-01-19 22:05:45 -0800221 { "mselect", "pll_p", 102000000, true },
Alex Frid7f970e72011-02-04 12:04:14 -0800222#endif
Colin Crossd8611962010-01-28 16:40:29 -0800223 { NULL, NULL, 0, 0},
224};
Erik Gillingc5f80062010-01-21 16:53:02 -0800225
Scott Williams70d70472012-02-02 18:55:00 -0800226#ifdef CONFIG_CACHE_L2X0
227#ifdef CONFIG_TRUSTED_FOUNDATIONS
Chris Johnson644d1fb2011-11-18 16:14:07 -0800228static void tegra_cache_smc(bool enable, u32 arg)
229{
230 void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
231 bool need_affinity_switch;
232 bool can_switch_affinity;
233 bool l2x0_enabled;
234 cpumask_t local_cpu_mask;
235 cpumask_t saved_cpu_mask;
236 unsigned long flags;
237 long ret;
238
239 /*
240 * ISSUE : Some registers of PL310 controler must be written
241 * from Secure context (and from CPU0)!
242 *
243 * When called form Normal we obtain an abort or do nothing.
244 * Instructions that must be called in Secure:
245 * - Write to Control register (L2X0_CTRL==0x100)
246 * - Write in Auxiliary controler (L2X0_AUX_CTRL==0x104)
247 * - Invalidate all entries (L2X0_INV_WAY==0x77C),
248 * mandatory at boot time.
249 * - Tag and Data RAM Latency Control Registers
250 * (0x108 & 0x10C) must be written in Secure.
251 */
252 need_affinity_switch = (smp_processor_id() != 0);
253 can_switch_affinity = !irqs_disabled();
254
255 WARN_ON(need_affinity_switch && !can_switch_affinity);
256 if (need_affinity_switch && can_switch_affinity) {
257 cpu_set(0, local_cpu_mask);
258 sched_getaffinity(0, &saved_cpu_mask);
259 ret = sched_setaffinity(0, &local_cpu_mask);
260 WARN_ON(ret != 0);
261 }
262
263 local_irq_save(flags);
264 l2x0_enabled = readl_relaxed(p + L2X0_CTRL) & 1;
265 if (enable && !l2x0_enabled)
266 tegra_generic_smc(0xFFFFF100, 0x00000001, arg);
267 else if (!enable && l2x0_enabled)
268 tegra_generic_smc(0xFFFFF100, 0x00000002, arg);
269 local_irq_restore(flags);
270
271 if (need_affinity_switch && can_switch_affinity) {
272 ret = sched_setaffinity(0, &saved_cpu_mask);
273 WARN_ON(ret != 0);
274 }
275}
276
277static void tegra_l2x0_disable(void)
278{
279 unsigned long flags;
280 static u32 l2x0_way_mask;
281
282 if (!l2x0_way_mask) {
283 void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
284 u32 aux_ctrl;
285 u32 ways;
286
287 aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
288 ways = (aux_ctrl & (1 << 16)) ? 16 : 8;
289 l2x0_way_mask = (1 << ways) - 1;
290 }
291
292 local_irq_save(flags);
293 tegra_cache_smc(false, l2x0_way_mask);
294 local_irq_restore(flags);
295}
Scott Williams70d70472012-02-02 18:55:00 -0800296#endif /* CONFIG_TRUSTED_FOUNDATIONS */
Chris Johnson644d1fb2011-11-18 16:14:07 -0800297
Krishna Reddy1212eb82011-12-01 15:32:36 -0800298void tegra_init_cache(bool init)
Erik Gillingc5f80062010-01-21 16:53:02 -0800299{
Erik Gillingc5f80062010-01-21 16:53:02 -0800300 void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
Scott Williams191914c2010-12-27 19:03:57 -0800301 u32 aux_ctrl;
Diwakar Tundlamf4ca2962011-12-02 15:49:42 -0800302 u32 speedo;
Krishna Reddy58eb2d02011-12-05 12:57:07 -0800303 u32 tmp;
Erik Gillingc5f80062010-01-21 16:53:02 -0800304
Chris Johnson644d1fb2011-11-18 16:14:07 -0800305#ifdef CONFIG_TRUSTED_FOUNDATIONS
306 /* issue the SMC to enable the L2 */
307 aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
308 tegra_cache_smc(true, aux_ctrl);
309
310 /* after init, reread aux_ctrl and register handlers */
311 aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
312 l2x0_init(p, aux_ctrl, 0xFFFFFFFF);
313
314 /* override outer_disable() with our disable */
315 outer_cache.disable = tegra_l2x0_disable;
316#else
Scott Williams816ab052010-12-07 11:19:20 -0800317#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
Colin Cross535371c2011-01-22 00:36:14 -0800318 writel_relaxed(0x331, p + L2X0_TAG_LATENCY_CTRL);
319 writel_relaxed(0x441, p + L2X0_DATA_LATENCY_CTRL);
Erik Gillingc5f80062010-01-21 16:53:02 -0800320
Scott Williams816ab052010-12-07 11:19:20 -0800321#elif defined(CONFIG_ARCH_TEGRA_3x_SOC)
Yudong Tanf8cd6292011-07-01 11:26:17 -0700322#ifdef CONFIG_TEGRA_SILICON_PLATFORM
Scott Williams1245c8e2011-01-05 17:53:39 -0800323 /* PL310 RAM latency is CPU dependent. NOTE: Changes here
324 must also be reflected in __cortex_a9_l2x0_restart */
325
326 if (is_lp_cluster()) {
327 writel(0x221, p + L2X0_TAG_LATENCY_CTRL);
328 writel(0x221, p + L2X0_DATA_LATENCY_CTRL);
329 } else {
Diwakar Tundlamf4ca2962011-12-02 15:49:42 -0800330 /* relax l2-cache latency for speedos 4,5,6 (T33's chips) */
331 speedo = tegra_cpu_speedo_id();
Alex Fridd83fa392012-01-23 13:40:48 -0800332 if (speedo == 4 || speedo == 5 || speedo == 6 ||
333 speedo == 12 || speedo == 13) {
Diwakar Tundlamf4ca2962011-12-02 15:49:42 -0800334 writel(0x442, p + L2X0_TAG_LATENCY_CTRL);
335 writel(0x552, p + L2X0_DATA_LATENCY_CTRL);
336 } else {
337 writel(0x441, p + L2X0_TAG_LATENCY_CTRL);
338 writel(0x551, p + L2X0_DATA_LATENCY_CTRL);
339 }
Scott Williams1245c8e2011-01-05 17:53:39 -0800340 }
Yudong Tanf8cd6292011-07-01 11:26:17 -0700341#else
342 writel(0x770, p + L2X0_TAG_LATENCY_CTRL);
343 writel(0x770, p + L2X0_DATA_LATENCY_CTRL);
Scott Williams816ab052010-12-07 11:19:20 -0800344#endif
Scott Williams816ab052010-12-07 11:19:20 -0800345#endif
Krishna Reddy58eb2d02011-12-05 12:57:07 -0800346 aux_ctrl = readl(p + L2X0_CACHE_TYPE);
347 aux_ctrl = (aux_ctrl & 0x700) << (17-8);
348 aux_ctrl |= 0x7C000001;
Krishna Reddy1212eb82011-12-01 15:32:36 -0800349 if (init) {
Krishna Reddy1212eb82011-12-01 15:32:36 -0800350 l2x0_init(p, aux_ctrl, 0x8200c3fe);
Krishna Reddy58eb2d02011-12-05 12:57:07 -0800351 } else {
352 tmp = aux_ctrl;
353 aux_ctrl = readl(p + L2X0_AUX_CTRL);
354 aux_ctrl &= 0x8200c3fe;
355 aux_ctrl |= tmp;
356 writel(aux_ctrl, p + L2X0_AUX_CTRL);
Krishna Reddy1212eb82011-12-01 15:32:36 -0800357 }
Chris Johnson644d1fb2011-11-18 16:14:07 -0800358 l2x0_enable();
359#endif
Erik Gillingc5f80062010-01-21 16:53:02 -0800360}
Scott Williams70d70472012-02-02 18:55:00 -0800361#endif
Erik Gillingc5f80062010-01-21 16:53:02 -0800362
Dima Zavin7db7cbc2010-09-16 17:58:05 -0700363static void __init tegra_init_power(void)
364{
Scott Williams1a536c32011-09-01 16:20:47 -0700365#ifdef CONFIG_ARCH_TEGRA_HAS_SATA
Karan Jhavar49adefb2011-06-09 14:50:35 -0700366 tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_SATA);
Karan Jhavar93962282011-05-16 17:00:43 -0700367#endif
Scott Williams1a536c32011-09-01 16:20:47 -0700368#ifdef CONFIG_ARCH_TEGRA_HAS_PCIE
Karan Jhavar93962282011-05-16 17:00:43 -0700369 tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_PCIE);
Scott Williams1a536c32011-09-01 16:20:47 -0700370#endif
Dima Zavin7db7cbc2010-09-16 17:58:05 -0700371}
372
Rakesh Bodla1ad210a2011-05-31 15:18:00 +0530373static inline unsigned long gizmo_readl(unsigned long offset)
374{
375 return readl(IO_TO_VIRT(TEGRA_AHB_GIZMO_BASE + offset));
376}
377
378static inline void gizmo_writel(unsigned long value, unsigned long offset)
379{
380 writel(value, IO_TO_VIRT(TEGRA_AHB_GIZMO_BASE + offset));
381}
382
383static void __init tegra_init_ahb_gizmo_settings(void)
384{
385 unsigned long val;
386
387 val = gizmo_readl(AHB_GIZMO_AHB_MEM);
Jay Chengce4a7df2011-06-09 17:34:35 -0400388 val |= ENB_FAST_REARBITRATE | IMMEDIATE | DONT_SPLIT_AHB_WR;
Rakesh Bodla1ad210a2011-05-31 15:18:00 +0530389 gizmo_writel(val, AHB_GIZMO_AHB_MEM);
390
391 val = gizmo_readl(AHB_GIZMO_USB);
392 val |= IMMEDIATE;
393 gizmo_writel(val, AHB_GIZMO_USB);
394
395 val = gizmo_readl(AHB_GIZMO_USB2);
396 val |= IMMEDIATE;
397 gizmo_writel(val, AHB_GIZMO_USB2);
398
399 val = gizmo_readl(AHB_GIZMO_USB3);
400 val |= IMMEDIATE;
401 gizmo_writel(val, AHB_GIZMO_USB3);
402
403 val = gizmo_readl(AHB_ARBITRATION_PRIORITY_CTRL);
404 val |= PRIORITY_SELECT_USB | PRIORITY_SELECT_USB2 | PRIORITY_SELECT_USB3
405 | AHB_PRIORITY_WEIGHT(7);
406 gizmo_writel(val, AHB_ARBITRATION_PRIORITY_CTRL);
407
408 val = gizmo_readl(AHB_MEM_PREFETCH_CFG1);
409 val &= ~MST_ID(~0);
410 val |= PREFETCH_ENB | AHBDMA_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
411 gizmo_writel(val, AHB_MEM_PREFETCH_CFG1);
412
413 val = gizmo_readl(AHB_MEM_PREFETCH_CFG2);
414 val &= ~MST_ID(~0);
415 val |= PREFETCH_ENB | USB_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
416 gizmo_writel(val, AHB_MEM_PREFETCH_CFG2);
417
418 val = gizmo_readl(AHB_MEM_PREFETCH_CFG3);
419 val &= ~MST_ID(~0);
420 val |= PREFETCH_ENB | USB3_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
421 gizmo_writel(val, AHB_MEM_PREFETCH_CFG3);
422
423 val = gizmo_readl(AHB_MEM_PREFETCH_CFG4);
424 val &= ~MST_ID(~0);
425 val |= PREFETCH_ENB | USB2_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
426 gizmo_writel(val, AHB_MEM_PREFETCH_CFG4);
427}
428
Colin Cross0cf62302011-02-21 17:10:14 -0800429void __init tegra_init_early(void)
Erik Gillingc5f80062010-01-21 16:53:02 -0800430{
Scott Williams55f67602011-07-27 20:10:06 -0700431#ifndef CONFIG_SMP
432 /* For SMP system, initializing the reset handler here is too
433 late. For non-SMP systems, the function that calls the reset
434 handler initializer is not called, so do it here for non-SMP. */
435 tegra_cpu_reset_handler_init();
436#endif
Colin Cross73625e32010-06-23 15:49:17 -0700437 tegra_init_fuse();
Colin Cross45a1ca02011-03-28 17:47:31 -0700438 tegra_gpio_resume_init();
Colin Crossd8611962010-01-28 16:40:29 -0800439 tegra_init_clock();
Colin Cross120c3562011-03-28 17:48:56 -0700440 tegra_init_pinmux();
Colin Crossd8611962010-01-28 16:40:29 -0800441 tegra_clk_init_from_table(common_clk_init_table);
Dima Zavin7db7cbc2010-09-16 17:58:05 -0700442 tegra_init_power();
Krishna Reddy1212eb82011-12-01 15:32:36 -0800443 tegra_init_cache(true);
Rakesh Bodla1ad210a2011-05-31 15:18:00 +0530444 tegra_init_ahb_gizmo_settings();
Laxman Dewangan97d41432012-02-22 17:35:38 +0530445 tegra_init_debug_uart_rate();
Erik Gillingc5f80062010-01-21 16:53:02 -0800446}
Colin Cross8e437c22010-11-28 22:36:08 -0800447
448static int __init tegra_lp0_vec_arg(char *options)
449{
450 char *p = options;
451
452 tegra_lp0_vec_size = memparse(p, &p);
453 if (*p == '@')
454 tegra_lp0_vec_start = memparse(p+1, &p);
Scott Williams03122532011-01-13 14:30:20 -0800455 if (!tegra_lp0_vec_size || !tegra_lp0_vec_start) {
456 tegra_lp0_vec_size = 0;
457 tegra_lp0_vec_start = 0;
458 }
Colin Cross8e437c22010-11-28 22:36:08 -0800459
460 return 0;
461}
462early_param("lp0_vec", tegra_lp0_vec_arg);
463
Colin Cross838d7d62010-10-19 14:45:50 -0700464static int __init tegra_bootloader_fb_arg(char *options)
465{
466 char *p = options;
467
468 tegra_bootloader_fb_size = memparse(p, &p);
469 if (*p == '@')
470 tegra_bootloader_fb_start = memparse(p+1, &p);
471
472 pr_info("Found tegra_fbmem: %08lx@%08lx\n",
473 tegra_bootloader_fb_size, tegra_bootloader_fb_start);
474
475 return 0;
476}
477early_param("tegra_fbmem", tegra_bootloader_fb_arg);
478
Krishna Reddyb7d5a862011-10-05 12:23:37 -0700479static int __init tegra_vpr_arg(char *options)
480{
481 char *p = options;
482
483 tegra_vpr_size = memparse(p, &p);
484 if (*p == '@')
485 tegra_vpr_start = memparse(p+1, &p);
486 pr_info("Found vpr, start=0x%lx size=%lx",
487 tegra_vpr_start, tegra_vpr_size);
Colin Patrick McCabe997f4282011-11-09 13:44:27 -0800488 return 0;
Krishna Reddyb7d5a862011-10-05 12:23:37 -0700489}
490early_param("vpr", tegra_vpr_arg);
491
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530492enum panel_type get_panel_type(void)
493{
494 return board_panel_type;
495}
496static int __init tegra_board_panel_type(char *options)
497{
498 if (!strcmp(options, "lvds"))
499 board_panel_type = panel_type_lvds;
500 else if (!strcmp(options, "dsi"))
501 board_panel_type = panel_type_dsi;
502 else
503 return 0;
504 return 1;
505}
506__setup("panel=", tegra_board_panel_type);
507
Laxman Dewangan8644fc02011-09-04 17:10:13 +0530508enum power_supply_type get_power_supply_type(void)
509{
510 return pow_supply_type;
511}
512static int __init tegra_board_power_supply_type(char *options)
513{
514 if (!strcmp(options, "Adapter"))
515 pow_supply_type = POWER_SUPPLY_TYPE_MAINS;
516 if (!strcmp(options, "Mains"))
517 pow_supply_type = POWER_SUPPLY_TYPE_MAINS;
518 else if (!strcmp(options, "Battery"))
519 pow_supply_type = POWER_SUPPLY_TYPE_BATTERY;
520 else
521 return 0;
522 return 1;
523}
524__setup("power_supply=", tegra_board_power_supply_type);
525
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530526int get_core_edp(void)
527{
528 return pmu_core_edp;
529}
530static int __init tegra_pmu_core_edp(char *options)
531{
532 char *p = options;
Alex Frid3a5fc7c2011-05-11 16:01:44 -0700533 int core_edp = memparse(p, &p);
534 if (core_edp != 0)
535 pmu_core_edp = core_edp;
Deepesh Gujarathi9f73e312011-10-07 15:18:30 +0530536 return 0;
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530537}
Deepesh Gujarathiab7815e2011-09-15 13:57:02 +0530538early_param("core_edp_mv", tegra_pmu_core_edp);
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530539
Laxman Dewangan1f8be3d2011-10-15 15:44:04 +0530540int get_maximum_cpu_current_supported(void)
541{
542 return max_cpu_current;
543}
544static int __init tegra_max_cpu_current(char *options)
545{
546 char *p = options;
547 max_cpu_current = memparse(p, &p);
548 return 1;
549}
550__setup("max_cpu_cur_ma=", tegra_max_cpu_current);
551
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530552static int __init tegra_debug_uartport(char *info)
553{
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530554 char *p = info;
Laxman Dewanganc032ab22011-09-28 14:42:49 +0530555 unsigned long long port_id;
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530556 if (!strncmp(p, "hsport", 6))
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530557 is_tegra_debug_uart_hsport = true;
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530558 else if (!strncmp(p, "lsport", 6))
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530559 is_tegra_debug_uart_hsport = false;
560
Laxman Dewanganc032ab22011-09-28 14:42:49 +0530561 if (p[6] == ',') {
562 if (p[7] == '-') {
563 debug_uart_port_id = -1;
564 } else {
565 port_id = memparse(p + 7, &p);
566 debug_uart_port_id = (int) port_id;
567 }
568 } else {
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530569 debug_uart_port_id = -1;
Laxman Dewanganc032ab22011-09-28 14:42:49 +0530570 }
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530571
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530572 return 1;
573}
574
575bool is_tegra_debug_uartport_hs(void)
576{
577 return is_tegra_debug_uart_hsport;
578}
579
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530580int get_tegra_uart_debug_port_id(void)
581{
582 return debug_uart_port_id;
583}
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530584__setup("debug_uartport=", tegra_debug_uartport);
585
Ashwini Ghuge6bf2a5b2012-03-19 17:21:38 +0530586static int __init tegra_image_type(char *options)
587{
588 if (!strcmp(options, "RCK"))
589 board_image_type = rck_image;
590
591 return 0;
592}
593
594enum image_type get_tegra_image_type(void)
595{
596 return board_image_type;
597}
598
599__setup("image=", tegra_image_type);
600
Laxman Dewangan57b08762011-09-18 16:49:10 +0530601static int __init tegra_audio_codec_type(char *info)
602{
603 char *p = info;
604 if (!strncmp(p, "wm8903", 6))
605 audio_codec_name = audio_codec_wm8903;
606 else
607 audio_codec_name = audio_codec_none;
608
609 return 1;
610}
611
612enum audio_codec_type get_audio_codec_type(void)
613{
614 return audio_codec_name;
615}
616__setup("audio_codec=", tegra_audio_codec_type);
617
618
Nitin Kumbhar637ced42010-12-10 15:16:37 +0530619void tegra_get_board_info(struct board_info *bi)
620{
Laxman Dewanganc0f18022011-02-05 16:26:42 +0530621 bi->board_id = (system_serial_high >> 16) & 0xFFFF;
622 bi->sku = (system_serial_high) & 0xFFFF;
623 bi->fab = (system_serial_low >> 24) & 0xFF;
624 bi->major_revision = (system_serial_low >> 16) & 0xFF;
625 bi->minor_revision = (system_serial_low >> 8) & 0xFF;
Nitin Kumbhar637ced42010-12-10 15:16:37 +0530626}
627
Laxman Dewangan87d07ce2011-06-15 00:48:57 +0530628static int __init tegra_pmu_board_info(char *info)
629{
630 char *p = info;
631 pmu_board_info.board_id = memparse(p, &p);
632 pmu_board_info.sku = memparse(p+1, &p);
633 pmu_board_info.fab = memparse(p+1, &p);
634 pmu_board_info.major_revision = memparse(p+1, &p);
635 pmu_board_info.minor_revision = memparse(p+1, &p);
636 return 1;
637}
638
639void tegra_get_pmu_board_info(struct board_info *bi)
640{
641 memcpy(bi, &pmu_board_info, sizeof(struct board_info));
642}
643
644__setup("pmuboard=", tegra_pmu_board_info);
645
Hyungwoo Yang187ada82011-10-24 15:06:17 -0700646static int __init tegra_display_board_info(char *info)
647{
648 char *p = info;
649 display_board_info.board_id = memparse(p, &p);
650 display_board_info.sku = memparse(p+1, &p);
651 display_board_info.fab = memparse(p+1, &p);
652 display_board_info.major_revision = memparse(p+1, &p);
653 display_board_info.minor_revision = memparse(p+1, &p);
654 return 1;
655}
656
657void tegra_get_display_board_info(struct board_info *bi)
658{
659 memcpy(bi, &display_board_info, sizeof(struct board_info));
660}
661
662__setup("displayboard=", tegra_display_board_info);
663
Jihoon Bangea8fd162011-12-12 11:00:14 -0800664static int __init tegra_camera_board_info(char *info)
665{
666 char *p = info;
667 camera_board_info.board_id = memparse(p, &p);
668 camera_board_info.sku = memparse(p+1, &p);
669 camera_board_info.fab = memparse(p+1, &p);
670 camera_board_info.major_revision = memparse(p+1, &p);
671 camera_board_info.minor_revision = memparse(p+1, &p);
672 return 1;
673}
674
675void tegra_get_camera_board_info(struct board_info *bi)
676{
677 memcpy(bi, &camera_board_info, sizeof(struct board_info));
678}
679
680__setup("cameraboard=", tegra_camera_board_info);
681
Steve Lind2f4e4d2011-07-11 12:45:06 -0700682static int __init tegra_modem_id(char *id)
683{
684 char *p = id;
685
686 modem_id = memparse(p, &p);
687 return 1;
688}
689
690int tegra_get_modem_id(void)
691{
692 return modem_id;
693}
694
695__setup("modem_id=", tegra_modem_id);
Laxman Dewangan87d07ce2011-06-15 00:48:57 +0530696
Jihoon Bangea8fd162011-12-12 11:00:14 -0800697
698
Colin Crossf9c9bde2010-10-19 16:12:33 -0700699/*
700 * Tegra has a protected aperture that prevents access by most non-CPU
701 * memory masters to addresses above the aperture value. Enabling it
702 * secures the CPU's memory from the GPU, except through the GART.
703 */
704void __init tegra_protected_aperture_init(unsigned long aperture)
705{
706#ifndef CONFIG_NVMAP_ALLOW_SYSMEM
707 void __iomem *mc_base = IO_ADDRESS(TEGRA_MC_BASE);
708 pr_info("Enabling Tegra protected aperture at 0x%08lx\n", aperture);
709 writel(aperture, mc_base + MC_SECURITY_CFG2);
710#else
711 pr_err("Tegra protected aperture disabled because nvmap is using "
712 "system memory\n");
713#endif
714}
715
Colin Cross115467a2010-10-19 21:09:29 -0700716/*
717 * Due to conflicting restrictions on the placement of the framebuffer,
718 * the bootloader is likely to leave the framebuffer pointed at a location
719 * in memory that is outside the grhost aperture. This function will move
720 * the framebuffer contents from a physical address that is anywher (lowmem,
721 * highmem, or outside the memory map) to a physical address that is outside
722 * the memory map.
723 */
724void tegra_move_framebuffer(unsigned long to, unsigned long from,
725 unsigned long size)
726{
727 struct page *page;
728 void __iomem *to_io;
729 void *from_virt;
730 unsigned long i;
731
732 BUG_ON(PAGE_ALIGN((unsigned long)to) != (unsigned long)to);
733 BUG_ON(PAGE_ALIGN(from) != from);
734 BUG_ON(PAGE_ALIGN(size) != size);
735
736 to_io = ioremap(to, size);
737 if (!to_io) {
738 pr_err("%s: Failed to map target framebuffer\n", __func__);
739 return;
740 }
741
Colin Cross115467a2010-10-19 21:09:29 -0700742 if (pfn_valid(page_to_pfn(phys_to_page(from)))) {
743 for (i = 0 ; i < size; i += PAGE_SIZE) {
744 page = phys_to_page(from + i);
745 from_virt = kmap(page);
Jon Mayoa8553a42011-08-29 18:09:16 -0700746 memcpy(to_io + i, from_virt, PAGE_SIZE);
Colin Cross115467a2010-10-19 21:09:29 -0700747 kunmap(page);
748 }
749 } else {
750 void __iomem *from_io = ioremap(from, size);
751 if (!from_io) {
752 pr_err("%s: Failed to map source framebuffer\n",
753 __func__);
754 goto out;
755 }
756
Kevin Huangece493d2011-07-05 18:27:43 -0700757 for (i = 0; i < size; i += 4)
Colin Cross115467a2010-10-19 21:09:29 -0700758 writel(readl(from_io + i), to_io + i);
759
760 iounmap(from_io);
761 }
762out:
763 iounmap(to_io);
764}
765
Hiro Sugawara510eb102011-12-13 09:12:26 -0800766#ifdef CONFIG_TEGRA_SMMU_BASE_AT_E0000000
767#define FORCE_SMMU_BASE_FOR_TEGRA3_A01 1
768#else
769#define FORCE_SMMU_BASE_FOR_TEGRA3_A01 0
770#endif
771#if FORCE_SMMU_BASE_FOR_TEGRA3_A01 || \
772 (defined(CONFIG_TEGRA_IOVMM_SMMU) && defined(CONFIG_ARCH_TEGRA_3x_SOC))
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700773/* Support for Tegra3 A01 chip mask that needs to have SMMU IOVA reside in
774 * the upper half of 4GB IOVA space. A02 and after use the bottom 1GB and
775 * do not need to reserve memory.
776 */
Hiro Sugawara510eb102011-12-13 09:12:26 -0800777#define SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700778#endif
779
Colin Cross838d7d62010-10-19 14:45:50 -0700780void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size,
781 unsigned long fb2_size)
782{
Hiro Sugawara510eb102011-12-13 09:12:26 -0800783#ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700784 int smmu_reserved = 0;
Hiro Sugawara10f14812011-09-13 17:20:35 -0700785 struct tegra_smmu_window *smmu_window = tegra_smmu_window(0);
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700786#endif
Colin Cross838d7d62010-10-19 14:45:50 -0700787
Scott Williams03122532011-01-13 14:30:20 -0800788 if (carveout_size) {
789 tegra_carveout_start = memblock_end_of_DRAM() - carveout_size;
790 if (memblock_remove(tegra_carveout_start, carveout_size)) {
791 pr_err("Failed to remove carveout %08lx@%08lx "
792 "from memory map\n",
Hiro Sugawara5cb430a2011-03-10 15:19:03 -0800793 carveout_size, tegra_carveout_start);
Scott Williams03122532011-01-13 14:30:20 -0800794 tegra_carveout_start = 0;
795 tegra_carveout_size = 0;
Kevin Huangece493d2011-07-05 18:27:43 -0700796 } else
Scott Williams03122532011-01-13 14:30:20 -0800797 tegra_carveout_size = carveout_size;
798 }
Colin Cross838d7d62010-10-19 14:45:50 -0700799
Scott Williams03122532011-01-13 14:30:20 -0800800 if (fb2_size) {
801 tegra_fb2_start = memblock_end_of_DRAM() - fb2_size;
802 if (memblock_remove(tegra_fb2_start, fb2_size)) {
Kevin Huangece493d2011-07-05 18:27:43 -0700803 pr_err("Failed to remove second framebuffer "
804 "%08lx@%08lx from memory map\n",
Hiro Sugawaradc1d2812011-04-29 11:59:37 -0700805 fb2_size, tegra_fb2_start);
Scott Williams03122532011-01-13 14:30:20 -0800806 tegra_fb2_start = 0;
807 tegra_fb2_size = 0;
808 } else
809 tegra_fb2_size = fb2_size;
810 }
Colin Cross838d7d62010-10-19 14:45:50 -0700811
Scott Williams03122532011-01-13 14:30:20 -0800812 if (fb_size) {
813 tegra_fb_start = memblock_end_of_DRAM() - fb_size;
814 if (memblock_remove(tegra_fb_start, fb_size)) {
815 pr_err("Failed to remove framebuffer %08lx@%08lx "
816 "from memory map\n",
Hiro Sugawara5cb430a2011-03-10 15:19:03 -0800817 fb_size, tegra_fb_start);
Scott Williams03122532011-01-13 14:30:20 -0800818 tegra_fb_start = 0;
819 tegra_fb_size = 0;
820 } else
821 tegra_fb_size = fb_size;
822 }
Colin Cross838d7d62010-10-19 14:45:50 -0700823
Colin Crossf9c9bde2010-10-19 16:12:33 -0700824 if (tegra_fb_size)
825 tegra_grhost_aperture = tegra_fb_start;
826
827 if (tegra_fb2_size && tegra_fb2_start < tegra_grhost_aperture)
828 tegra_grhost_aperture = tegra_fb2_start;
829
830 if (tegra_carveout_size && tegra_carveout_start < tegra_grhost_aperture)
831 tegra_grhost_aperture = tegra_carveout_start;
832
Hiro Sugawara510eb102011-12-13 09:12:26 -0800833#ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700834 if (!smmu_window) {
Hiro Sugawara10f14812011-09-13 17:20:35 -0700835 pr_err("No SMMU resource\n");
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700836 } else {
Hiro Sugawara0d218182011-04-08 13:21:02 -0700837 size_t smmu_window_size;
838
Hiro Sugawara510eb102011-12-13 09:12:26 -0800839 if (FORCE_SMMU_BASE_FOR_TEGRA3_A01 ||
840 (tegra_get_chipid() == TEGRA_CHIPID_TEGRA3 &&
841 tegra_get_revision() == TEGRA_REVISION_A01)) {
842 smmu_window->start = TEGRA_SMMU_BASE_TEGRA3_A01;
843 smmu_window->end = TEGRA_SMMU_BASE_TEGRA3_A01 +
844 TEGRA_SMMU_SIZE_TEGRA3_A01 - 1;
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700845 }
846 smmu_window_size = smmu_window->end + 1 - smmu_window->start;
847 if (smmu_window->start >= 0x80000000) {
848 if (memblock_reserve(smmu_window->start,
849 smmu_window_size))
850 pr_err(
851 "Failed to reserve SMMU I/O VA window %08lx@%08lx\n",
Hiro Sugawara0d218182011-04-08 13:21:02 -0700852 (unsigned long)smmu_window_size,
853 (unsigned long)smmu_window->start);
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700854 else
855 smmu_reserved = 1;
856 }
Scott Williams599c1122011-02-10 14:35:32 -0800857 }
858#endif
859
Prashant Gaikwadff192312011-08-03 14:49:20 +0530860 if (tegra_lp0_vec_size &&
861 (tegra_lp0_vec_start < memblock_end_of_DRAM())) {
862 if (memblock_reserve(tegra_lp0_vec_start, tegra_lp0_vec_size)) {
863 pr_err("Failed to reserve lp0_vec %08lx@%08lx\n",
864 tegra_lp0_vec_size, tegra_lp0_vec_start);
865 tegra_lp0_vec_start = 0;
866 tegra_lp0_vec_size = 0;
867 }
868 tegra_lp0_vec_relocate = false;
869 } else
870 tegra_lp0_vec_relocate = true;
871
Colin Cross838d7d62010-10-19 14:45:50 -0700872 /*
Kevin Huangece493d2011-07-05 18:27:43 -0700873 * We copy the bootloader's framebuffer to the framebuffer allocated
874 * above, and then free this one.
875 * */
876 if (tegra_bootloader_fb_size) {
877 tegra_bootloader_fb_size = PAGE_ALIGN(tegra_bootloader_fb_size);
Colin Cross838d7d62010-10-19 14:45:50 -0700878 if (memblock_reserve(tegra_bootloader_fb_start,
Scott Williams03122532011-01-13 14:30:20 -0800879 tegra_bootloader_fb_size)) {
Kevin Huangece493d2011-07-05 18:27:43 -0700880 pr_err("Failed to reserve bootloader frame buffer "
881 "%08lx@%08lx\n", tegra_bootloader_fb_size,
882 tegra_bootloader_fb_start);
Scott Williams03122532011-01-13 14:30:20 -0800883 tegra_bootloader_fb_start = 0;
884 tegra_bootloader_fb_size = 0;
885 }
Kevin Huangece493d2011-07-05 18:27:43 -0700886 }
Colin Cross838d7d62010-10-19 14:45:50 -0700887
888 pr_info("Tegra reserved memory:\n"
889 "LP0: %08lx - %08lx\n"
890 "Bootloader framebuffer: %08lx - %08lx\n"
891 "Framebuffer: %08lx - %08lx\n"
Scott Williams22d51692011-01-11 10:50:52 -0800892 "2nd Framebuffer: %08lx - %08lx\n"
Krishna Reddyb7d5a862011-10-05 12:23:37 -0700893 "Carveout: %08lx - %08lx\n"
894 "Vpr: %08lx - %08lx\n",
Colin Cross838d7d62010-10-19 14:45:50 -0700895 tegra_lp0_vec_start,
Scott Williams03122532011-01-13 14:30:20 -0800896 tegra_lp0_vec_size ?
897 tegra_lp0_vec_start + tegra_lp0_vec_size - 1 : 0,
Colin Cross838d7d62010-10-19 14:45:50 -0700898 tegra_bootloader_fb_start,
Scott Williams03122532011-01-13 14:30:20 -0800899 tegra_bootloader_fb_size ?
900 tegra_bootloader_fb_start + tegra_bootloader_fb_size - 1 : 0,
Colin Cross838d7d62010-10-19 14:45:50 -0700901 tegra_fb_start,
Scott Williams03122532011-01-13 14:30:20 -0800902 tegra_fb_size ?
903 tegra_fb_start + tegra_fb_size - 1 : 0,
Colin Cross838d7d62010-10-19 14:45:50 -0700904 tegra_fb2_start,
Scott Williams03122532011-01-13 14:30:20 -0800905 tegra_fb2_size ?
906 tegra_fb2_start + tegra_fb2_size - 1 : 0,
Colin Cross838d7d62010-10-19 14:45:50 -0700907 tegra_carveout_start,
Scott Williams03122532011-01-13 14:30:20 -0800908 tegra_carveout_size ?
Krishna Reddyb7d5a862011-10-05 12:23:37 -0700909 tegra_carveout_start + tegra_carveout_size - 1 : 0,
910 tegra_vpr_start,
911 tegra_vpr_size ?
912 tegra_vpr_start + tegra_vpr_size - 1 : 0);
Scott Williams599c1122011-02-10 14:35:32 -0800913
Hiro Sugawara510eb102011-12-13 09:12:26 -0800914#ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700915 if (smmu_reserved)
Hiro Sugawara10f14812011-09-13 17:20:35 -0700916 pr_info("SMMU: %08lx - %08lx\n",
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700917 smmu_window->start, smmu_window->end);
Scott Williams599c1122011-02-10 14:35:32 -0800918#endif
Colin Cross838d7d62010-10-19 14:45:50 -0700919}
Kevin Huangece493d2011-07-05 18:27:43 -0700920
Haley Teng290e96f2011-09-27 12:20:32 +0800921static struct resource ram_console_resources[] = {
922 {
923 .flags = IORESOURCE_MEM,
924 },
925};
926
927static struct platform_device ram_console_device = {
928 .name = "ram_console",
929 .id = -1,
930 .num_resources = ARRAY_SIZE(ram_console_resources),
931 .resource = ram_console_resources,
932};
933
934void __init tegra_ram_console_debug_reserve(unsigned long ram_console_size)
935{
936 struct resource *res;
937 long ret;
938
939 res = platform_get_resource(&ram_console_device, IORESOURCE_MEM, 0);
940 if (!res)
941 goto fail;
942 res->start = memblock_end_of_DRAM() - ram_console_size;
943 res->end = res->start + ram_console_size - 1;
944 ret = memblock_remove(res->start, ram_console_size);
945 if (ret)
946 goto fail;
947
948 return;
949
950fail:
951 ram_console_device.resource = NULL;
952 ram_console_device.num_resources = 0;
953 pr_err("Failed to reserve memory block for ram console\n");
954}
955
956void __init tegra_ram_console_debug_init(void)
957{
958 int err;
959
960 err = platform_device_register(&ram_console_device);
961 if (err) {
962 pr_err("%s: ram console registration failed (%d)!\n", __func__, err);
963 }
964}
965
Kevin Huangece493d2011-07-05 18:27:43 -0700966void __init tegra_release_bootloader_fb(void)
967{
968 /* Since bootloader fb is reserved in common.c, it is freed here. */
969 if (tegra_bootloader_fb_size)
970 if (memblock_free(tegra_bootloader_fb_start,
971 tegra_bootloader_fb_size))
972 pr_err("Failed to free bootloader fb.\n");
973}
Victor(Weiguo) Pan5ab70782011-08-23 14:48:30 -0700974
Bharat Nihalani50e7bec2011-05-19 20:09:14 +0530975#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
Wen Yifd9bfde2011-04-18 14:21:25 -0700976static char cpufreq_gov_default[32];
977static char *cpufreq_gov_conservative = "conservative";
978static char *cpufreq_sysfs_place_holder="/sys/devices/system/cpu/cpu%i/cpufreq/scaling_governor";
Wen Yi10027352011-06-06 13:51:12 -0700979static char *cpufreq_gov_conservative_param="/sys/devices/system/cpu/cpufreq/conservative/%s";
Wen Yifd9bfde2011-04-18 14:21:25 -0700980
981static void cpufreq_set_governor(char *governor)
982{
983 struct file *scaling_gov = NULL;
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -0700984 mm_segment_t old_fs;
Wen Yifd9bfde2011-04-18 14:21:25 -0700985 char buf[128];
Diwakar Tundlam47719fe2012-01-30 15:53:05 -0800986 int i = 0;
Wen Yifd9bfde2011-04-18 14:21:25 -0700987 loff_t offset = 0;
988
989 if (governor == NULL)
990 return;
991
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -0700992 /* change to KERNEL_DS address limit */
993 old_fs = get_fs();
994 set_fs(KERNEL_DS);
Prashant Gaikwad8d1e39c2011-12-26 16:41:29 +0530995#ifndef CONFIG_TEGRA_AUTO_HOTPLUG
Sang-Hun Lee00535522011-12-22 11:06:29 -0800996 for_each_online_cpu(i)
997#endif
998 {
Wen Yifd9bfde2011-04-18 14:21:25 -0700999 sprintf(buf, cpufreq_sysfs_place_holder, i);
1000 scaling_gov = filp_open(buf, O_RDWR, 0);
Wen Yi50582972012-01-06 16:29:00 -08001001 if (scaling_gov != NULL) {
Wen Yifd9bfde2011-04-18 14:21:25 -07001002 if (scaling_gov->f_op != NULL &&
1003 scaling_gov->f_op->write != NULL)
1004 scaling_gov->f_op->write(scaling_gov,
1005 governor,
1006 strlen(governor),
1007 &offset);
1008 else
1009 pr_err("f_op might be null\n");
1010
1011 filp_close(scaling_gov, NULL);
Wen Yi50582972012-01-06 16:29:00 -08001012 } else {
1013 pr_err("%s. Can't open %s\n", __func__, buf);
Wen Yifd9bfde2011-04-18 14:21:25 -07001014 }
1015 }
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001016 set_fs(old_fs);
Wen Yifd9bfde2011-04-18 14:21:25 -07001017}
1018
1019void cpufreq_save_default_governor(void)
1020{
1021 struct file *scaling_gov = NULL;
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001022 mm_segment_t old_fs;
Wen Yifd9bfde2011-04-18 14:21:25 -07001023 char buf[128];
1024 loff_t offset = 0;
1025
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001026 /* change to KERNEL_DS address limit */
1027 old_fs = get_fs();
1028 set_fs(KERNEL_DS);
1029
Wen Yifd9bfde2011-04-18 14:21:25 -07001030 buf[127] = 0;
1031 sprintf(buf, cpufreq_sysfs_place_holder,0);
1032 scaling_gov = filp_open(buf, O_RDONLY, 0);
Wen Yi50582972012-01-06 16:29:00 -08001033 if (scaling_gov != NULL) {
Wen Yifd9bfde2011-04-18 14:21:25 -07001034 if (scaling_gov->f_op != NULL &&
1035 scaling_gov->f_op->read != NULL)
1036 scaling_gov->f_op->read(scaling_gov,
1037 cpufreq_gov_default,
Wen Yi10027352011-06-06 13:51:12 -07001038 32,
Wen Yifd9bfde2011-04-18 14:21:25 -07001039 &offset);
1040 else
1041 pr_err("f_op might be null\n");
1042
1043 filp_close(scaling_gov, NULL);
Wen Yi50582972012-01-06 16:29:00 -08001044 } else {
1045 pr_err("%s. Can't open %s\n", __func__, buf);
Wen Yifd9bfde2011-04-18 14:21:25 -07001046 }
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001047 set_fs(old_fs);
Wen Yifd9bfde2011-04-18 14:21:25 -07001048}
1049
1050void cpufreq_restore_default_governor(void)
1051{
1052 cpufreq_set_governor(cpufreq_gov_default);
1053}
1054
Wen Yi50582972012-01-06 16:29:00 -08001055void cpufreq_set_conservative_governor_param(char *name, int value)
Wen Yi10027352011-06-06 13:51:12 -07001056{
1057 struct file *gov_param = NULL;
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001058 mm_segment_t old_fs;
Wen Yi50582972012-01-06 16:29:00 -08001059 static char buf[128], param_value[8];
1060 loff_t offset = 0;
Wen Yi10027352011-06-06 13:51:12 -07001061
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001062 /* change to KERNEL_DS address limit */
1063 old_fs = get_fs();
1064 set_fs(KERNEL_DS);
1065
Wen Yi50582972012-01-06 16:29:00 -08001066 sprintf(param_value, "%d", value);
1067 sprintf(buf, cpufreq_gov_conservative_param, name);
1068 gov_param = filp_open(buf, O_RDWR, 0);
1069 if (gov_param != NULL) {
Wen Yi10027352011-06-06 13:51:12 -07001070 if (gov_param->f_op != NULL &&
1071 gov_param->f_op->write != NULL)
1072 gov_param->f_op->write(gov_param,
Wen Yi50582972012-01-06 16:29:00 -08001073 param_value,
1074 strlen(param_value),
Wen Yi10027352011-06-06 13:51:12 -07001075 &offset);
1076 else
1077 pr_err("f_op might be null\n");
1078
1079 filp_close(gov_param, NULL);
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001080 } else {
Wen Yi50582972012-01-06 16:29:00 -08001081 pr_err("%s. Can't open %s\n", __func__, buf);
Wen Yi10027352011-06-06 13:51:12 -07001082 }
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001083 set_fs(old_fs);
Wen Yi10027352011-06-06 13:51:12 -07001084}
1085
Wen Yifd9bfde2011-04-18 14:21:25 -07001086void cpufreq_set_conservative_governor(void)
1087{
1088 cpufreq_set_governor(cpufreq_gov_conservative);
1089}
Bharat Nihalani50e7bec2011-05-19 20:09:14 +05301090#endif /* CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND */