blob: d91ad83fd6a5bb98753748406aed49d586065f2f [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
singhome_lee95e843a2012-05-02 22:30:37 +080050#define PMC_SCRATCH37 0x130
51
Scott Williams816ab052010-12-07 11:19:20 -080052#define MC_SECURITY_CFG2 0x7c
Colin Crossf9c9bde2010-10-19 16:12:33 -070053
Rakesh Bodla1ad210a2011-05-31 15:18:00 +053054#define AHB_ARBITRATION_PRIORITY_CTRL 0x4
55#define AHB_PRIORITY_WEIGHT(x) (((x) & 0x7) << 29)
56#define PRIORITY_SELECT_USB BIT(6)
57#define PRIORITY_SELECT_USB2 BIT(18)
58#define PRIORITY_SELECT_USB3 BIT(17)
59
60#define AHB_GIZMO_AHB_MEM 0xc
61#define ENB_FAST_REARBITRATE BIT(2)
Jay Chengce4a7df2011-06-09 17:34:35 -040062#define DONT_SPLIT_AHB_WR BIT(7)
Rakesh Bodla1ad210a2011-05-31 15:18:00 +053063
Gaurav Sarode7e782c02012-02-27 21:54:30 +053064#define RECOVERY_MODE BIT(31)
65#define BOOTLOADER_MODE BIT(30)
Gaurav Sarodec2723e92012-03-02 18:30:19 +053066#define FORCED_RECOVERY_MODE BIT(1)
singhome_lee95e843a2012-05-02 22:30:37 +080067#define GO_TO_CHARGER_MODE (0xA5A55A5A)
Gaurav Sarode7e782c02012-02-27 21:54:30 +053068
Rakesh Bodla1ad210a2011-05-31 15:18:00 +053069#define AHB_GIZMO_USB 0x1c
70#define AHB_GIZMO_USB2 0x78
71#define AHB_GIZMO_USB3 0x7c
72#define IMMEDIATE BIT(18)
73
74#define AHB_MEM_PREFETCH_CFG3 0xe0
75#define AHB_MEM_PREFETCH_CFG4 0xe4
76#define AHB_MEM_PREFETCH_CFG1 0xec
77#define AHB_MEM_PREFETCH_CFG2 0xf0
78#define PREFETCH_ENB BIT(31)
79#define MST_ID(x) (((x) & 0x1f) << 26)
80#define AHBDMA_MST_ID MST_ID(5)
81#define USB_MST_ID MST_ID(6)
82#define USB2_MST_ID MST_ID(18)
83#define USB3_MST_ID MST_ID(17)
84#define ADDR_BNDRY(x) (((x) & 0xf) << 21)
85#define INACTIVITY_TIMEOUT(x) (((x) & 0xffff) << 0)
86
Colin Cross838d7d62010-10-19 14:45:50 -070087unsigned long tegra_bootloader_fb_start;
88unsigned long tegra_bootloader_fb_size;
89unsigned long tegra_fb_start;
90unsigned long tegra_fb_size;
91unsigned long tegra_fb2_start;
92unsigned long tegra_fb2_size;
93unsigned long tegra_carveout_start;
94unsigned long tegra_carveout_size;
Krishna Reddyb7d5a862011-10-05 12:23:37 -070095unsigned long tegra_vpr_start;
96unsigned long tegra_vpr_size;
Colin Cross8e437c22010-11-28 22:36:08 -080097unsigned long tegra_lp0_vec_start;
98unsigned long tegra_lp0_vec_size;
Prashant Gaikwadff192312011-08-03 14:49:20 +053099bool tegra_lp0_vec_relocate;
Scott Williams03122532011-01-13 14:30:20 -0800100unsigned long tegra_grhost_aperture = ~0ul;
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530101static bool is_tegra_debug_uart_hsport;
Laxman Dewangan87d07ce2011-06-15 00:48:57 +0530102static struct board_info pmu_board_info;
Hyungwoo Yang187ada82011-10-24 15:06:17 -0700103static struct board_info display_board_info;
Jihoon Bangea8fd162011-12-12 11:00:14 -0800104static struct board_info camera_board_info;
Colin Crossd8611962010-01-28 16:40:29 -0800105
Alex Frid3a5fc7c2011-05-11 16:01:44 -0700106static int pmu_core_edp = 1200; /* default 1.2V EDP limit */
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530107static int board_panel_type;
Laxman Dewangan8644fc02011-09-04 17:10:13 +0530108static enum power_supply_type pow_supply_type = POWER_SUPPLY_TYPE_MAINS;
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530109
Colin Cross699fe142010-08-23 18:37:25 -0700110void (*arch_reset)(char mode, const char *cmd) = tegra_assert_system_reset;
111
Scott Williamsae811c32011-02-10 15:45:06 -0800112#define NEVER_RESET 0
Scott Williams9bc40532011-01-28 03:26:28 -0800113
Colin Cross699fe142010-08-23 18:37:25 -0700114void tegra_assert_system_reset(char mode, const char *cmd)
115{
Scott Williams9bc40532011-01-28 03:26:28 -0800116#if defined(CONFIG_TEGRA_FPGA_PLATFORM) || NEVER_RESET
Scott Williamsae811c32011-02-10 15:45:06 -0800117 printk("tegra_assert_system_reset() ignored.....");
Scott Williams9bc40532011-01-28 03:26:28 -0800118 do { } while (1);
119#else
Deepesh Gujarathi43921782010-12-07 14:09:22 +0530120 void __iomem *reset = IO_ADDRESS(TEGRA_PMC_BASE + 0x00);
Colin Cross699fe142010-08-23 18:37:25 -0700121 u32 reg;
122
Gaurav Sarode7e782c02012-02-27 21:54:30 +0530123 reg = readl_relaxed(reset + PMC_SCRATCH0);
Gaurav Sarodec2723e92012-03-02 18:30:19 +0530124 /* Writing recovery kernel or Bootloader mode in SCRATCH0 31:30:1 */
Gaurav Sarode7e782c02012-02-27 21:54:30 +0530125 if (cmd) {
126 if (!strcmp(cmd, "recovery"))
127 reg |= RECOVERY_MODE;
128 else if (!strcmp(cmd, "bootloader"))
129 reg |= BOOTLOADER_MODE;
Gaurav Sarodec2723e92012-03-02 18:30:19 +0530130 else if (!strcmp(cmd, "forced-recovery"))
131 reg |= FORCED_RECOVERY_MODE;
132 else
133 reg &= ~(BOOTLOADER_MODE | RECOVERY_MODE | FORCED_RECOVERY_MODE);
Gaurav Sarode7e782c02012-02-27 21:54:30 +0530134 }
135 else {
Gaurav Sarodec2723e92012-03-02 18:30:19 +0530136 /* Clearing SCRATCH0 31:30:1 on default reboot */
137 reg &= ~(BOOTLOADER_MODE | RECOVERY_MODE | FORCED_RECOVERY_MODE);
Gaurav Sarode7e782c02012-02-27 21:54:30 +0530138 }
139 writel_relaxed(reg, reset + PMC_SCRATCH0);
singhome_lee95e843a2012-05-02 22:30:37 +0800140
141 if (cmd && !strcmp(cmd, "chrager-mode"))
142 {
143 reg = readl_relaxed(reset + PMC_SCRATCH37);
144 reg = GO_TO_CHARGER_MODE;
145 writel_relaxed(GO_TO_CHARGER_MODE, reset + PMC_SCRATCH37);
146 //printk("tegra_assert_system_reset reg =%x",reg );
147 }
148
Simon Glass375b19c2011-02-17 08:13:57 -0800149 /* use *_related to avoid spinlock since caches are off */
150 reg = readl_relaxed(reset);
Deepesh Gujarathi43921782010-12-07 14:09:22 +0530151 reg |= 0x10;
Simon Glass375b19c2011-02-17 08:13:57 -0800152 writel_relaxed(reg, reset);
Scott Williams4ad5ff12011-01-07 20:43:13 -0800153#endif
Colin Cross699fe142010-08-23 18:37:25 -0700154}
Steve Lind2f4e4d2011-07-11 12:45:06 -0700155static int modem_id;
Ray Poudrierb2278732011-12-08 17:38:25 -0800156static int sku_override;
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530157static int debug_uart_port_id;
Laxman Dewangan57b08762011-09-18 16:49:10 +0530158static enum audio_codec_type audio_codec_name;
Ashwini Ghuge6bf2a5b2012-03-19 17:21:38 +0530159static enum image_type board_image_type = system_image;
Laxman Dewangan1f8be3d2011-10-15 15:44:04 +0530160static int max_cpu_current;
Colin Cross699fe142010-08-23 18:37:25 -0700161
Laxman Dewangan844407d2011-04-27 19:11:08 +0530162/* WARNING: There is implicit client of pllp_out3 like i2c, uart, dsi
163 * and so this clock (pllp_out3) should never be disabled.
164 */
Colin Crossd8611962010-01-28 16:40:29 -0800165static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
166 /* name parent rate enabled */
167 { "clk_m", NULL, 0, true },
Yudong Tanf8cd6292011-07-01 11:26:17 -0700168#ifdef CONFIG_TEGRA_SILICON_PLATFORM
Alex Fridc86c2252011-05-28 00:21:30 -0700169#ifdef CONFIG_ARCH_TEGRA_2x_SOC
Scott Williams816ab052010-12-07 11:19:20 -0800170 { "pll_p", NULL, 216000000, true },
Colin Crossd8611962010-01-28 16:40:29 -0800171 { "pll_p_out1", "pll_p", 28800000, true },
Prashant Gaikwad1529b8e2012-01-23 12:43:28 +0530172 { "pll_p_out2", "pll_p", 48000000, false },
Colin Crossd8611962010-01-28 16:40:29 -0800173 { "pll_p_out3", "pll_p", 72000000, true },
Prashant Gaikwad1529b8e2012-01-23 12:43:28 +0530174 { "pll_p_out4", "pll_p", 108000000, false },
Prashant Gaikwad9a975332011-11-01 18:16:47 +0530175 { "pll_m", "clk_m", 0, true },
Pritesh Raithathabb1d62b2011-11-11 16:52:11 +0530176 { "pll_m_out1", "pll_m", 120000000, true },
Prashant Gaikwad9a975332011-11-01 18:16:47 +0530177 { "sclk", "pll_c_out1", 40000000, true },
Scott Williams07fc3312011-05-23 22:08:42 -0700178 { "hclk", "sclk", 40000000, true },
179 { "pclk", "hclk", 40000000, true },
Prashant Gaikwad9a975332011-11-01 18:16:47 +0530180 { "mpe", "pll_c", 0, false },
181 { "epp", "pll_c", 0, false },
182 { "vi_sensor", "pll_c", 0, false },
183 { "vi", "pll_c", 0, false },
184 { "2d", "pll_c", 0, false },
185 { "3d", "pll_c", 0, false },
Scott Williams07fc3312011-05-23 22:08:42 -0700186#else
Alex Fride818b6e2012-01-12 20:27:55 -0800187 { "pll_p", NULL, 0, true },
188 { "pll_p_out1", "pll_p", 0, false },
ScottPetersonfde0dd42011-12-28 13:40:20 -0800189 { "pll_p_out2", "pll_p", 48000000, false },
Alex Fride818b6e2012-01-12 20:27:55 -0800190 { "pll_p_out3", "pll_p", 0, true },
Alex Frid58af6ba2011-10-24 18:51:32 -0700191 { "pll_m_out1", "pll_m", 275000000, false },
Peter Zu590fd1f2012-02-05 22:10:42 -0800192 { "pll_p_out4", "pll_p", 102000000, true },
Alex Fridc86c2252011-05-28 00:21:30 -0700193 { "sclk", "pll_p_out4", 102000000, true },
194 { "hclk", "sclk", 102000000, true },
195 { "pclk", "hclk", 51000000, true },
Amit Kamath3b693812012-04-02 17:22:57 +0530196 { "wake.sclk", NULL, 40000000, true },
Laxman Dewangance8ac372012-03-12 23:03:55 +0530197 { "sbc5.sclk", NULL, 40000000, false},
198 { "sbc6.sclk", NULL, 40000000, false},
Alex Frid8b5ce662011-01-31 10:07:57 -0800199#endif
Laxman Dewangance8ac372012-03-12 23:03:55 +0530200 { "sbc1.sclk", NULL, 40000000, false},
201 { "sbc2.sclk", NULL, 40000000, false},
202 { "sbc3.sclk", NULL, 40000000, false},
203 { "sbc4.sclk", NULL, 40000000, false},
Scott Williams0aac1552011-06-10 12:58:11 -0700204#else
205 { "pll_p", NULL, 216000000, true },
ScottPetersonfde0dd42011-12-28 13:40:20 -0800206 { "pll_p_out1", "pll_p", 28800000, false },
207 { "pll_p_out2", "pll_p", 48000000, false },
Scott Williams0aac1552011-06-10 12:58:11 -0700208 { "pll_p_out3", "pll_p", 72000000, true },
209 { "pll_m_out1", "pll_m", 275000000, true },
ScottPetersonfde0dd42011-12-28 13:40:20 -0800210 { "pll_p_out4", "pll_p", 108000000, false },
Scott Williams0aac1552011-06-10 12:58:11 -0700211 { "sclk", "pll_p_out4", 108000000, true },
212 { "hclk", "sclk", 108000000, true },
213 { "pclk", "hclk", 54000000, true },
Alex Frid29138fe2012-04-01 00:28:46 -0700214 { "pll_c", NULL, ULONG_MAX, false },
215 { "pll_c_out1", "pll_c", 208000000, false },
Scott Williams0aac1552011-06-10 12:58:11 -0700216#endif
ScottPetersonf8b15a82012-01-19 11:27:07 -0800217#ifdef CONFIG_TEGRA_SLOW_CSITE
218 { "csite", "clk_m", 1000000, true },
219#else
220 { "csite", NULL, 0, true },
221#endif
Colin Crosscd51d0e2011-02-21 17:05:36 -0800222 { "emc", NULL, 0, true },
223 { "cpu", NULL, 0, true },
Alex Fridd3b4e362011-05-26 22:58:21 -0700224 { "kfuse", NULL, 0, true },
Varun Wadekar0e0ccdb2011-06-25 16:42:37 +0530225 { "fuse", NULL, 0, true },
Scott Williams816ab052010-12-07 11:19:20 -0800226 { "pll_u", NULL, 480000000, false },
Alex Fridc86c2252011-05-28 00:21:30 -0700227 { "sdmmc1", "pll_p", 48000000, false},
Pavan Kunapuli0a420462011-03-16 19:29:42 +0530228 { "sdmmc3", "pll_p", 48000000, false},
Pavan Kunapuli4a743e72011-11-08 18:02:52 +0530229 { "sdmmc4", "pll_p", 48000000, false},
ScottPetersonc9a567732012-01-17 16:37:09 -0800230 { "pll_a", "pll_p_out1", 0, false},
231 { "pll_a_out0", "pll_a", 0, false},
Scott Williams07fc3312011-05-23 22:08:42 -0700232#ifndef CONFIG_ARCH_TEGRA_2x_SOC
Alex Frid5be85392011-06-28 20:50:29 -0700233 { "cbus", "pll_c", 416000000, false },
Alex Frid7359d832011-05-13 23:58:33 -0700234 { "pll_c_out1", "pll_c", 208000000, false },
Alex Frid67982942012-01-19 22:05:45 -0800235 { "mselect", "pll_p", 102000000, true },
Alex Frid7f970e72011-02-04 12:04:14 -0800236#endif
Colin Crossd8611962010-01-28 16:40:29 -0800237 { NULL, NULL, 0, 0},
238};
Erik Gillingc5f80062010-01-21 16:53:02 -0800239
Scott Williams70d70472012-02-02 18:55:00 -0800240#ifdef CONFIG_CACHE_L2X0
241#ifdef CONFIG_TRUSTED_FOUNDATIONS
Chris Johnson644d1fb2011-11-18 16:14:07 -0800242static void tegra_cache_smc(bool enable, u32 arg)
243{
244 void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
245 bool need_affinity_switch;
246 bool can_switch_affinity;
247 bool l2x0_enabled;
248 cpumask_t local_cpu_mask;
249 cpumask_t saved_cpu_mask;
250 unsigned long flags;
251 long ret;
252
253 /*
254 * ISSUE : Some registers of PL310 controler must be written
255 * from Secure context (and from CPU0)!
256 *
257 * When called form Normal we obtain an abort or do nothing.
258 * Instructions that must be called in Secure:
259 * - Write to Control register (L2X0_CTRL==0x100)
260 * - Write in Auxiliary controler (L2X0_AUX_CTRL==0x104)
261 * - Invalidate all entries (L2X0_INV_WAY==0x77C),
262 * mandatory at boot time.
263 * - Tag and Data RAM Latency Control Registers
264 * (0x108 & 0x10C) must be written in Secure.
265 */
266 need_affinity_switch = (smp_processor_id() != 0);
267 can_switch_affinity = !irqs_disabled();
268
269 WARN_ON(need_affinity_switch && !can_switch_affinity);
270 if (need_affinity_switch && can_switch_affinity) {
271 cpu_set(0, local_cpu_mask);
272 sched_getaffinity(0, &saved_cpu_mask);
273 ret = sched_setaffinity(0, &local_cpu_mask);
274 WARN_ON(ret != 0);
275 }
276
277 local_irq_save(flags);
278 l2x0_enabled = readl_relaxed(p + L2X0_CTRL) & 1;
279 if (enable && !l2x0_enabled)
280 tegra_generic_smc(0xFFFFF100, 0x00000001, arg);
281 else if (!enable && l2x0_enabled)
282 tegra_generic_smc(0xFFFFF100, 0x00000002, arg);
283 local_irq_restore(flags);
284
285 if (need_affinity_switch && can_switch_affinity) {
286 ret = sched_setaffinity(0, &saved_cpu_mask);
287 WARN_ON(ret != 0);
288 }
289}
290
291static void tegra_l2x0_disable(void)
292{
293 unsigned long flags;
294 static u32 l2x0_way_mask;
295
296 if (!l2x0_way_mask) {
297 void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
298 u32 aux_ctrl;
299 u32 ways;
300
301 aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
302 ways = (aux_ctrl & (1 << 16)) ? 16 : 8;
303 l2x0_way_mask = (1 << ways) - 1;
304 }
305
306 local_irq_save(flags);
307 tegra_cache_smc(false, l2x0_way_mask);
308 local_irq_restore(flags);
309}
Scott Williams70d70472012-02-02 18:55:00 -0800310#endif /* CONFIG_TRUSTED_FOUNDATIONS */
Chris Johnson644d1fb2011-11-18 16:14:07 -0800311
Krishna Reddy1212eb82011-12-01 15:32:36 -0800312void tegra_init_cache(bool init)
Erik Gillingc5f80062010-01-21 16:53:02 -0800313{
Erik Gillingc5f80062010-01-21 16:53:02 -0800314 void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
Scott Williams191914c2010-12-27 19:03:57 -0800315 u32 aux_ctrl;
Diwakar Tundlamf4ca2962011-12-02 15:49:42 -0800316 u32 speedo;
Krishna Reddy58eb2d02011-12-05 12:57:07 -0800317 u32 tmp;
Erik Gillingc5f80062010-01-21 16:53:02 -0800318
Chris Johnson644d1fb2011-11-18 16:14:07 -0800319#ifdef CONFIG_TRUSTED_FOUNDATIONS
320 /* issue the SMC to enable the L2 */
321 aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
322 tegra_cache_smc(true, aux_ctrl);
323
324 /* after init, reread aux_ctrl and register handlers */
325 aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
326 l2x0_init(p, aux_ctrl, 0xFFFFFFFF);
327
328 /* override outer_disable() with our disable */
329 outer_cache.disable = tegra_l2x0_disable;
330#else
Scott Williams816ab052010-12-07 11:19:20 -0800331#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
Colin Cross535371c2011-01-22 00:36:14 -0800332 writel_relaxed(0x331, p + L2X0_TAG_LATENCY_CTRL);
333 writel_relaxed(0x441, p + L2X0_DATA_LATENCY_CTRL);
Erik Gillingc5f80062010-01-21 16:53:02 -0800334
Scott Williams816ab052010-12-07 11:19:20 -0800335#elif defined(CONFIG_ARCH_TEGRA_3x_SOC)
Yudong Tanf8cd6292011-07-01 11:26:17 -0700336#ifdef CONFIG_TEGRA_SILICON_PLATFORM
Scott Williams1245c8e2011-01-05 17:53:39 -0800337 /* PL310 RAM latency is CPU dependent. NOTE: Changes here
338 must also be reflected in __cortex_a9_l2x0_restart */
339
340 if (is_lp_cluster()) {
341 writel(0x221, p + L2X0_TAG_LATENCY_CTRL);
342 writel(0x221, p + L2X0_DATA_LATENCY_CTRL);
343 } else {
Diwakar Tundlamf4ca2962011-12-02 15:49:42 -0800344 /* relax l2-cache latency for speedos 4,5,6 (T33's chips) */
345 speedo = tegra_cpu_speedo_id();
Alex Fridd83fa392012-01-23 13:40:48 -0800346 if (speedo == 4 || speedo == 5 || speedo == 6 ||
347 speedo == 12 || speedo == 13) {
Diwakar Tundlamf4ca2962011-12-02 15:49:42 -0800348 writel(0x442, p + L2X0_TAG_LATENCY_CTRL);
349 writel(0x552, p + L2X0_DATA_LATENCY_CTRL);
350 } else {
351 writel(0x441, p + L2X0_TAG_LATENCY_CTRL);
352 writel(0x551, p + L2X0_DATA_LATENCY_CTRL);
353 }
Scott Williams1245c8e2011-01-05 17:53:39 -0800354 }
Yudong Tanf8cd6292011-07-01 11:26:17 -0700355#else
356 writel(0x770, p + L2X0_TAG_LATENCY_CTRL);
357 writel(0x770, p + L2X0_DATA_LATENCY_CTRL);
Scott Williams816ab052010-12-07 11:19:20 -0800358#endif
Scott Williams816ab052010-12-07 11:19:20 -0800359#endif
Krishna Reddy58eb2d02011-12-05 12:57:07 -0800360 aux_ctrl = readl(p + L2X0_CACHE_TYPE);
361 aux_ctrl = (aux_ctrl & 0x700) << (17-8);
362 aux_ctrl |= 0x7C000001;
Krishna Reddy1212eb82011-12-01 15:32:36 -0800363 if (init) {
Krishna Reddy1212eb82011-12-01 15:32:36 -0800364 l2x0_init(p, aux_ctrl, 0x8200c3fe);
Krishna Reddy58eb2d02011-12-05 12:57:07 -0800365 } else {
366 tmp = aux_ctrl;
367 aux_ctrl = readl(p + L2X0_AUX_CTRL);
368 aux_ctrl &= 0x8200c3fe;
369 aux_ctrl |= tmp;
370 writel(aux_ctrl, p + L2X0_AUX_CTRL);
Krishna Reddy1212eb82011-12-01 15:32:36 -0800371 }
Chris Johnson644d1fb2011-11-18 16:14:07 -0800372 l2x0_enable();
373#endif
Erik Gillingc5f80062010-01-21 16:53:02 -0800374}
Scott Williams70d70472012-02-02 18:55:00 -0800375#endif
Erik Gillingc5f80062010-01-21 16:53:02 -0800376
Dima Zavin7db7cbc2010-09-16 17:58:05 -0700377static void __init tegra_init_power(void)
378{
Scott Williams1a536c32011-09-01 16:20:47 -0700379#ifdef CONFIG_ARCH_TEGRA_HAS_SATA
Karan Jhavar49adefb2011-06-09 14:50:35 -0700380 tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_SATA);
Karan Jhavar93962282011-05-16 17:00:43 -0700381#endif
Scott Williams1a536c32011-09-01 16:20:47 -0700382#ifdef CONFIG_ARCH_TEGRA_HAS_PCIE
Karan Jhavar93962282011-05-16 17:00:43 -0700383 tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_PCIE);
Scott Williams1a536c32011-09-01 16:20:47 -0700384#endif
Dima Zavin7db7cbc2010-09-16 17:58:05 -0700385}
386
Rakesh Bodla1ad210a2011-05-31 15:18:00 +0530387static inline unsigned long gizmo_readl(unsigned long offset)
388{
389 return readl(IO_TO_VIRT(TEGRA_AHB_GIZMO_BASE + offset));
390}
391
392static inline void gizmo_writel(unsigned long value, unsigned long offset)
393{
394 writel(value, IO_TO_VIRT(TEGRA_AHB_GIZMO_BASE + offset));
395}
396
397static void __init tegra_init_ahb_gizmo_settings(void)
398{
399 unsigned long val;
400
401 val = gizmo_readl(AHB_GIZMO_AHB_MEM);
Jay Chengce4a7df2011-06-09 17:34:35 -0400402 val |= ENB_FAST_REARBITRATE | IMMEDIATE | DONT_SPLIT_AHB_WR;
Rakesh Bodla1ad210a2011-05-31 15:18:00 +0530403 gizmo_writel(val, AHB_GIZMO_AHB_MEM);
404
405 val = gizmo_readl(AHB_GIZMO_USB);
406 val |= IMMEDIATE;
407 gizmo_writel(val, AHB_GIZMO_USB);
408
409 val = gizmo_readl(AHB_GIZMO_USB2);
410 val |= IMMEDIATE;
411 gizmo_writel(val, AHB_GIZMO_USB2);
412
413 val = gizmo_readl(AHB_GIZMO_USB3);
414 val |= IMMEDIATE;
415 gizmo_writel(val, AHB_GIZMO_USB3);
416
417 val = gizmo_readl(AHB_ARBITRATION_PRIORITY_CTRL);
418 val |= PRIORITY_SELECT_USB | PRIORITY_SELECT_USB2 | PRIORITY_SELECT_USB3
419 | AHB_PRIORITY_WEIGHT(7);
420 gizmo_writel(val, AHB_ARBITRATION_PRIORITY_CTRL);
421
422 val = gizmo_readl(AHB_MEM_PREFETCH_CFG1);
423 val &= ~MST_ID(~0);
424 val |= PREFETCH_ENB | AHBDMA_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
425 gizmo_writel(val, AHB_MEM_PREFETCH_CFG1);
426
427 val = gizmo_readl(AHB_MEM_PREFETCH_CFG2);
428 val &= ~MST_ID(~0);
429 val |= PREFETCH_ENB | USB_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
430 gizmo_writel(val, AHB_MEM_PREFETCH_CFG2);
431
432 val = gizmo_readl(AHB_MEM_PREFETCH_CFG3);
433 val &= ~MST_ID(~0);
434 val |= PREFETCH_ENB | USB3_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
435 gizmo_writel(val, AHB_MEM_PREFETCH_CFG3);
436
437 val = gizmo_readl(AHB_MEM_PREFETCH_CFG4);
438 val &= ~MST_ID(~0);
439 val |= PREFETCH_ENB | USB2_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
440 gizmo_writel(val, AHB_MEM_PREFETCH_CFG4);
441}
442
Colin Cross0cf62302011-02-21 17:10:14 -0800443void __init tegra_init_early(void)
Erik Gillingc5f80062010-01-21 16:53:02 -0800444{
Scott Williams55f67602011-07-27 20:10:06 -0700445#ifndef CONFIG_SMP
446 /* For SMP system, initializing the reset handler here is too
447 late. For non-SMP systems, the function that calls the reset
448 handler initializer is not called, so do it here for non-SMP. */
449 tegra_cpu_reset_handler_init();
450#endif
Colin Cross73625e32010-06-23 15:49:17 -0700451 tegra_init_fuse();
Colin Cross45a1ca02011-03-28 17:47:31 -0700452 tegra_gpio_resume_init();
Colin Crossd8611962010-01-28 16:40:29 -0800453 tegra_init_clock();
Colin Cross120c3562011-03-28 17:48:56 -0700454 tegra_init_pinmux();
Colin Crossd8611962010-01-28 16:40:29 -0800455 tegra_clk_init_from_table(common_clk_init_table);
Dima Zavin7db7cbc2010-09-16 17:58:05 -0700456 tegra_init_power();
Krishna Reddy1212eb82011-12-01 15:32:36 -0800457 tegra_init_cache(true);
Rakesh Bodla1ad210a2011-05-31 15:18:00 +0530458 tegra_init_ahb_gizmo_settings();
Laxman Dewangan97d41432012-02-22 17:35:38 +0530459 tegra_init_debug_uart_rate();
Erik Gillingc5f80062010-01-21 16:53:02 -0800460}
Colin Cross8e437c22010-11-28 22:36:08 -0800461
462static int __init tegra_lp0_vec_arg(char *options)
463{
464 char *p = options;
465
466 tegra_lp0_vec_size = memparse(p, &p);
467 if (*p == '@')
468 tegra_lp0_vec_start = memparse(p+1, &p);
Scott Williams03122532011-01-13 14:30:20 -0800469 if (!tegra_lp0_vec_size || !tegra_lp0_vec_start) {
470 tegra_lp0_vec_size = 0;
471 tegra_lp0_vec_start = 0;
472 }
Colin Cross8e437c22010-11-28 22:36:08 -0800473
474 return 0;
475}
476early_param("lp0_vec", tegra_lp0_vec_arg);
477
Colin Cross838d7d62010-10-19 14:45:50 -0700478static int __init tegra_bootloader_fb_arg(char *options)
479{
480 char *p = options;
481
482 tegra_bootloader_fb_size = memparse(p, &p);
483 if (*p == '@')
484 tegra_bootloader_fb_start = memparse(p+1, &p);
485
486 pr_info("Found tegra_fbmem: %08lx@%08lx\n",
487 tegra_bootloader_fb_size, tegra_bootloader_fb_start);
488
489 return 0;
490}
491early_param("tegra_fbmem", tegra_bootloader_fb_arg);
492
Ray Poudrierb2278732011-12-08 17:38:25 -0800493static int __init tegra_sku_override(char *id)
494{
495 char *p = id;
496
497 sku_override = memparse(p, &p);
498
499 return 0;
500}
501early_param("sku_override", tegra_sku_override);
502
503int tegra_get_sku_override(void)
504{
505 return sku_override;
506}
507
Krishna Reddyb7d5a862011-10-05 12:23:37 -0700508static int __init tegra_vpr_arg(char *options)
509{
510 char *p = options;
511
512 tegra_vpr_size = memparse(p, &p);
513 if (*p == '@')
514 tegra_vpr_start = memparse(p+1, &p);
515 pr_info("Found vpr, start=0x%lx size=%lx",
516 tegra_vpr_start, tegra_vpr_size);
Colin Patrick McCabe997f4282011-11-09 13:44:27 -0800517 return 0;
Krishna Reddyb7d5a862011-10-05 12:23:37 -0700518}
519early_param("vpr", tegra_vpr_arg);
520
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530521enum panel_type get_panel_type(void)
522{
523 return board_panel_type;
524}
525static int __init tegra_board_panel_type(char *options)
526{
527 if (!strcmp(options, "lvds"))
528 board_panel_type = panel_type_lvds;
529 else if (!strcmp(options, "dsi"))
530 board_panel_type = panel_type_dsi;
531 else
532 return 0;
533 return 1;
534}
535__setup("panel=", tegra_board_panel_type);
536
Laxman Dewangan8644fc02011-09-04 17:10:13 +0530537enum power_supply_type get_power_supply_type(void)
538{
539 return pow_supply_type;
540}
541static int __init tegra_board_power_supply_type(char *options)
542{
543 if (!strcmp(options, "Adapter"))
544 pow_supply_type = POWER_SUPPLY_TYPE_MAINS;
545 if (!strcmp(options, "Mains"))
546 pow_supply_type = POWER_SUPPLY_TYPE_MAINS;
547 else if (!strcmp(options, "Battery"))
548 pow_supply_type = POWER_SUPPLY_TYPE_BATTERY;
549 else
550 return 0;
551 return 1;
552}
553__setup("power_supply=", tegra_board_power_supply_type);
554
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530555int get_core_edp(void)
556{
557 return pmu_core_edp;
558}
559static int __init tegra_pmu_core_edp(char *options)
560{
561 char *p = options;
Alex Frid3a5fc7c2011-05-11 16:01:44 -0700562 int core_edp = memparse(p, &p);
563 if (core_edp != 0)
564 pmu_core_edp = core_edp;
Deepesh Gujarathi9f73e312011-10-07 15:18:30 +0530565 return 0;
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530566}
Deepesh Gujarathiab7815e2011-09-15 13:57:02 +0530567early_param("core_edp_mv", tegra_pmu_core_edp);
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530568
Laxman Dewangan1f8be3d2011-10-15 15:44:04 +0530569int get_maximum_cpu_current_supported(void)
570{
571 return max_cpu_current;
572}
573static int __init tegra_max_cpu_current(char *options)
574{
575 char *p = options;
576 max_cpu_current = memparse(p, &p);
577 return 1;
578}
579__setup("max_cpu_cur_ma=", tegra_max_cpu_current);
580
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530581static int __init tegra_debug_uartport(char *info)
582{
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530583 char *p = info;
Laxman Dewanganc032ab22011-09-28 14:42:49 +0530584 unsigned long long port_id;
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530585 if (!strncmp(p, "hsport", 6))
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530586 is_tegra_debug_uart_hsport = true;
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530587 else if (!strncmp(p, "lsport", 6))
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530588 is_tegra_debug_uart_hsport = false;
589
Laxman Dewanganc032ab22011-09-28 14:42:49 +0530590 if (p[6] == ',') {
591 if (p[7] == '-') {
592 debug_uart_port_id = -1;
593 } else {
594 port_id = memparse(p + 7, &p);
595 debug_uart_port_id = (int) port_id;
596 }
597 } else {
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530598 debug_uart_port_id = -1;
Laxman Dewanganc032ab22011-09-28 14:42:49 +0530599 }
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530600
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530601 return 1;
602}
603
604bool is_tegra_debug_uartport_hs(void)
605{
606 return is_tegra_debug_uart_hsport;
607}
608
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530609int get_tegra_uart_debug_port_id(void)
610{
611 return debug_uart_port_id;
612}
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530613__setup("debug_uartport=", tegra_debug_uartport);
614
Ashwini Ghuge6bf2a5b2012-03-19 17:21:38 +0530615static int __init tegra_image_type(char *options)
616{
617 if (!strcmp(options, "RCK"))
618 board_image_type = rck_image;
619
620 return 0;
621}
622
623enum image_type get_tegra_image_type(void)
624{
625 return board_image_type;
626}
627
628__setup("image=", tegra_image_type);
629
Laxman Dewangan57b08762011-09-18 16:49:10 +0530630static int __init tegra_audio_codec_type(char *info)
631{
632 char *p = info;
633 if (!strncmp(p, "wm8903", 6))
634 audio_codec_name = audio_codec_wm8903;
635 else
636 audio_codec_name = audio_codec_none;
637
638 return 1;
639}
640
641enum audio_codec_type get_audio_codec_type(void)
642{
643 return audio_codec_name;
644}
645__setup("audio_codec=", tegra_audio_codec_type);
646
Nitin Kumbhar637ced42010-12-10 15:16:37 +0530647void tegra_get_board_info(struct board_info *bi)
648{
singhome_leef20f8fa2012-08-15 16:58:20 +0800649 bi->board_id = 0xF41;
650 bi->sku = 0xA00;
651 bi->fab =0x1;
652 bi->major_revision = 0x044;
653 bi->minor_revision = 0x2;
Nitin Kumbhar637ced42010-12-10 15:16:37 +0530654}
Laxman Dewangan87d07ce2011-06-15 00:48:57 +0530655static int __init tegra_pmu_board_info(char *info)
656{
657 char *p = info;
658 pmu_board_info.board_id = memparse(p, &p);
659 pmu_board_info.sku = memparse(p+1, &p);
660 pmu_board_info.fab = memparse(p+1, &p);
661 pmu_board_info.major_revision = memparse(p+1, &p);
662 pmu_board_info.minor_revision = memparse(p+1, &p);
663 return 1;
664}
665
666void tegra_get_pmu_board_info(struct board_info *bi)
667{
singhome_leef20f8fa2012-08-15 16:58:20 +0800668 pmu_board_info.sku = 0x1;
Laxman Dewangan87d07ce2011-06-15 00:48:57 +0530669 memcpy(bi, &pmu_board_info, sizeof(struct board_info));
670}
671
672__setup("pmuboard=", tegra_pmu_board_info);
673
Hyungwoo Yang187ada82011-10-24 15:06:17 -0700674static int __init tegra_display_board_info(char *info)
675{
676 char *p = info;
677 display_board_info.board_id = memparse(p, &p);
678 display_board_info.sku = memparse(p+1, &p);
679 display_board_info.fab = memparse(p+1, &p);
680 display_board_info.major_revision = memparse(p+1, &p);
681 display_board_info.minor_revision = memparse(p+1, &p);
682 return 1;
683}
684
685void tegra_get_display_board_info(struct board_info *bi)
686{
687 memcpy(bi, &display_board_info, sizeof(struct board_info));
688}
689
690__setup("displayboard=", tegra_display_board_info);
691
Jihoon Bangea8fd162011-12-12 11:00:14 -0800692static int __init tegra_camera_board_info(char *info)
693{
694 char *p = info;
695 camera_board_info.board_id = memparse(p, &p);
696 camera_board_info.sku = memparse(p+1, &p);
697 camera_board_info.fab = memparse(p+1, &p);
698 camera_board_info.major_revision = memparse(p+1, &p);
699 camera_board_info.minor_revision = memparse(p+1, &p);
700 return 1;
701}
702
703void tegra_get_camera_board_info(struct board_info *bi)
704{
705 memcpy(bi, &camera_board_info, sizeof(struct board_info));
706}
707
708__setup("cameraboard=", tegra_camera_board_info);
709
Steve Lind2f4e4d2011-07-11 12:45:06 -0700710static int __init tegra_modem_id(char *id)
711{
712 char *p = id;
713
714 modem_id = memparse(p, &p);
715 return 1;
716}
717
718int tegra_get_modem_id(void)
719{
720 return modem_id;
721}
722
723__setup("modem_id=", tegra_modem_id);
Laxman Dewangan87d07ce2011-06-15 00:48:57 +0530724
Colin Crossf9c9bde2010-10-19 16:12:33 -0700725/*
726 * Tegra has a protected aperture that prevents access by most non-CPU
727 * memory masters to addresses above the aperture value. Enabling it
728 * secures the CPU's memory from the GPU, except through the GART.
729 */
730void __init tegra_protected_aperture_init(unsigned long aperture)
731{
732#ifndef CONFIG_NVMAP_ALLOW_SYSMEM
733 void __iomem *mc_base = IO_ADDRESS(TEGRA_MC_BASE);
734 pr_info("Enabling Tegra protected aperture at 0x%08lx\n", aperture);
735 writel(aperture, mc_base + MC_SECURITY_CFG2);
736#else
737 pr_err("Tegra protected aperture disabled because nvmap is using "
738 "system memory\n");
739#endif
740}
741
Colin Cross115467a2010-10-19 21:09:29 -0700742/*
743 * Due to conflicting restrictions on the placement of the framebuffer,
744 * the bootloader is likely to leave the framebuffer pointed at a location
745 * in memory that is outside the grhost aperture. This function will move
746 * the framebuffer contents from a physical address that is anywher (lowmem,
747 * highmem, or outside the memory map) to a physical address that is outside
748 * the memory map.
749 */
750void tegra_move_framebuffer(unsigned long to, unsigned long from,
751 unsigned long size)
752{
753 struct page *page;
754 void __iomem *to_io;
755 void *from_virt;
756 unsigned long i;
757
758 BUG_ON(PAGE_ALIGN((unsigned long)to) != (unsigned long)to);
759 BUG_ON(PAGE_ALIGN(from) != from);
760 BUG_ON(PAGE_ALIGN(size) != size);
761
762 to_io = ioremap(to, size);
763 if (!to_io) {
764 pr_err("%s: Failed to map target framebuffer\n", __func__);
765 return;
766 }
767
Colin Cross115467a2010-10-19 21:09:29 -0700768 if (pfn_valid(page_to_pfn(phys_to_page(from)))) {
769 for (i = 0 ; i < size; i += PAGE_SIZE) {
770 page = phys_to_page(from + i);
771 from_virt = kmap(page);
Jon Mayoa8553a42011-08-29 18:09:16 -0700772 memcpy(to_io + i, from_virt, PAGE_SIZE);
Colin Cross115467a2010-10-19 21:09:29 -0700773 kunmap(page);
774 }
775 } else {
776 void __iomem *from_io = ioremap(from, size);
777 if (!from_io) {
778 pr_err("%s: Failed to map source framebuffer\n",
779 __func__);
780 goto out;
781 }
782
Kevin Huangece493d2011-07-05 18:27:43 -0700783 for (i = 0; i < size; i += 4)
Colin Cross115467a2010-10-19 21:09:29 -0700784 writel(readl(from_io + i), to_io + i);
785
786 iounmap(from_io);
787 }
788out:
789 iounmap(to_io);
790}
791
Hiro Sugawara510eb102011-12-13 09:12:26 -0800792#ifdef CONFIG_TEGRA_SMMU_BASE_AT_E0000000
793#define FORCE_SMMU_BASE_FOR_TEGRA3_A01 1
794#else
795#define FORCE_SMMU_BASE_FOR_TEGRA3_A01 0
796#endif
797#if FORCE_SMMU_BASE_FOR_TEGRA3_A01 || \
798 (defined(CONFIG_TEGRA_IOVMM_SMMU) && defined(CONFIG_ARCH_TEGRA_3x_SOC))
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700799/* Support for Tegra3 A01 chip mask that needs to have SMMU IOVA reside in
800 * the upper half of 4GB IOVA space. A02 and after use the bottom 1GB and
801 * do not need to reserve memory.
802 */
Hiro Sugawara510eb102011-12-13 09:12:26 -0800803#define SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700804#endif
805
Colin Cross838d7d62010-10-19 14:45:50 -0700806void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size,
807 unsigned long fb2_size)
808{
Hiro Sugawara510eb102011-12-13 09:12:26 -0800809#ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700810 int smmu_reserved = 0;
Hiro Sugawara10f14812011-09-13 17:20:35 -0700811 struct tegra_smmu_window *smmu_window = tegra_smmu_window(0);
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700812#endif
Colin Cross838d7d62010-10-19 14:45:50 -0700813
Scott Williams03122532011-01-13 14:30:20 -0800814 if (carveout_size) {
815 tegra_carveout_start = memblock_end_of_DRAM() - carveout_size;
816 if (memblock_remove(tegra_carveout_start, carveout_size)) {
817 pr_err("Failed to remove carveout %08lx@%08lx "
818 "from memory map\n",
Hiro Sugawara5cb430a2011-03-10 15:19:03 -0800819 carveout_size, tegra_carveout_start);
Scott Williams03122532011-01-13 14:30:20 -0800820 tegra_carveout_start = 0;
821 tegra_carveout_size = 0;
Kevin Huangece493d2011-07-05 18:27:43 -0700822 } else
Scott Williams03122532011-01-13 14:30:20 -0800823 tegra_carveout_size = carveout_size;
824 }
Colin Cross838d7d62010-10-19 14:45:50 -0700825
Scott Williams03122532011-01-13 14:30:20 -0800826 if (fb2_size) {
827 tegra_fb2_start = memblock_end_of_DRAM() - fb2_size;
828 if (memblock_remove(tegra_fb2_start, fb2_size)) {
Kevin Huangece493d2011-07-05 18:27:43 -0700829 pr_err("Failed to remove second framebuffer "
830 "%08lx@%08lx from memory map\n",
Hiro Sugawaradc1d2812011-04-29 11:59:37 -0700831 fb2_size, tegra_fb2_start);
Scott Williams03122532011-01-13 14:30:20 -0800832 tegra_fb2_start = 0;
833 tegra_fb2_size = 0;
834 } else
835 tegra_fb2_size = fb2_size;
836 }
Colin Cross838d7d62010-10-19 14:45:50 -0700837
Scott Williams03122532011-01-13 14:30:20 -0800838 if (fb_size) {
839 tegra_fb_start = memblock_end_of_DRAM() - fb_size;
840 if (memblock_remove(tegra_fb_start, fb_size)) {
841 pr_err("Failed to remove framebuffer %08lx@%08lx "
842 "from memory map\n",
Hiro Sugawara5cb430a2011-03-10 15:19:03 -0800843 fb_size, tegra_fb_start);
Scott Williams03122532011-01-13 14:30:20 -0800844 tegra_fb_start = 0;
845 tegra_fb_size = 0;
846 } else
847 tegra_fb_size = fb_size;
848 }
Colin Cross838d7d62010-10-19 14:45:50 -0700849
Colin Crossf9c9bde2010-10-19 16:12:33 -0700850 if (tegra_fb_size)
851 tegra_grhost_aperture = tegra_fb_start;
852
853 if (tegra_fb2_size && tegra_fb2_start < tegra_grhost_aperture)
854 tegra_grhost_aperture = tegra_fb2_start;
855
856 if (tegra_carveout_size && tegra_carveout_start < tegra_grhost_aperture)
857 tegra_grhost_aperture = tegra_carveout_start;
858
Hiro Sugawara510eb102011-12-13 09:12:26 -0800859#ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700860 if (!smmu_window) {
Hiro Sugawara10f14812011-09-13 17:20:35 -0700861 pr_err("No SMMU resource\n");
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700862 } else {
Hiro Sugawara0d218182011-04-08 13:21:02 -0700863 size_t smmu_window_size;
864
Hiro Sugawara510eb102011-12-13 09:12:26 -0800865 if (FORCE_SMMU_BASE_FOR_TEGRA3_A01 ||
866 (tegra_get_chipid() == TEGRA_CHIPID_TEGRA3 &&
867 tegra_get_revision() == TEGRA_REVISION_A01)) {
868 smmu_window->start = TEGRA_SMMU_BASE_TEGRA3_A01;
869 smmu_window->end = TEGRA_SMMU_BASE_TEGRA3_A01 +
870 TEGRA_SMMU_SIZE_TEGRA3_A01 - 1;
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700871 }
872 smmu_window_size = smmu_window->end + 1 - smmu_window->start;
873 if (smmu_window->start >= 0x80000000) {
874 if (memblock_reserve(smmu_window->start,
875 smmu_window_size))
876 pr_err(
877 "Failed to reserve SMMU I/O VA window %08lx@%08lx\n",
Hiro Sugawara0d218182011-04-08 13:21:02 -0700878 (unsigned long)smmu_window_size,
879 (unsigned long)smmu_window->start);
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700880 else
881 smmu_reserved = 1;
882 }
Scott Williams599c1122011-02-10 14:35:32 -0800883 }
884#endif
885
Prashant Gaikwadff192312011-08-03 14:49:20 +0530886 if (tegra_lp0_vec_size &&
887 (tegra_lp0_vec_start < memblock_end_of_DRAM())) {
888 if (memblock_reserve(tegra_lp0_vec_start, tegra_lp0_vec_size)) {
889 pr_err("Failed to reserve lp0_vec %08lx@%08lx\n",
890 tegra_lp0_vec_size, tegra_lp0_vec_start);
891 tegra_lp0_vec_start = 0;
892 tegra_lp0_vec_size = 0;
893 }
894 tegra_lp0_vec_relocate = false;
895 } else
896 tegra_lp0_vec_relocate = true;
897
Colin Cross838d7d62010-10-19 14:45:50 -0700898 /*
Kevin Huangece493d2011-07-05 18:27:43 -0700899 * We copy the bootloader's framebuffer to the framebuffer allocated
900 * above, and then free this one.
901 * */
902 if (tegra_bootloader_fb_size) {
903 tegra_bootloader_fb_size = PAGE_ALIGN(tegra_bootloader_fb_size);
Colin Cross838d7d62010-10-19 14:45:50 -0700904 if (memblock_reserve(tegra_bootloader_fb_start,
Scott Williams03122532011-01-13 14:30:20 -0800905 tegra_bootloader_fb_size)) {
Kevin Huangece493d2011-07-05 18:27:43 -0700906 pr_err("Failed to reserve bootloader frame buffer "
907 "%08lx@%08lx\n", tegra_bootloader_fb_size,
908 tegra_bootloader_fb_start);
Scott Williams03122532011-01-13 14:30:20 -0800909 tegra_bootloader_fb_start = 0;
910 tegra_bootloader_fb_size = 0;
911 }
Kevin Huangece493d2011-07-05 18:27:43 -0700912 }
Colin Cross838d7d62010-10-19 14:45:50 -0700913
914 pr_info("Tegra reserved memory:\n"
915 "LP0: %08lx - %08lx\n"
916 "Bootloader framebuffer: %08lx - %08lx\n"
917 "Framebuffer: %08lx - %08lx\n"
Scott Williams22d51692011-01-11 10:50:52 -0800918 "2nd Framebuffer: %08lx - %08lx\n"
Krishna Reddyb7d5a862011-10-05 12:23:37 -0700919 "Carveout: %08lx - %08lx\n"
920 "Vpr: %08lx - %08lx\n",
Colin Cross838d7d62010-10-19 14:45:50 -0700921 tegra_lp0_vec_start,
Scott Williams03122532011-01-13 14:30:20 -0800922 tegra_lp0_vec_size ?
923 tegra_lp0_vec_start + tegra_lp0_vec_size - 1 : 0,
Colin Cross838d7d62010-10-19 14:45:50 -0700924 tegra_bootloader_fb_start,
Scott Williams03122532011-01-13 14:30:20 -0800925 tegra_bootloader_fb_size ?
926 tegra_bootloader_fb_start + tegra_bootloader_fb_size - 1 : 0,
Colin Cross838d7d62010-10-19 14:45:50 -0700927 tegra_fb_start,
Scott Williams03122532011-01-13 14:30:20 -0800928 tegra_fb_size ?
929 tegra_fb_start + tegra_fb_size - 1 : 0,
Colin Cross838d7d62010-10-19 14:45:50 -0700930 tegra_fb2_start,
Scott Williams03122532011-01-13 14:30:20 -0800931 tegra_fb2_size ?
932 tegra_fb2_start + tegra_fb2_size - 1 : 0,
Colin Cross838d7d62010-10-19 14:45:50 -0700933 tegra_carveout_start,
Scott Williams03122532011-01-13 14:30:20 -0800934 tegra_carveout_size ?
Krishna Reddyb7d5a862011-10-05 12:23:37 -0700935 tegra_carveout_start + tegra_carveout_size - 1 : 0,
936 tegra_vpr_start,
937 tegra_vpr_size ?
938 tegra_vpr_start + tegra_vpr_size - 1 : 0);
Scott Williams599c1122011-02-10 14:35:32 -0800939
Hiro Sugawara510eb102011-12-13 09:12:26 -0800940#ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700941 if (smmu_reserved)
Hiro Sugawara10f14812011-09-13 17:20:35 -0700942 pr_info("SMMU: %08lx - %08lx\n",
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700943 smmu_window->start, smmu_window->end);
Scott Williams599c1122011-02-10 14:35:32 -0800944#endif
Colin Cross838d7d62010-10-19 14:45:50 -0700945}
Kevin Huangece493d2011-07-05 18:27:43 -0700946
Haley Teng290e96f2011-09-27 12:20:32 +0800947static struct resource ram_console_resources[] = {
948 {
949 .flags = IORESOURCE_MEM,
950 },
951};
952
953static struct platform_device ram_console_device = {
954 .name = "ram_console",
955 .id = -1,
956 .num_resources = ARRAY_SIZE(ram_console_resources),
957 .resource = ram_console_resources,
958};
959
960void __init tegra_ram_console_debug_reserve(unsigned long ram_console_size)
961{
962 struct resource *res;
963 long ret;
964
965 res = platform_get_resource(&ram_console_device, IORESOURCE_MEM, 0);
966 if (!res)
967 goto fail;
968 res->start = memblock_end_of_DRAM() - ram_console_size;
969 res->end = res->start + ram_console_size - 1;
970 ret = memblock_remove(res->start, ram_console_size);
971 if (ret)
972 goto fail;
973
974 return;
975
976fail:
977 ram_console_device.resource = NULL;
978 ram_console_device.num_resources = 0;
979 pr_err("Failed to reserve memory block for ram console\n");
980}
981
982void __init tegra_ram_console_debug_init(void)
983{
984 int err;
985
986 err = platform_device_register(&ram_console_device);
987 if (err) {
988 pr_err("%s: ram console registration failed (%d)!\n", __func__, err);
989 }
990}
991
Kevin Huangece493d2011-07-05 18:27:43 -0700992void __init tegra_release_bootloader_fb(void)
993{
994 /* Since bootloader fb is reserved in common.c, it is freed here. */
995 if (tegra_bootloader_fb_size)
996 if (memblock_free(tegra_bootloader_fb_start,
997 tegra_bootloader_fb_size))
998 pr_err("Failed to free bootloader fb.\n");
999}
Victor(Weiguo) Pan5ab70782011-08-23 14:48:30 -07001000
Bharat Nihalani50e7bec2011-05-19 20:09:14 +05301001#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
Wen Yifd9bfde2011-04-18 14:21:25 -07001002static char cpufreq_gov_default[32];
1003static char *cpufreq_gov_conservative = "conservative";
1004static char *cpufreq_sysfs_place_holder="/sys/devices/system/cpu/cpu%i/cpufreq/scaling_governor";
Wen Yi10027352011-06-06 13:51:12 -07001005static char *cpufreq_gov_conservative_param="/sys/devices/system/cpu/cpufreq/conservative/%s";
Wen Yifd9bfde2011-04-18 14:21:25 -07001006
1007static void cpufreq_set_governor(char *governor)
1008{
1009 struct file *scaling_gov = NULL;
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001010 mm_segment_t old_fs;
Wen Yifd9bfde2011-04-18 14:21:25 -07001011 char buf[128];
Diwakar Tundlam47719fe2012-01-30 15:53:05 -08001012 int i = 0;
Wen Yifd9bfde2011-04-18 14:21:25 -07001013 loff_t offset = 0;
1014
1015 if (governor == NULL)
1016 return;
1017
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001018 /* change to KERNEL_DS address limit */
1019 old_fs = get_fs();
1020 set_fs(KERNEL_DS);
Prashant Gaikwad8d1e39c2011-12-26 16:41:29 +05301021#ifndef CONFIG_TEGRA_AUTO_HOTPLUG
Sang-Hun Lee00535522011-12-22 11:06:29 -08001022 for_each_online_cpu(i)
1023#endif
1024 {
Wen Yifd9bfde2011-04-18 14:21:25 -07001025 sprintf(buf, cpufreq_sysfs_place_holder, i);
1026 scaling_gov = filp_open(buf, O_RDWR, 0);
Wen Yi50582972012-01-06 16:29:00 -08001027 if (scaling_gov != NULL) {
Wen Yifd9bfde2011-04-18 14:21:25 -07001028 if (scaling_gov->f_op != NULL &&
1029 scaling_gov->f_op->write != NULL)
1030 scaling_gov->f_op->write(scaling_gov,
1031 governor,
1032 strlen(governor),
1033 &offset);
1034 else
1035 pr_err("f_op might be null\n");
1036
1037 filp_close(scaling_gov, NULL);
Wen Yi50582972012-01-06 16:29:00 -08001038 } else {
1039 pr_err("%s. Can't open %s\n", __func__, buf);
Wen Yifd9bfde2011-04-18 14:21:25 -07001040 }
1041 }
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001042 set_fs(old_fs);
Wen Yifd9bfde2011-04-18 14:21:25 -07001043}
1044
1045void cpufreq_save_default_governor(void)
1046{
1047 struct file *scaling_gov = NULL;
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001048 mm_segment_t old_fs;
Wen Yifd9bfde2011-04-18 14:21:25 -07001049 char buf[128];
1050 loff_t offset = 0;
1051
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001052 /* change to KERNEL_DS address limit */
1053 old_fs = get_fs();
1054 set_fs(KERNEL_DS);
1055
Wen Yifd9bfde2011-04-18 14:21:25 -07001056 buf[127] = 0;
1057 sprintf(buf, cpufreq_sysfs_place_holder,0);
1058 scaling_gov = filp_open(buf, O_RDONLY, 0);
Wen Yi50582972012-01-06 16:29:00 -08001059 if (scaling_gov != NULL) {
Wen Yifd9bfde2011-04-18 14:21:25 -07001060 if (scaling_gov->f_op != NULL &&
1061 scaling_gov->f_op->read != NULL)
1062 scaling_gov->f_op->read(scaling_gov,
1063 cpufreq_gov_default,
Wen Yi10027352011-06-06 13:51:12 -07001064 32,
Wen Yifd9bfde2011-04-18 14:21:25 -07001065 &offset);
1066 else
1067 pr_err("f_op might be null\n");
1068
1069 filp_close(scaling_gov, NULL);
Wen Yi50582972012-01-06 16:29:00 -08001070 } else {
1071 pr_err("%s. Can't open %s\n", __func__, buf);
Wen Yifd9bfde2011-04-18 14:21:25 -07001072 }
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001073 set_fs(old_fs);
Wen Yifd9bfde2011-04-18 14:21:25 -07001074}
1075
1076void cpufreq_restore_default_governor(void)
1077{
1078 cpufreq_set_governor(cpufreq_gov_default);
1079}
1080
Wen Yi50582972012-01-06 16:29:00 -08001081void cpufreq_set_conservative_governor_param(char *name, int value)
Wen Yi10027352011-06-06 13:51:12 -07001082{
1083 struct file *gov_param = NULL;
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001084 mm_segment_t old_fs;
Wen Yi50582972012-01-06 16:29:00 -08001085 static char buf[128], param_value[8];
1086 loff_t offset = 0;
Wen Yi10027352011-06-06 13:51:12 -07001087
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001088 /* change to KERNEL_DS address limit */
1089 old_fs = get_fs();
1090 set_fs(KERNEL_DS);
1091
Wen Yi50582972012-01-06 16:29:00 -08001092 sprintf(param_value, "%d", value);
1093 sprintf(buf, cpufreq_gov_conservative_param, name);
1094 gov_param = filp_open(buf, O_RDWR, 0);
1095 if (gov_param != NULL) {
Wen Yi10027352011-06-06 13:51:12 -07001096 if (gov_param->f_op != NULL &&
1097 gov_param->f_op->write != NULL)
1098 gov_param->f_op->write(gov_param,
Wen Yi50582972012-01-06 16:29:00 -08001099 param_value,
1100 strlen(param_value),
Wen Yi10027352011-06-06 13:51:12 -07001101 &offset);
1102 else
1103 pr_err("f_op might be null\n");
1104
1105 filp_close(gov_param, NULL);
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001106 } else {
Wen Yi50582972012-01-06 16:29:00 -08001107 pr_err("%s. Can't open %s\n", __func__, buf);
Wen Yi10027352011-06-06 13:51:12 -07001108 }
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001109 set_fs(old_fs);
Wen Yi10027352011-06-06 13:51:12 -07001110}
1111
Wen Yifd9bfde2011-04-18 14:21:25 -07001112void cpufreq_set_conservative_governor(void)
1113{
1114 cpufreq_set_governor(cpufreq_gov_conservative);
1115}
Bharat Nihalani50e7bec2011-05-19 20:09:14 +05301116#endif /* CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND */