blob: 9d5b0819c9d08a573ce0058c07251e418ba025c9 [file] [log] [blame]
Erik Gillingc5f80062010-01-21 16:53:02 -08001/*
Todd Poynor433cb7f2010-09-02 15:10:29 -07002 * arch/arm/mach-tegra/common.c
Erik Gillingc5f80062010-01-21 16:53:02 -08003 *
4 * Copyright (C) 2010 Google, Inc.
Alex Fride818b6e2012-01-12 20:27:55 -08005 * Copyright (C) 2010-2012 NVIDIA Corporation
Erik Gillingc5f80062010-01-21 16:53:02 -08006 *
7 * Author:
8 * Colin Cross <ccross@android.com>
9 *
10 * This software is licensed under the terms of the GNU General Public
11 * License version 2, as published by the Free Software Foundation, and
12 * may be copied, distributed, and modified under those terms.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 */
20
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -070021#include <linux/platform_device.h>
Dima Zavin7e158ac2010-11-11 15:28:46 -080022#include <linux/console.h>
Erik Gillingc5f80062010-01-21 16:53:02 -080023#include <linux/init.h>
24#include <linux/io.h>
Colin Cross4de3a8f2010-04-05 13:16:42 -070025#include <linux/clk.h>
26#include <linux/delay.h>
Colin Cross115467a2010-10-19 21:09:29 -070027#include <linux/highmem.h>
Colin Cross8e437c22010-11-28 22:36:08 -080028#include <linux/memblock.h>
Rakesh Bodla1ad210a2011-05-31 15:18:00 +053029#include <linux/bitops.h>
Chris Johnson644d1fb2011-11-18 16:14:07 -080030#include <linux/sched.h>
Erik Gillingc5f80062010-01-21 16:53:02 -080031
32#include <asm/hardware/cache-l2x0.h>
Dima Zavin7e158ac2010-11-11 15:28:46 -080033#include <asm/system.h>
Erik Gillingc5f80062010-01-21 16:53:02 -080034
Colin Cross45a1ca02011-03-28 17:47:31 -070035#include <mach/gpio.h>
Erik Gillingc5f80062010-01-21 16:53:02 -080036#include <mach/iomap.h>
Colin Cross120c3562011-03-28 17:48:56 -070037#include <mach/pinmux.h>
Dima Zavin7db7cbc2010-09-16 17:58:05 -070038#include <mach/powergate.h>
Colin Cross699fe142010-08-23 18:37:25 -070039#include <mach/system.h>
Hiroshi DOYU6ebf00f2012-01-09 08:52:47 +020040#include <mach/tegra_smmu.h>
Erik Gillingc5f80062010-01-21 16:53:02 -080041
Jon Mayo6ae77a92010-12-21 15:09:33 -080042#include "apbio.h"
Erik Gillingc5f80062010-01-21 16:53:02 -080043#include "board.h"
Colin Crossd8611962010-01-28 16:40:29 -080044#include "clock.h"
Colin Cross73625e32010-06-23 15:49:17 -070045#include "fuse.h"
Colin Cross8e437c22010-11-28 22:36:08 -080046#include "pm.h"
Scott Williams45376ca2011-08-17 11:47:58 -070047#include "reset.h"
Colin Cross8e437c22010-11-28 22:36:08 -080048
Scott Williams816ab052010-12-07 11:19:20 -080049#define MC_SECURITY_CFG2 0x7c
Colin Crossf9c9bde2010-10-19 16:12:33 -070050
Rakesh Bodla1ad210a2011-05-31 15:18:00 +053051#define AHB_ARBITRATION_PRIORITY_CTRL 0x4
52#define AHB_PRIORITY_WEIGHT(x) (((x) & 0x7) << 29)
53#define PRIORITY_SELECT_USB BIT(6)
54#define PRIORITY_SELECT_USB2 BIT(18)
55#define PRIORITY_SELECT_USB3 BIT(17)
56
57#define AHB_GIZMO_AHB_MEM 0xc
58#define ENB_FAST_REARBITRATE BIT(2)
Jay Chengce4a7df2011-06-09 17:34:35 -040059#define DONT_SPLIT_AHB_WR BIT(7)
Rakesh Bodla1ad210a2011-05-31 15:18:00 +053060
61#define AHB_GIZMO_USB 0x1c
62#define AHB_GIZMO_USB2 0x78
63#define AHB_GIZMO_USB3 0x7c
64#define IMMEDIATE BIT(18)
65
66#define AHB_MEM_PREFETCH_CFG3 0xe0
67#define AHB_MEM_PREFETCH_CFG4 0xe4
68#define AHB_MEM_PREFETCH_CFG1 0xec
69#define AHB_MEM_PREFETCH_CFG2 0xf0
70#define PREFETCH_ENB BIT(31)
71#define MST_ID(x) (((x) & 0x1f) << 26)
72#define AHBDMA_MST_ID MST_ID(5)
73#define USB_MST_ID MST_ID(6)
74#define USB2_MST_ID MST_ID(18)
75#define USB3_MST_ID MST_ID(17)
76#define ADDR_BNDRY(x) (((x) & 0xf) << 21)
77#define INACTIVITY_TIMEOUT(x) (((x) & 0xffff) << 0)
78
Colin Cross838d7d62010-10-19 14:45:50 -070079unsigned long tegra_bootloader_fb_start;
80unsigned long tegra_bootloader_fb_size;
81unsigned long tegra_fb_start;
82unsigned long tegra_fb_size;
83unsigned long tegra_fb2_start;
84unsigned long tegra_fb2_size;
85unsigned long tegra_carveout_start;
86unsigned long tegra_carveout_size;
Krishna Reddyb7d5a862011-10-05 12:23:37 -070087unsigned long tegra_vpr_start;
88unsigned long tegra_vpr_size;
Colin Cross8e437c22010-11-28 22:36:08 -080089unsigned long tegra_lp0_vec_start;
90unsigned long tegra_lp0_vec_size;
Prashant Gaikwadff192312011-08-03 14:49:20 +053091bool tegra_lp0_vec_relocate;
Scott Williams03122532011-01-13 14:30:20 -080092unsigned long tegra_grhost_aperture = ~0ul;
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +053093static bool is_tegra_debug_uart_hsport;
Laxman Dewangan87d07ce2011-06-15 00:48:57 +053094static struct board_info pmu_board_info;
Hyungwoo Yang187ada82011-10-24 15:06:17 -070095static struct board_info display_board_info;
Jihoon Bangea8fd162011-12-12 11:00:14 -080096static struct board_info camera_board_info;
Colin Crossd8611962010-01-28 16:40:29 -080097
Alex Frid3a5fc7c2011-05-11 16:01:44 -070098static int pmu_core_edp = 1200; /* default 1.2V EDP limit */
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +053099static int board_panel_type;
Laxman Dewangan8644fc02011-09-04 17:10:13 +0530100static enum power_supply_type pow_supply_type = POWER_SUPPLY_TYPE_MAINS;
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530101
Colin Cross699fe142010-08-23 18:37:25 -0700102void (*arch_reset)(char mode, const char *cmd) = tegra_assert_system_reset;
103
Scott Williamsae811c32011-02-10 15:45:06 -0800104#define NEVER_RESET 0
Scott Williams9bc40532011-01-28 03:26:28 -0800105
Colin Cross699fe142010-08-23 18:37:25 -0700106void tegra_assert_system_reset(char mode, const char *cmd)
107{
Scott Williams9bc40532011-01-28 03:26:28 -0800108#if defined(CONFIG_TEGRA_FPGA_PLATFORM) || NEVER_RESET
Scott Williamsae811c32011-02-10 15:45:06 -0800109 printk("tegra_assert_system_reset() ignored.....");
Scott Williams9bc40532011-01-28 03:26:28 -0800110 do { } while (1);
111#else
Deepesh Gujarathi43921782010-12-07 14:09:22 +0530112 void __iomem *reset = IO_ADDRESS(TEGRA_PMC_BASE + 0x00);
Colin Cross699fe142010-08-23 18:37:25 -0700113 u32 reg;
114
Simon Glass375b19c2011-02-17 08:13:57 -0800115 /* use *_related to avoid spinlock since caches are off */
116 reg = readl_relaxed(reset);
Deepesh Gujarathi43921782010-12-07 14:09:22 +0530117 reg |= 0x10;
Simon Glass375b19c2011-02-17 08:13:57 -0800118 writel_relaxed(reg, reset);
Scott Williams4ad5ff12011-01-07 20:43:13 -0800119#endif
Colin Cross699fe142010-08-23 18:37:25 -0700120}
Steve Lind2f4e4d2011-07-11 12:45:06 -0700121static int modem_id;
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530122static int debug_uart_port_id;
Laxman Dewangan57b08762011-09-18 16:49:10 +0530123static enum audio_codec_type audio_codec_name;
Laxman Dewangan1f8be3d2011-10-15 15:44:04 +0530124static int max_cpu_current;
Colin Cross699fe142010-08-23 18:37:25 -0700125
Laxman Dewangan844407d2011-04-27 19:11:08 +0530126/* WARNING: There is implicit client of pllp_out3 like i2c, uart, dsi
127 * and so this clock (pllp_out3) should never be disabled.
128 */
Colin Crossd8611962010-01-28 16:40:29 -0800129static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
130 /* name parent rate enabled */
131 { "clk_m", NULL, 0, true },
Yudong Tanf8cd6292011-07-01 11:26:17 -0700132#ifdef CONFIG_TEGRA_SILICON_PLATFORM
Alex Fridc86c2252011-05-28 00:21:30 -0700133#ifdef CONFIG_ARCH_TEGRA_2x_SOC
Scott Williams816ab052010-12-07 11:19:20 -0800134 { "pll_p", NULL, 216000000, true },
Colin Crossd8611962010-01-28 16:40:29 -0800135 { "pll_p_out1", "pll_p", 28800000, true },
Prashant Gaikwad1529b8e2012-01-23 12:43:28 +0530136 { "pll_p_out2", "pll_p", 48000000, false },
Colin Crossd8611962010-01-28 16:40:29 -0800137 { "pll_p_out3", "pll_p", 72000000, true },
Prashant Gaikwad1529b8e2012-01-23 12:43:28 +0530138 { "pll_p_out4", "pll_p", 108000000, false },
Prashant Gaikwad9a975332011-11-01 18:16:47 +0530139 { "pll_m", "clk_m", 0, true },
Pritesh Raithathabb1d62b2011-11-11 16:52:11 +0530140 { "pll_m_out1", "pll_m", 120000000, true },
Prashant Gaikwad9a975332011-11-01 18:16:47 +0530141 { "sclk", "pll_c_out1", 40000000, true },
Scott Williams07fc3312011-05-23 22:08:42 -0700142 { "hclk", "sclk", 40000000, true },
143 { "pclk", "hclk", 40000000, true },
Prashant Gaikwad9a975332011-11-01 18:16:47 +0530144 { "mpe", "pll_c", 0, false },
145 { "epp", "pll_c", 0, false },
146 { "vi_sensor", "pll_c", 0, false },
147 { "vi", "pll_c", 0, false },
148 { "2d", "pll_c", 0, false },
149 { "3d", "pll_c", 0, false },
Scott Williams07fc3312011-05-23 22:08:42 -0700150#else
Alex Fride818b6e2012-01-12 20:27:55 -0800151 { "pll_p", NULL, 0, true },
152 { "pll_p_out1", "pll_p", 0, false },
ScottPetersonfde0dd42011-12-28 13:40:20 -0800153 { "pll_p_out2", "pll_p", 48000000, false },
Alex Fride818b6e2012-01-12 20:27:55 -0800154 { "pll_p_out3", "pll_p", 0, true },
Alex Frid58af6ba2011-10-24 18:51:32 -0700155 { "pll_m_out1", "pll_m", 275000000, false },
ScottPetersonfde0dd42011-12-28 13:40:20 -0800156 { "pll_p_out4", "pll_p", 102000000, false },
Alex Fridc86c2252011-05-28 00:21:30 -0700157 { "sclk", "pll_p_out4", 102000000, true },
158 { "hclk", "sclk", 102000000, true },
159 { "pclk", "hclk", 51000000, true },
Alex Frid8b5ce662011-01-31 10:07:57 -0800160#endif
Scott Williams0aac1552011-06-10 12:58:11 -0700161#else
162 { "pll_p", NULL, 216000000, true },
ScottPetersonfde0dd42011-12-28 13:40:20 -0800163 { "pll_p_out1", "pll_p", 28800000, false },
164 { "pll_p_out2", "pll_p", 48000000, false },
Scott Williams0aac1552011-06-10 12:58:11 -0700165 { "pll_p_out3", "pll_p", 72000000, true },
166 { "pll_m_out1", "pll_m", 275000000, true },
167 { "pll_c", NULL, ULONG_MAX, false },
168 { "pll_c_out1", "pll_c", 208000000, false },
ScottPetersonfde0dd42011-12-28 13:40:20 -0800169 { "pll_p_out4", "pll_p", 108000000, false },
Scott Williams0aac1552011-06-10 12:58:11 -0700170 { "sclk", "pll_p_out4", 108000000, true },
171 { "hclk", "sclk", 108000000, true },
172 { "pclk", "hclk", 54000000, true },
173#endif
Colin Crosscd51d0e2011-02-21 17:05:36 -0800174 { "csite", NULL, 0, true },
175 { "emc", NULL, 0, true },
176 { "cpu", NULL, 0, true },
Alex Fridd3b4e362011-05-26 22:58:21 -0700177 { "kfuse", NULL, 0, true },
Varun Wadekar0e0ccdb2011-06-25 16:42:37 +0530178 { "fuse", NULL, 0, true },
Scott Williams816ab052010-12-07 11:19:20 -0800179 { "pll_u", NULL, 480000000, false },
Alex Fridc86c2252011-05-28 00:21:30 -0700180 { "sdmmc1", "pll_p", 48000000, false},
Pavan Kunapuli0a420462011-03-16 19:29:42 +0530181 { "sdmmc3", "pll_p", 48000000, false},
Pavan Kunapuli4a743e72011-11-08 18:02:52 +0530182 { "sdmmc4", "pll_p", 48000000, false},
Scott Williams07fc3312011-05-23 22:08:42 -0700183#ifndef CONFIG_ARCH_TEGRA_2x_SOC
Alex Frid5be85392011-06-28 20:50:29 -0700184 { "cbus", "pll_c", 416000000, false },
Alex Frid7359d832011-05-13 23:58:33 -0700185 { "pll_c_out1", "pll_c", 208000000, false },
Alex Frid7f970e72011-02-04 12:04:14 -0800186#endif
Colin Crossd8611962010-01-28 16:40:29 -0800187 { NULL, NULL, 0, 0},
188};
Erik Gillingc5f80062010-01-21 16:53:02 -0800189
Chris Johnson644d1fb2011-11-18 16:14:07 -0800190#if defined(CONFIG_TRUSTED_FOUNDATIONS) && defined(CONFIG_CACHE_L2X0)
191static void tegra_cache_smc(bool enable, u32 arg)
192{
193 void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
194 bool need_affinity_switch;
195 bool can_switch_affinity;
196 bool l2x0_enabled;
197 cpumask_t local_cpu_mask;
198 cpumask_t saved_cpu_mask;
199 unsigned long flags;
200 long ret;
201
202 /*
203 * ISSUE : Some registers of PL310 controler must be written
204 * from Secure context (and from CPU0)!
205 *
206 * When called form Normal we obtain an abort or do nothing.
207 * Instructions that must be called in Secure:
208 * - Write to Control register (L2X0_CTRL==0x100)
209 * - Write in Auxiliary controler (L2X0_AUX_CTRL==0x104)
210 * - Invalidate all entries (L2X0_INV_WAY==0x77C),
211 * mandatory at boot time.
212 * - Tag and Data RAM Latency Control Registers
213 * (0x108 & 0x10C) must be written in Secure.
214 */
215 need_affinity_switch = (smp_processor_id() != 0);
216 can_switch_affinity = !irqs_disabled();
217
218 WARN_ON(need_affinity_switch && !can_switch_affinity);
219 if (need_affinity_switch && can_switch_affinity) {
220 cpu_set(0, local_cpu_mask);
221 sched_getaffinity(0, &saved_cpu_mask);
222 ret = sched_setaffinity(0, &local_cpu_mask);
223 WARN_ON(ret != 0);
224 }
225
226 local_irq_save(flags);
227 l2x0_enabled = readl_relaxed(p + L2X0_CTRL) & 1;
228 if (enable && !l2x0_enabled)
229 tegra_generic_smc(0xFFFFF100, 0x00000001, arg);
230 else if (!enable && l2x0_enabled)
231 tegra_generic_smc(0xFFFFF100, 0x00000002, arg);
232 local_irq_restore(flags);
233
234 if (need_affinity_switch && can_switch_affinity) {
235 ret = sched_setaffinity(0, &saved_cpu_mask);
236 WARN_ON(ret != 0);
237 }
238}
239
240static void tegra_l2x0_disable(void)
241{
242 unsigned long flags;
243 static u32 l2x0_way_mask;
244
245 if (!l2x0_way_mask) {
246 void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
247 u32 aux_ctrl;
248 u32 ways;
249
250 aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
251 ways = (aux_ctrl & (1 << 16)) ? 16 : 8;
252 l2x0_way_mask = (1 << ways) - 1;
253 }
254
255 local_irq_save(flags);
256 tegra_cache_smc(false, l2x0_way_mask);
257 local_irq_restore(flags);
258}
259#endif /* CONFIG_TRUSTED_FOUNDATIONS && defined(CONFIG_CACHE_L2X0) */
260
Krishna Reddy1212eb82011-12-01 15:32:36 -0800261void tegra_init_cache(bool init)
Erik Gillingc5f80062010-01-21 16:53:02 -0800262{
263#ifdef CONFIG_CACHE_L2X0
264 void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
Scott Williams191914c2010-12-27 19:03:57 -0800265 u32 aux_ctrl;
Diwakar Tundlamf4ca2962011-12-02 15:49:42 -0800266 u32 speedo;
Krishna Reddy58eb2d02011-12-05 12:57:07 -0800267 u32 tmp;
Erik Gillingc5f80062010-01-21 16:53:02 -0800268
Chris Johnson644d1fb2011-11-18 16:14:07 -0800269#ifdef CONFIG_TRUSTED_FOUNDATIONS
270 /* issue the SMC to enable the L2 */
271 aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
272 tegra_cache_smc(true, aux_ctrl);
273
274 /* after init, reread aux_ctrl and register handlers */
275 aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
276 l2x0_init(p, aux_ctrl, 0xFFFFFFFF);
277
278 /* override outer_disable() with our disable */
279 outer_cache.disable = tegra_l2x0_disable;
280#else
Scott Williams816ab052010-12-07 11:19:20 -0800281#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
Colin Cross535371c2011-01-22 00:36:14 -0800282 writel_relaxed(0x331, p + L2X0_TAG_LATENCY_CTRL);
283 writel_relaxed(0x441, p + L2X0_DATA_LATENCY_CTRL);
Erik Gillingc5f80062010-01-21 16:53:02 -0800284
Scott Williams816ab052010-12-07 11:19:20 -0800285#elif defined(CONFIG_ARCH_TEGRA_3x_SOC)
Yudong Tanf8cd6292011-07-01 11:26:17 -0700286#ifdef CONFIG_TEGRA_SILICON_PLATFORM
Scott Williams1245c8e2011-01-05 17:53:39 -0800287 /* PL310 RAM latency is CPU dependent. NOTE: Changes here
288 must also be reflected in __cortex_a9_l2x0_restart */
289
290 if (is_lp_cluster()) {
291 writel(0x221, p + L2X0_TAG_LATENCY_CTRL);
292 writel(0x221, p + L2X0_DATA_LATENCY_CTRL);
293 } else {
Diwakar Tundlamf4ca2962011-12-02 15:49:42 -0800294 /* relax l2-cache latency for speedos 4,5,6 (T33's chips) */
295 speedo = tegra_cpu_speedo_id();
296 if (speedo == 4 || speedo == 5 || speedo == 6) {
297 writel(0x442, p + L2X0_TAG_LATENCY_CTRL);
298 writel(0x552, p + L2X0_DATA_LATENCY_CTRL);
299 } else {
300 writel(0x441, p + L2X0_TAG_LATENCY_CTRL);
301 writel(0x551, p + L2X0_DATA_LATENCY_CTRL);
302 }
Scott Williams1245c8e2011-01-05 17:53:39 -0800303 }
Yudong Tanf8cd6292011-07-01 11:26:17 -0700304#else
305 writel(0x770, p + L2X0_TAG_LATENCY_CTRL);
306 writel(0x770, p + L2X0_DATA_LATENCY_CTRL);
Scott Williams816ab052010-12-07 11:19:20 -0800307#endif
Scott Williams816ab052010-12-07 11:19:20 -0800308#endif
Krishna Reddy58eb2d02011-12-05 12:57:07 -0800309 aux_ctrl = readl(p + L2X0_CACHE_TYPE);
310 aux_ctrl = (aux_ctrl & 0x700) << (17-8);
311 aux_ctrl |= 0x7C000001;
Krishna Reddy1212eb82011-12-01 15:32:36 -0800312 if (init) {
Krishna Reddy1212eb82011-12-01 15:32:36 -0800313 l2x0_init(p, aux_ctrl, 0x8200c3fe);
Krishna Reddy58eb2d02011-12-05 12:57:07 -0800314 } else {
315 tmp = aux_ctrl;
316 aux_ctrl = readl(p + L2X0_AUX_CTRL);
317 aux_ctrl &= 0x8200c3fe;
318 aux_ctrl |= tmp;
319 writel(aux_ctrl, p + L2X0_AUX_CTRL);
Krishna Reddy1212eb82011-12-01 15:32:36 -0800320 }
Chris Johnson644d1fb2011-11-18 16:14:07 -0800321 l2x0_enable();
322#endif
Erik Gillingc5f80062010-01-21 16:53:02 -0800323#endif
324}
325
Dima Zavin7db7cbc2010-09-16 17:58:05 -0700326static void __init tegra_init_power(void)
327{
Scott Williams1a536c32011-09-01 16:20:47 -0700328#ifdef CONFIG_ARCH_TEGRA_HAS_SATA
Karan Jhavar49adefb2011-06-09 14:50:35 -0700329 tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_SATA);
Karan Jhavar93962282011-05-16 17:00:43 -0700330#endif
Scott Williams1a536c32011-09-01 16:20:47 -0700331#ifdef CONFIG_ARCH_TEGRA_HAS_PCIE
Karan Jhavar93962282011-05-16 17:00:43 -0700332 tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_PCIE);
Scott Williams1a536c32011-09-01 16:20:47 -0700333#endif
Dima Zavin7db7cbc2010-09-16 17:58:05 -0700334}
335
Rakesh Bodla1ad210a2011-05-31 15:18:00 +0530336static inline unsigned long gizmo_readl(unsigned long offset)
337{
338 return readl(IO_TO_VIRT(TEGRA_AHB_GIZMO_BASE + offset));
339}
340
341static inline void gizmo_writel(unsigned long value, unsigned long offset)
342{
343 writel(value, IO_TO_VIRT(TEGRA_AHB_GIZMO_BASE + offset));
344}
345
346static void __init tegra_init_ahb_gizmo_settings(void)
347{
348 unsigned long val;
349
350 val = gizmo_readl(AHB_GIZMO_AHB_MEM);
Jay Chengce4a7df2011-06-09 17:34:35 -0400351 val |= ENB_FAST_REARBITRATE | IMMEDIATE | DONT_SPLIT_AHB_WR;
Rakesh Bodla1ad210a2011-05-31 15:18:00 +0530352 gizmo_writel(val, AHB_GIZMO_AHB_MEM);
353
354 val = gizmo_readl(AHB_GIZMO_USB);
355 val |= IMMEDIATE;
356 gizmo_writel(val, AHB_GIZMO_USB);
357
358 val = gizmo_readl(AHB_GIZMO_USB2);
359 val |= IMMEDIATE;
360 gizmo_writel(val, AHB_GIZMO_USB2);
361
362 val = gizmo_readl(AHB_GIZMO_USB3);
363 val |= IMMEDIATE;
364 gizmo_writel(val, AHB_GIZMO_USB3);
365
366 val = gizmo_readl(AHB_ARBITRATION_PRIORITY_CTRL);
367 val |= PRIORITY_SELECT_USB | PRIORITY_SELECT_USB2 | PRIORITY_SELECT_USB3
368 | AHB_PRIORITY_WEIGHT(7);
369 gizmo_writel(val, AHB_ARBITRATION_PRIORITY_CTRL);
370
371 val = gizmo_readl(AHB_MEM_PREFETCH_CFG1);
372 val &= ~MST_ID(~0);
373 val |= PREFETCH_ENB | AHBDMA_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
374 gizmo_writel(val, AHB_MEM_PREFETCH_CFG1);
375
376 val = gizmo_readl(AHB_MEM_PREFETCH_CFG2);
377 val &= ~MST_ID(~0);
378 val |= PREFETCH_ENB | USB_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
379 gizmo_writel(val, AHB_MEM_PREFETCH_CFG2);
380
381 val = gizmo_readl(AHB_MEM_PREFETCH_CFG3);
382 val &= ~MST_ID(~0);
383 val |= PREFETCH_ENB | USB3_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
384 gizmo_writel(val, AHB_MEM_PREFETCH_CFG3);
385
386 val = gizmo_readl(AHB_MEM_PREFETCH_CFG4);
387 val &= ~MST_ID(~0);
388 val |= PREFETCH_ENB | USB2_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000);
389 gizmo_writel(val, AHB_MEM_PREFETCH_CFG4);
390}
391
Dima Zavin7e158ac2010-11-11 15:28:46 -0800392static bool console_flushed;
393
Bo Yan9f309002011-08-11 15:03:08 -0700394static void tegra_pm_flush_console(void)
Dima Zavin7e158ac2010-11-11 15:28:46 -0800395{
396 if (console_flushed)
Bo Yan9f309002011-08-11 15:03:08 -0700397 return;
Dima Zavin7e158ac2010-11-11 15:28:46 -0800398 console_flushed = true;
399
Dima Zavin7e158ac2010-11-11 15:28:46 -0800400 pr_emerg("Restarting %s\n", linux_banner);
Colin Crossfec84b22011-04-07 14:40:23 -0700401 if (console_trylock()) {
402 console_unlock();
Bo Yan9f309002011-08-11 15:03:08 -0700403 return;
Dima Zavin7e158ac2010-11-11 15:28:46 -0800404 }
405
406 mdelay(50);
407
408 local_irq_disable();
Colin Crossfec84b22011-04-07 14:40:23 -0700409 if (!console_trylock())
Mayuresh Kulkarniabce6622011-06-17 19:47:05 +0530410 pr_emerg("%s: Console was locked! Busting\n", __func__);
Dima Zavin7e158ac2010-11-11 15:28:46 -0800411 else
Mayuresh Kulkarniabce6622011-06-17 19:47:05 +0530412 pr_emerg("%s: Console was locked!\n", __func__);
Colin Crossfec84b22011-04-07 14:40:23 -0700413 console_unlock();
Dima Zavin7e158ac2010-11-11 15:28:46 -0800414}
415
Bo Yan9f309002011-08-11 15:03:08 -0700416static void tegra_pm_restart(char mode, const char *cmd)
417{
418 tegra_pm_flush_console();
419 arm_machine_restart(mode, cmd);
420}
Bo Yandf2009a2011-04-18 17:04:47 -0700421
Colin Cross0cf62302011-02-21 17:10:14 -0800422void __init tegra_init_early(void)
Erik Gillingc5f80062010-01-21 16:53:02 -0800423{
Bo Yan9f309002011-08-11 15:03:08 -0700424 arm_pm_restart = tegra_pm_restart;
Scott Williams55f67602011-07-27 20:10:06 -0700425#ifndef CONFIG_SMP
426 /* For SMP system, initializing the reset handler here is too
427 late. For non-SMP systems, the function that calls the reset
428 handler initializer is not called, so do it here for non-SMP. */
429 tegra_cpu_reset_handler_init();
430#endif
Colin Cross73625e32010-06-23 15:49:17 -0700431 tegra_init_fuse();
Colin Cross45a1ca02011-03-28 17:47:31 -0700432 tegra_gpio_resume_init();
Colin Crossd8611962010-01-28 16:40:29 -0800433 tegra_init_clock();
Colin Cross120c3562011-03-28 17:48:56 -0700434 tegra_init_pinmux();
Colin Crossd8611962010-01-28 16:40:29 -0800435 tegra_clk_init_from_table(common_clk_init_table);
Dima Zavin7db7cbc2010-09-16 17:58:05 -0700436 tegra_init_power();
Krishna Reddy1212eb82011-12-01 15:32:36 -0800437 tegra_init_cache(true);
Rakesh Bodla1ad210a2011-05-31 15:18:00 +0530438 tegra_init_ahb_gizmo_settings();
Erik Gillingc5f80062010-01-21 16:53:02 -0800439}
Colin Cross8e437c22010-11-28 22:36:08 -0800440
441static int __init tegra_lp0_vec_arg(char *options)
442{
443 char *p = options;
444
445 tegra_lp0_vec_size = memparse(p, &p);
446 if (*p == '@')
447 tegra_lp0_vec_start = memparse(p+1, &p);
Scott Williams03122532011-01-13 14:30:20 -0800448 if (!tegra_lp0_vec_size || !tegra_lp0_vec_start) {
449 tegra_lp0_vec_size = 0;
450 tegra_lp0_vec_start = 0;
451 }
Colin Cross8e437c22010-11-28 22:36:08 -0800452
453 return 0;
454}
455early_param("lp0_vec", tegra_lp0_vec_arg);
456
Colin Cross838d7d62010-10-19 14:45:50 -0700457static int __init tegra_bootloader_fb_arg(char *options)
458{
459 char *p = options;
460
461 tegra_bootloader_fb_size = memparse(p, &p);
462 if (*p == '@')
463 tegra_bootloader_fb_start = memparse(p+1, &p);
464
465 pr_info("Found tegra_fbmem: %08lx@%08lx\n",
466 tegra_bootloader_fb_size, tegra_bootloader_fb_start);
467
468 return 0;
469}
470early_param("tegra_fbmem", tegra_bootloader_fb_arg);
471
Krishna Reddyb7d5a862011-10-05 12:23:37 -0700472static int __init tegra_vpr_arg(char *options)
473{
474 char *p = options;
475
476 tegra_vpr_size = memparse(p, &p);
477 if (*p == '@')
478 tegra_vpr_start = memparse(p+1, &p);
479 pr_info("Found vpr, start=0x%lx size=%lx",
480 tegra_vpr_start, tegra_vpr_size);
Colin Patrick McCabe997f4282011-11-09 13:44:27 -0800481 return 0;
Krishna Reddyb7d5a862011-10-05 12:23:37 -0700482}
483early_param("vpr", tegra_vpr_arg);
484
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530485enum panel_type get_panel_type(void)
486{
487 return board_panel_type;
488}
489static int __init tegra_board_panel_type(char *options)
490{
491 if (!strcmp(options, "lvds"))
492 board_panel_type = panel_type_lvds;
493 else if (!strcmp(options, "dsi"))
494 board_panel_type = panel_type_dsi;
495 else
496 return 0;
497 return 1;
498}
499__setup("panel=", tegra_board_panel_type);
500
Laxman Dewangan8644fc02011-09-04 17:10:13 +0530501enum power_supply_type get_power_supply_type(void)
502{
503 return pow_supply_type;
504}
505static int __init tegra_board_power_supply_type(char *options)
506{
507 if (!strcmp(options, "Adapter"))
508 pow_supply_type = POWER_SUPPLY_TYPE_MAINS;
509 if (!strcmp(options, "Mains"))
510 pow_supply_type = POWER_SUPPLY_TYPE_MAINS;
511 else if (!strcmp(options, "Battery"))
512 pow_supply_type = POWER_SUPPLY_TYPE_BATTERY;
513 else
514 return 0;
515 return 1;
516}
517__setup("power_supply=", tegra_board_power_supply_type);
518
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530519int get_core_edp(void)
520{
521 return pmu_core_edp;
522}
523static int __init tegra_pmu_core_edp(char *options)
524{
525 char *p = options;
Alex Frid3a5fc7c2011-05-11 16:01:44 -0700526 int core_edp = memparse(p, &p);
527 if (core_edp != 0)
528 pmu_core_edp = core_edp;
Deepesh Gujarathi9f73e312011-10-07 15:18:30 +0530529 return 0;
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530530}
Deepesh Gujarathiab7815e2011-09-15 13:57:02 +0530531early_param("core_edp_mv", tegra_pmu_core_edp);
Laxman Dewanganb1a6ea22011-05-09 19:15:29 +0530532
Laxman Dewangan1f8be3d2011-10-15 15:44:04 +0530533int get_maximum_cpu_current_supported(void)
534{
535 return max_cpu_current;
536}
537static int __init tegra_max_cpu_current(char *options)
538{
539 char *p = options;
540 max_cpu_current = memparse(p, &p);
541 return 1;
542}
543__setup("max_cpu_cur_ma=", tegra_max_cpu_current);
544
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530545static int __init tegra_debug_uartport(char *info)
546{
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530547 char *p = info;
Laxman Dewanganc032ab22011-09-28 14:42:49 +0530548 unsigned long long port_id;
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530549 if (!strncmp(p, "hsport", 6))
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530550 is_tegra_debug_uart_hsport = true;
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530551 else if (!strncmp(p, "lsport", 6))
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530552 is_tegra_debug_uart_hsport = false;
553
Laxman Dewanganc032ab22011-09-28 14:42:49 +0530554 if (p[6] == ',') {
555 if (p[7] == '-') {
556 debug_uart_port_id = -1;
557 } else {
558 port_id = memparse(p + 7, &p);
559 debug_uart_port_id = (int) port_id;
560 }
561 } else {
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530562 debug_uart_port_id = -1;
Laxman Dewanganc032ab22011-09-28 14:42:49 +0530563 }
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530564
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530565 return 1;
566}
567
568bool is_tegra_debug_uartport_hs(void)
569{
570 return is_tegra_debug_uart_hsport;
571}
572
Laxman Dewangan6c6ba1b2011-09-08 19:36:17 +0530573int get_tegra_uart_debug_port_id(void)
574{
575 return debug_uart_port_id;
576}
Pradeep Goudagunta3dd04c42011-03-23 23:16:12 +0530577__setup("debug_uartport=", tegra_debug_uartport);
578
Laxman Dewangan57b08762011-09-18 16:49:10 +0530579static int __init tegra_audio_codec_type(char *info)
580{
581 char *p = info;
582 if (!strncmp(p, "wm8903", 6))
583 audio_codec_name = audio_codec_wm8903;
584 else
585 audio_codec_name = audio_codec_none;
586
587 return 1;
588}
589
590enum audio_codec_type get_audio_codec_type(void)
591{
592 return audio_codec_name;
593}
594__setup("audio_codec=", tegra_audio_codec_type);
595
596
Nitin Kumbhar637ced42010-12-10 15:16:37 +0530597void tegra_get_board_info(struct board_info *bi)
598{
Laxman Dewanganc0f18022011-02-05 16:26:42 +0530599 bi->board_id = (system_serial_high >> 16) & 0xFFFF;
600 bi->sku = (system_serial_high) & 0xFFFF;
601 bi->fab = (system_serial_low >> 24) & 0xFF;
602 bi->major_revision = (system_serial_low >> 16) & 0xFF;
603 bi->minor_revision = (system_serial_low >> 8) & 0xFF;
Nitin Kumbhar637ced42010-12-10 15:16:37 +0530604}
605
Laxman Dewangan87d07ce2011-06-15 00:48:57 +0530606static int __init tegra_pmu_board_info(char *info)
607{
608 char *p = info;
609 pmu_board_info.board_id = memparse(p, &p);
610 pmu_board_info.sku = memparse(p+1, &p);
611 pmu_board_info.fab = memparse(p+1, &p);
612 pmu_board_info.major_revision = memparse(p+1, &p);
613 pmu_board_info.minor_revision = memparse(p+1, &p);
614 return 1;
615}
616
617void tegra_get_pmu_board_info(struct board_info *bi)
618{
619 memcpy(bi, &pmu_board_info, sizeof(struct board_info));
620}
621
622__setup("pmuboard=", tegra_pmu_board_info);
623
Hyungwoo Yang187ada82011-10-24 15:06:17 -0700624static int __init tegra_display_board_info(char *info)
625{
626 char *p = info;
627 display_board_info.board_id = memparse(p, &p);
628 display_board_info.sku = memparse(p+1, &p);
629 display_board_info.fab = memparse(p+1, &p);
630 display_board_info.major_revision = memparse(p+1, &p);
631 display_board_info.minor_revision = memparse(p+1, &p);
632 return 1;
633}
634
635void tegra_get_display_board_info(struct board_info *bi)
636{
637 memcpy(bi, &display_board_info, sizeof(struct board_info));
638}
639
640__setup("displayboard=", tegra_display_board_info);
641
Jihoon Bangea8fd162011-12-12 11:00:14 -0800642static int __init tegra_camera_board_info(char *info)
643{
644 char *p = info;
645 camera_board_info.board_id = memparse(p, &p);
646 camera_board_info.sku = memparse(p+1, &p);
647 camera_board_info.fab = memparse(p+1, &p);
648 camera_board_info.major_revision = memparse(p+1, &p);
649 camera_board_info.minor_revision = memparse(p+1, &p);
650 return 1;
651}
652
653void tegra_get_camera_board_info(struct board_info *bi)
654{
655 memcpy(bi, &camera_board_info, sizeof(struct board_info));
656}
657
658__setup("cameraboard=", tegra_camera_board_info);
659
Steve Lind2f4e4d2011-07-11 12:45:06 -0700660static int __init tegra_modem_id(char *id)
661{
662 char *p = id;
663
664 modem_id = memparse(p, &p);
665 return 1;
666}
667
668int tegra_get_modem_id(void)
669{
670 return modem_id;
671}
672
673__setup("modem_id=", tegra_modem_id);
Laxman Dewangan87d07ce2011-06-15 00:48:57 +0530674
Jihoon Bangea8fd162011-12-12 11:00:14 -0800675
676
Colin Crossf9c9bde2010-10-19 16:12:33 -0700677/*
678 * Tegra has a protected aperture that prevents access by most non-CPU
679 * memory masters to addresses above the aperture value. Enabling it
680 * secures the CPU's memory from the GPU, except through the GART.
681 */
682void __init tegra_protected_aperture_init(unsigned long aperture)
683{
684#ifndef CONFIG_NVMAP_ALLOW_SYSMEM
685 void __iomem *mc_base = IO_ADDRESS(TEGRA_MC_BASE);
686 pr_info("Enabling Tegra protected aperture at 0x%08lx\n", aperture);
687 writel(aperture, mc_base + MC_SECURITY_CFG2);
688#else
689 pr_err("Tegra protected aperture disabled because nvmap is using "
690 "system memory\n");
691#endif
692}
693
Colin Cross115467a2010-10-19 21:09:29 -0700694/*
695 * Due to conflicting restrictions on the placement of the framebuffer,
696 * the bootloader is likely to leave the framebuffer pointed at a location
697 * in memory that is outside the grhost aperture. This function will move
698 * the framebuffer contents from a physical address that is anywher (lowmem,
699 * highmem, or outside the memory map) to a physical address that is outside
700 * the memory map.
701 */
702void tegra_move_framebuffer(unsigned long to, unsigned long from,
703 unsigned long size)
704{
705 struct page *page;
706 void __iomem *to_io;
707 void *from_virt;
708 unsigned long i;
709
710 BUG_ON(PAGE_ALIGN((unsigned long)to) != (unsigned long)to);
711 BUG_ON(PAGE_ALIGN(from) != from);
712 BUG_ON(PAGE_ALIGN(size) != size);
713
714 to_io = ioremap(to, size);
715 if (!to_io) {
716 pr_err("%s: Failed to map target framebuffer\n", __func__);
717 return;
718 }
719
Colin Cross115467a2010-10-19 21:09:29 -0700720 if (pfn_valid(page_to_pfn(phys_to_page(from)))) {
721 for (i = 0 ; i < size; i += PAGE_SIZE) {
722 page = phys_to_page(from + i);
723 from_virt = kmap(page);
Jon Mayoa8553a42011-08-29 18:09:16 -0700724 memcpy(to_io + i, from_virt, PAGE_SIZE);
Colin Cross115467a2010-10-19 21:09:29 -0700725 kunmap(page);
726 }
727 } else {
728 void __iomem *from_io = ioremap(from, size);
729 if (!from_io) {
730 pr_err("%s: Failed to map source framebuffer\n",
731 __func__);
732 goto out;
733 }
734
Kevin Huangece493d2011-07-05 18:27:43 -0700735 for (i = 0; i < size; i += 4)
Colin Cross115467a2010-10-19 21:09:29 -0700736 writel(readl(from_io + i), to_io + i);
737
738 iounmap(from_io);
739 }
740out:
741 iounmap(to_io);
742}
743
Hiro Sugawara510eb102011-12-13 09:12:26 -0800744#ifdef CONFIG_TEGRA_SMMU_BASE_AT_E0000000
745#define FORCE_SMMU_BASE_FOR_TEGRA3_A01 1
746#else
747#define FORCE_SMMU_BASE_FOR_TEGRA3_A01 0
748#endif
749#if FORCE_SMMU_BASE_FOR_TEGRA3_A01 || \
750 (defined(CONFIG_TEGRA_IOVMM_SMMU) && defined(CONFIG_ARCH_TEGRA_3x_SOC))
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700751/* Support for Tegra3 A01 chip mask that needs to have SMMU IOVA reside in
752 * the upper half of 4GB IOVA space. A02 and after use the bottom 1GB and
753 * do not need to reserve memory.
754 */
Hiro Sugawara510eb102011-12-13 09:12:26 -0800755#define SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700756#endif
757
Colin Cross838d7d62010-10-19 14:45:50 -0700758void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size,
759 unsigned long fb2_size)
760{
Hiro Sugawara510eb102011-12-13 09:12:26 -0800761#ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700762 int smmu_reserved = 0;
Hiro Sugawara10f14812011-09-13 17:20:35 -0700763 struct tegra_smmu_window *smmu_window = tegra_smmu_window(0);
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700764#endif
Colin Cross838d7d62010-10-19 14:45:50 -0700765
Scott Williams03122532011-01-13 14:30:20 -0800766 if (carveout_size) {
767 tegra_carveout_start = memblock_end_of_DRAM() - carveout_size;
768 if (memblock_remove(tegra_carveout_start, carveout_size)) {
769 pr_err("Failed to remove carveout %08lx@%08lx "
770 "from memory map\n",
Hiro Sugawara5cb430a2011-03-10 15:19:03 -0800771 carveout_size, tegra_carveout_start);
Scott Williams03122532011-01-13 14:30:20 -0800772 tegra_carveout_start = 0;
773 tegra_carveout_size = 0;
Kevin Huangece493d2011-07-05 18:27:43 -0700774 } else
Scott Williams03122532011-01-13 14:30:20 -0800775 tegra_carveout_size = carveout_size;
776 }
Colin Cross838d7d62010-10-19 14:45:50 -0700777
Scott Williams03122532011-01-13 14:30:20 -0800778 if (fb2_size) {
779 tegra_fb2_start = memblock_end_of_DRAM() - fb2_size;
780 if (memblock_remove(tegra_fb2_start, fb2_size)) {
Kevin Huangece493d2011-07-05 18:27:43 -0700781 pr_err("Failed to remove second framebuffer "
782 "%08lx@%08lx from memory map\n",
Hiro Sugawaradc1d2812011-04-29 11:59:37 -0700783 fb2_size, tegra_fb2_start);
Scott Williams03122532011-01-13 14:30:20 -0800784 tegra_fb2_start = 0;
785 tegra_fb2_size = 0;
786 } else
787 tegra_fb2_size = fb2_size;
788 }
Colin Cross838d7d62010-10-19 14:45:50 -0700789
Scott Williams03122532011-01-13 14:30:20 -0800790 if (fb_size) {
791 tegra_fb_start = memblock_end_of_DRAM() - fb_size;
792 if (memblock_remove(tegra_fb_start, fb_size)) {
793 pr_err("Failed to remove framebuffer %08lx@%08lx "
794 "from memory map\n",
Hiro Sugawara5cb430a2011-03-10 15:19:03 -0800795 fb_size, tegra_fb_start);
Scott Williams03122532011-01-13 14:30:20 -0800796 tegra_fb_start = 0;
797 tegra_fb_size = 0;
798 } else
799 tegra_fb_size = fb_size;
800 }
Colin Cross838d7d62010-10-19 14:45:50 -0700801
Colin Crossf9c9bde2010-10-19 16:12:33 -0700802 if (tegra_fb_size)
803 tegra_grhost_aperture = tegra_fb_start;
804
805 if (tegra_fb2_size && tegra_fb2_start < tegra_grhost_aperture)
806 tegra_grhost_aperture = tegra_fb2_start;
807
808 if (tegra_carveout_size && tegra_carveout_start < tegra_grhost_aperture)
809 tegra_grhost_aperture = tegra_carveout_start;
810
Hiro Sugawara510eb102011-12-13 09:12:26 -0800811#ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700812 if (!smmu_window) {
Hiro Sugawara10f14812011-09-13 17:20:35 -0700813 pr_err("No SMMU resource\n");
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700814 } else {
Hiro Sugawara0d218182011-04-08 13:21:02 -0700815 size_t smmu_window_size;
816
Hiro Sugawara510eb102011-12-13 09:12:26 -0800817 if (FORCE_SMMU_BASE_FOR_TEGRA3_A01 ||
818 (tegra_get_chipid() == TEGRA_CHIPID_TEGRA3 &&
819 tegra_get_revision() == TEGRA_REVISION_A01)) {
820 smmu_window->start = TEGRA_SMMU_BASE_TEGRA3_A01;
821 smmu_window->end = TEGRA_SMMU_BASE_TEGRA3_A01 +
822 TEGRA_SMMU_SIZE_TEGRA3_A01 - 1;
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700823 }
824 smmu_window_size = smmu_window->end + 1 - smmu_window->start;
825 if (smmu_window->start >= 0x80000000) {
826 if (memblock_reserve(smmu_window->start,
827 smmu_window_size))
828 pr_err(
829 "Failed to reserve SMMU I/O VA window %08lx@%08lx\n",
Hiro Sugawara0d218182011-04-08 13:21:02 -0700830 (unsigned long)smmu_window_size,
831 (unsigned long)smmu_window->start);
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700832 else
833 smmu_reserved = 1;
834 }
Scott Williams599c1122011-02-10 14:35:32 -0800835 }
836#endif
837
Prashant Gaikwadff192312011-08-03 14:49:20 +0530838 if (tegra_lp0_vec_size &&
839 (tegra_lp0_vec_start < memblock_end_of_DRAM())) {
840 if (memblock_reserve(tegra_lp0_vec_start, tegra_lp0_vec_size)) {
841 pr_err("Failed to reserve lp0_vec %08lx@%08lx\n",
842 tegra_lp0_vec_size, tegra_lp0_vec_start);
843 tegra_lp0_vec_start = 0;
844 tegra_lp0_vec_size = 0;
845 }
846 tegra_lp0_vec_relocate = false;
847 } else
848 tegra_lp0_vec_relocate = true;
849
Colin Cross838d7d62010-10-19 14:45:50 -0700850 /*
Kevin Huangece493d2011-07-05 18:27:43 -0700851 * We copy the bootloader's framebuffer to the framebuffer allocated
852 * above, and then free this one.
853 * */
854 if (tegra_bootloader_fb_size) {
855 tegra_bootloader_fb_size = PAGE_ALIGN(tegra_bootloader_fb_size);
Colin Cross838d7d62010-10-19 14:45:50 -0700856 if (memblock_reserve(tegra_bootloader_fb_start,
Scott Williams03122532011-01-13 14:30:20 -0800857 tegra_bootloader_fb_size)) {
Kevin Huangece493d2011-07-05 18:27:43 -0700858 pr_err("Failed to reserve bootloader frame buffer "
859 "%08lx@%08lx\n", tegra_bootloader_fb_size,
860 tegra_bootloader_fb_start);
Scott Williams03122532011-01-13 14:30:20 -0800861 tegra_bootloader_fb_start = 0;
862 tegra_bootloader_fb_size = 0;
863 }
Kevin Huangece493d2011-07-05 18:27:43 -0700864 }
Colin Cross838d7d62010-10-19 14:45:50 -0700865
866 pr_info("Tegra reserved memory:\n"
867 "LP0: %08lx - %08lx\n"
868 "Bootloader framebuffer: %08lx - %08lx\n"
869 "Framebuffer: %08lx - %08lx\n"
Scott Williams22d51692011-01-11 10:50:52 -0800870 "2nd Framebuffer: %08lx - %08lx\n"
Krishna Reddyb7d5a862011-10-05 12:23:37 -0700871 "Carveout: %08lx - %08lx\n"
872 "Vpr: %08lx - %08lx\n",
Colin Cross838d7d62010-10-19 14:45:50 -0700873 tegra_lp0_vec_start,
Scott Williams03122532011-01-13 14:30:20 -0800874 tegra_lp0_vec_size ?
875 tegra_lp0_vec_start + tegra_lp0_vec_size - 1 : 0,
Colin Cross838d7d62010-10-19 14:45:50 -0700876 tegra_bootloader_fb_start,
Scott Williams03122532011-01-13 14:30:20 -0800877 tegra_bootloader_fb_size ?
878 tegra_bootloader_fb_start + tegra_bootloader_fb_size - 1 : 0,
Colin Cross838d7d62010-10-19 14:45:50 -0700879 tegra_fb_start,
Scott Williams03122532011-01-13 14:30:20 -0800880 tegra_fb_size ?
881 tegra_fb_start + tegra_fb_size - 1 : 0,
Colin Cross838d7d62010-10-19 14:45:50 -0700882 tegra_fb2_start,
Scott Williams03122532011-01-13 14:30:20 -0800883 tegra_fb2_size ?
884 tegra_fb2_start + tegra_fb2_size - 1 : 0,
Colin Cross838d7d62010-10-19 14:45:50 -0700885 tegra_carveout_start,
Scott Williams03122532011-01-13 14:30:20 -0800886 tegra_carveout_size ?
Krishna Reddyb7d5a862011-10-05 12:23:37 -0700887 tegra_carveout_start + tegra_carveout_size - 1 : 0,
888 tegra_vpr_start,
889 tegra_vpr_size ?
890 tegra_vpr_start + tegra_vpr_size - 1 : 0);
Scott Williams599c1122011-02-10 14:35:32 -0800891
Hiro Sugawara510eb102011-12-13 09:12:26 -0800892#ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700893 if (smmu_reserved)
Hiro Sugawara10f14812011-09-13 17:20:35 -0700894 pr_info("SMMU: %08lx - %08lx\n",
Hiro Sugawarad5ea29e2011-03-17 11:19:29 -0700895 smmu_window->start, smmu_window->end);
Scott Williams599c1122011-02-10 14:35:32 -0800896#endif
Colin Cross838d7d62010-10-19 14:45:50 -0700897}
Kevin Huangece493d2011-07-05 18:27:43 -0700898
Haley Teng290e96f2011-09-27 12:20:32 +0800899static struct resource ram_console_resources[] = {
900 {
901 .flags = IORESOURCE_MEM,
902 },
903};
904
905static struct platform_device ram_console_device = {
906 .name = "ram_console",
907 .id = -1,
908 .num_resources = ARRAY_SIZE(ram_console_resources),
909 .resource = ram_console_resources,
910};
911
912void __init tegra_ram_console_debug_reserve(unsigned long ram_console_size)
913{
914 struct resource *res;
915 long ret;
916
917 res = platform_get_resource(&ram_console_device, IORESOURCE_MEM, 0);
918 if (!res)
919 goto fail;
920 res->start = memblock_end_of_DRAM() - ram_console_size;
921 res->end = res->start + ram_console_size - 1;
922 ret = memblock_remove(res->start, ram_console_size);
923 if (ret)
924 goto fail;
925
926 return;
927
928fail:
929 ram_console_device.resource = NULL;
930 ram_console_device.num_resources = 0;
931 pr_err("Failed to reserve memory block for ram console\n");
932}
933
934void __init tegra_ram_console_debug_init(void)
935{
936 int err;
937
938 err = platform_device_register(&ram_console_device);
939 if (err) {
940 pr_err("%s: ram console registration failed (%d)!\n", __func__, err);
941 }
942}
943
Kevin Huangece493d2011-07-05 18:27:43 -0700944void __init tegra_release_bootloader_fb(void)
945{
946 /* Since bootloader fb is reserved in common.c, it is freed here. */
947 if (tegra_bootloader_fb_size)
948 if (memblock_free(tegra_bootloader_fb_start,
949 tegra_bootloader_fb_size))
950 pr_err("Failed to free bootloader fb.\n");
951}
Victor(Weiguo) Pan5ab70782011-08-23 14:48:30 -0700952
Bharat Nihalani50e7bec2011-05-19 20:09:14 +0530953#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
Wen Yifd9bfde2011-04-18 14:21:25 -0700954static char cpufreq_gov_default[32];
955static char *cpufreq_gov_conservative = "conservative";
956static char *cpufreq_sysfs_place_holder="/sys/devices/system/cpu/cpu%i/cpufreq/scaling_governor";
Wen Yi10027352011-06-06 13:51:12 -0700957static char *cpufreq_gov_conservative_param="/sys/devices/system/cpu/cpufreq/conservative/%s";
Wen Yifd9bfde2011-04-18 14:21:25 -0700958
959static void cpufreq_set_governor(char *governor)
960{
961 struct file *scaling_gov = NULL;
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -0700962 mm_segment_t old_fs;
Wen Yifd9bfde2011-04-18 14:21:25 -0700963 char buf[128];
Sang-Hun Lee00535522011-12-22 11:06:29 -0800964 int i = 0;
Wen Yifd9bfde2011-04-18 14:21:25 -0700965 loff_t offset = 0;
966
967 if (governor == NULL)
968 return;
969
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -0700970 /* change to KERNEL_DS address limit */
971 old_fs = get_fs();
972 set_fs(KERNEL_DS);
Prashant Gaikwad8d1e39c2011-12-26 16:41:29 +0530973#ifndef CONFIG_TEGRA_AUTO_HOTPLUG
Sang-Hun Lee00535522011-12-22 11:06:29 -0800974 for_each_online_cpu(i)
975#endif
976 {
Wen Yifd9bfde2011-04-18 14:21:25 -0700977 sprintf(buf, cpufreq_sysfs_place_holder, i);
978 scaling_gov = filp_open(buf, O_RDWR, 0);
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -0700979 if (IS_ERR_OR_NULL(scaling_gov)) {
980 pr_err("%s. Can't open %s\n", __func__, buf);
981 } else {
Wen Yifd9bfde2011-04-18 14:21:25 -0700982 if (scaling_gov->f_op != NULL &&
983 scaling_gov->f_op->write != NULL)
984 scaling_gov->f_op->write(scaling_gov,
985 governor,
986 strlen(governor),
987 &offset);
988 else
989 pr_err("f_op might be null\n");
990
991 filp_close(scaling_gov, NULL);
Wen Yifd9bfde2011-04-18 14:21:25 -0700992 }
993 }
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -0700994 set_fs(old_fs);
Wen Yifd9bfde2011-04-18 14:21:25 -0700995}
996
997void cpufreq_save_default_governor(void)
998{
999 struct file *scaling_gov = NULL;
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001000 mm_segment_t old_fs;
Wen Yifd9bfde2011-04-18 14:21:25 -07001001 char buf[128];
1002 loff_t offset = 0;
1003
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001004 /* change to KERNEL_DS address limit */
1005 old_fs = get_fs();
1006 set_fs(KERNEL_DS);
1007
Wen Yifd9bfde2011-04-18 14:21:25 -07001008 buf[127] = 0;
1009 sprintf(buf, cpufreq_sysfs_place_holder,0);
1010 scaling_gov = filp_open(buf, O_RDONLY, 0);
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001011 if (IS_ERR_OR_NULL(scaling_gov)) {
1012 pr_err("%s. Can't open %s\n", __func__, buf);
1013 } else {
Wen Yifd9bfde2011-04-18 14:21:25 -07001014 if (scaling_gov->f_op != NULL &&
1015 scaling_gov->f_op->read != NULL)
1016 scaling_gov->f_op->read(scaling_gov,
1017 cpufreq_gov_default,
Wen Yi10027352011-06-06 13:51:12 -07001018 32,
Wen Yifd9bfde2011-04-18 14:21:25 -07001019 &offset);
1020 else
1021 pr_err("f_op might be null\n");
1022
1023 filp_close(scaling_gov, NULL);
Wen Yifd9bfde2011-04-18 14:21:25 -07001024 }
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001025 set_fs(old_fs);
Wen Yifd9bfde2011-04-18 14:21:25 -07001026}
1027
1028void cpufreq_restore_default_governor(void)
1029{
1030 cpufreq_set_governor(cpufreq_gov_default);
1031}
1032
Wen Yi10027352011-06-06 13:51:12 -07001033void cpufreq_set_conservative_governor_param(int up_th, int down_th)
1034{
1035 struct file *gov_param = NULL;
1036 static char buf[128],parm[8];
1037 loff_t offset = 0;
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001038 mm_segment_t old_fs;
Wen Yi10027352011-06-06 13:51:12 -07001039
1040 if (up_th <= down_th) {
1041 printk(KERN_ERR "%s: up_th(%d) is lesser than down_th(%d)\n",
1042 __func__, up_th, down_th);
1043 return;
1044 }
1045
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001046 /* change to KERNEL_DS address limit */
1047 old_fs = get_fs();
1048 set_fs(KERNEL_DS);
1049
Wen Yi10027352011-06-06 13:51:12 -07001050 sprintf(parm, "%d", up_th);
1051 sprintf(buf, cpufreq_gov_conservative_param ,"up_threshold");
1052 gov_param = filp_open(buf, O_RDONLY, 0);
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001053 if (IS_ERR_OR_NULL(gov_param)) {
1054 pr_err("%s. Can't open %s\n", __func__, buf);
1055 } else {
Wen Yi10027352011-06-06 13:51:12 -07001056 if (gov_param->f_op != NULL &&
1057 gov_param->f_op->write != NULL)
1058 gov_param->f_op->write(gov_param,
1059 parm,
1060 strlen(parm),
1061 &offset);
1062 else
1063 pr_err("f_op might be null\n");
1064
1065 filp_close(gov_param, NULL);
Wen Yi10027352011-06-06 13:51:12 -07001066 }
1067
1068 sprintf(parm, "%d", down_th);
1069 sprintf(buf, cpufreq_gov_conservative_param ,"down_threshold");
1070 gov_param = filp_open(buf, O_RDONLY, 0);
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001071 if (IS_ERR_OR_NULL(gov_param)) {
1072 pr_err("%s. Can't open %s\n", __func__, buf);
1073 } else {
Wen Yi10027352011-06-06 13:51:12 -07001074 if (gov_param->f_op != NULL &&
1075 gov_param->f_op->write != NULL)
1076 gov_param->f_op->write(gov_param,
1077 parm,
1078 strlen(parm),
1079 &offset);
1080 else
1081 pr_err("f_op might be null\n");
1082
1083 filp_close(gov_param, NULL);
Wen Yi10027352011-06-06 13:51:12 -07001084 }
Victor(Weiguo) Pan2dbf0712011-08-23 14:48:30 -07001085 set_fs(old_fs);
Wen Yi10027352011-06-06 13:51:12 -07001086}
1087
Wen Yifd9bfde2011-04-18 14:21:25 -07001088void cpufreq_set_conservative_governor(void)
1089{
1090 cpufreq_set_governor(cpufreq_gov_conservative);
1091}
Bharat Nihalani50e7bec2011-05-19 20:09:14 +05301092#endif /* CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND */