diff options
Diffstat (limited to 'arch/arm/mach-tegra/common.c')
-rw-r--r-- | arch/arm/mach-tegra/common.c | 1051 |
1 files changed, 1040 insertions, 11 deletions
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c index d5e3f89b05a..36a9f8781b6 100644 --- a/arch/arm/mach-tegra/common.c +++ b/arch/arm/mach-tegra/common.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * arch/arm/mach-tegra/board-harmony.c | 2 | * arch/arm/mach-tegra/common.c |
3 | * | 3 | * |
4 | * Copyright (C) 2010 Google, Inc. | 4 | * Copyright (C) 2010 Google, Inc. |
5 | * Copyright (C) 2010-2012 NVIDIA Corporation | ||
5 | * | 6 | * |
6 | * Author: | 7 | * Author: |
7 | * Colin Cross <ccross@android.com> | 8 | * Colin Cross <ccross@android.com> |
@@ -17,67 +18,1095 @@ | |||
17 | * | 18 | * |
18 | */ | 19 | */ |
19 | 20 | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/console.h> | ||
20 | #include <linux/init.h> | 23 | #include <linux/init.h> |
21 | #include <linux/io.h> | 24 | #include <linux/io.h> |
22 | #include <linux/clk.h> | 25 | #include <linux/clk.h> |
23 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/highmem.h> | ||
28 | #include <linux/memblock.h> | ||
29 | #include <linux/bitops.h> | ||
30 | #include <linux/sched.h> | ||
24 | 31 | ||
25 | #include <asm/hardware/cache-l2x0.h> | 32 | #include <asm/hardware/cache-l2x0.h> |
33 | #include <asm/system.h> | ||
26 | 34 | ||
35 | #include <mach/gpio.h> | ||
27 | #include <mach/iomap.h> | 36 | #include <mach/iomap.h> |
37 | #include <mach/pinmux.h> | ||
38 | #include <mach/powergate.h> | ||
28 | #include <mach/system.h> | 39 | #include <mach/system.h> |
40 | #include <mach/tegra_smmu.h> | ||
29 | 41 | ||
42 | #include "apbio.h" | ||
30 | #include "board.h" | 43 | #include "board.h" |
31 | #include "clock.h" | 44 | #include "clock.h" |
32 | #include "fuse.h" | 45 | #include "fuse.h" |
46 | #include "pm.h" | ||
47 | #include "reset.h" | ||
48 | #include "devices.h" | ||
49 | |||
50 | #define MC_SECURITY_CFG2 0x7c | ||
51 | |||
52 | #define AHB_ARBITRATION_PRIORITY_CTRL 0x4 | ||
53 | #define AHB_PRIORITY_WEIGHT(x) (((x) & 0x7) << 29) | ||
54 | #define PRIORITY_SELECT_USB BIT(6) | ||
55 | #define PRIORITY_SELECT_USB2 BIT(18) | ||
56 | #define PRIORITY_SELECT_USB3 BIT(17) | ||
57 | |||
58 | #define AHB_GIZMO_AHB_MEM 0xc | ||
59 | #define ENB_FAST_REARBITRATE BIT(2) | ||
60 | #define DONT_SPLIT_AHB_WR BIT(7) | ||
61 | |||
62 | #define RECOVERY_MODE BIT(31) | ||
63 | #define BOOTLOADER_MODE BIT(30) | ||
64 | #define FORCED_RECOVERY_MODE BIT(1) | ||
65 | |||
66 | #define AHB_GIZMO_USB 0x1c | ||
67 | #define AHB_GIZMO_USB2 0x78 | ||
68 | #define AHB_GIZMO_USB3 0x7c | ||
69 | #define IMMEDIATE BIT(18) | ||
70 | |||
71 | #define AHB_MEM_PREFETCH_CFG3 0xe0 | ||
72 | #define AHB_MEM_PREFETCH_CFG4 0xe4 | ||
73 | #define AHB_MEM_PREFETCH_CFG1 0xec | ||
74 | #define AHB_MEM_PREFETCH_CFG2 0xf0 | ||
75 | #define PREFETCH_ENB BIT(31) | ||
76 | #define MST_ID(x) (((x) & 0x1f) << 26) | ||
77 | #define AHBDMA_MST_ID MST_ID(5) | ||
78 | #define USB_MST_ID MST_ID(6) | ||
79 | #define USB2_MST_ID MST_ID(18) | ||
80 | #define USB3_MST_ID MST_ID(17) | ||
81 | #define ADDR_BNDRY(x) (((x) & 0xf) << 21) | ||
82 | #define INACTIVITY_TIMEOUT(x) (((x) & 0xffff) << 0) | ||
83 | |||
84 | unsigned long tegra_bootloader_fb_start; | ||
85 | unsigned long tegra_bootloader_fb_size; | ||
86 | unsigned long tegra_fb_start; | ||
87 | unsigned long tegra_fb_size; | ||
88 | unsigned long tegra_fb2_start; | ||
89 | unsigned long tegra_fb2_size; | ||
90 | unsigned long tegra_carveout_start; | ||
91 | unsigned long tegra_carveout_size; | ||
92 | unsigned long tegra_vpr_start; | ||
93 | unsigned long tegra_vpr_size; | ||
94 | unsigned long tegra_lp0_vec_start; | ||
95 | unsigned long tegra_lp0_vec_size; | ||
96 | bool tegra_lp0_vec_relocate; | ||
97 | unsigned long tegra_grhost_aperture = ~0ul; | ||
98 | static bool is_tegra_debug_uart_hsport; | ||
99 | static struct board_info pmu_board_info; | ||
100 | static struct board_info display_board_info; | ||
101 | static struct board_info camera_board_info; | ||
102 | |||
103 | static int pmu_core_edp = 1200; /* default 1.2V EDP limit */ | ||
104 | static int board_panel_type; | ||
105 | static enum power_supply_type pow_supply_type = POWER_SUPPLY_TYPE_MAINS; | ||
33 | 106 | ||
34 | void (*arch_reset)(char mode, const char *cmd) = tegra_assert_system_reset; | 107 | void (*arch_reset)(char mode, const char *cmd) = tegra_assert_system_reset; |
35 | 108 | ||
109 | #define NEVER_RESET 0 | ||
110 | |||
36 | void tegra_assert_system_reset(char mode, const char *cmd) | 111 | void tegra_assert_system_reset(char mode, const char *cmd) |
37 | { | 112 | { |
38 | void __iomem *reset = IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x04); | 113 | #if defined(CONFIG_TEGRA_FPGA_PLATFORM) || NEVER_RESET |
114 | printk("tegra_assert_system_reset() ignored....."); | ||
115 | do { } while (1); | ||
116 | #else | ||
117 | void __iomem *reset = IO_ADDRESS(TEGRA_PMC_BASE + 0x00); | ||
39 | u32 reg; | 118 | u32 reg; |
40 | 119 | ||
120 | reg = readl_relaxed(reset + PMC_SCRATCH0); | ||
121 | /* Writing recovery kernel or Bootloader mode in SCRATCH0 31:30:1 */ | ||
122 | if (cmd) { | ||
123 | if (!strcmp(cmd, "recovery")) | ||
124 | reg |= RECOVERY_MODE; | ||
125 | else if (!strcmp(cmd, "bootloader")) | ||
126 | reg |= BOOTLOADER_MODE; | ||
127 | else if (!strcmp(cmd, "forced-recovery")) | ||
128 | reg |= FORCED_RECOVERY_MODE; | ||
129 | else | ||
130 | reg &= ~(BOOTLOADER_MODE | RECOVERY_MODE | FORCED_RECOVERY_MODE); | ||
131 | } | ||
132 | else { | ||
133 | /* Clearing SCRATCH0 31:30:1 on default reboot */ | ||
134 | reg &= ~(BOOTLOADER_MODE | RECOVERY_MODE | FORCED_RECOVERY_MODE); | ||
135 | } | ||
136 | writel_relaxed(reg, reset + PMC_SCRATCH0); | ||
41 | /* use *_related to avoid spinlock since caches are off */ | 137 | /* use *_related to avoid spinlock since caches are off */ |
42 | reg = readl_relaxed(reset); | 138 | reg = readl_relaxed(reset); |
43 | reg |= 0x04; | 139 | reg |= 0x10; |
44 | writel_relaxed(reg, reset); | 140 | writel_relaxed(reg, reset); |
141 | #endif | ||
45 | } | 142 | } |
143 | static int modem_id; | ||
144 | static int sku_override; | ||
145 | static int debug_uart_port_id; | ||
146 | static enum audio_codec_type audio_codec_name; | ||
147 | static enum image_type board_image_type = system_image; | ||
148 | static int max_cpu_current; | ||
46 | 149 | ||
150 | /* WARNING: There is implicit client of pllp_out3 like i2c, uart, dsi | ||
151 | * and so this clock (pllp_out3) should never be disabled. | ||
152 | */ | ||
47 | static __initdata struct tegra_clk_init_table common_clk_init_table[] = { | 153 | static __initdata struct tegra_clk_init_table common_clk_init_table[] = { |
48 | /* name parent rate enabled */ | 154 | /* name parent rate enabled */ |
49 | { "clk_m", NULL, 0, true }, | 155 | { "clk_m", NULL, 0, true }, |
50 | { "pll_p", "clk_m", 216000000, true }, | 156 | #ifdef CONFIG_TEGRA_SILICON_PLATFORM |
157 | #ifdef CONFIG_ARCH_TEGRA_2x_SOC | ||
158 | { "pll_p", NULL, 216000000, true }, | ||
51 | { "pll_p_out1", "pll_p", 28800000, true }, | 159 | { "pll_p_out1", "pll_p", 28800000, true }, |
52 | { "pll_p_out2", "pll_p", 48000000, true }, | 160 | { "pll_p_out2", "pll_p", 48000000, false }, |
161 | { "pll_p_out3", "pll_p", 72000000, true }, | ||
162 | { "pll_p_out4", "pll_p", 108000000, false }, | ||
163 | { "pll_m", "clk_m", 0, true }, | ||
164 | { "pll_m_out1", "pll_m", 120000000, true }, | ||
165 | { "sclk", "pll_c_out1", 40000000, true }, | ||
166 | { "hclk", "sclk", 40000000, true }, | ||
167 | { "pclk", "hclk", 40000000, true }, | ||
168 | { "mpe", "pll_c", 0, false }, | ||
169 | { "epp", "pll_c", 0, false }, | ||
170 | { "vi_sensor", "pll_c", 0, false }, | ||
171 | { "vi", "pll_c", 0, false }, | ||
172 | { "2d", "pll_c", 0, false }, | ||
173 | { "3d", "pll_c", 0, false }, | ||
174 | #else | ||
175 | { "pll_p", NULL, 0, true }, | ||
176 | { "pll_p_out1", "pll_p", 0, false }, | ||
177 | { "pll_p_out2", "pll_p", 48000000, false }, | ||
178 | { "pll_p_out3", "pll_p", 0, true }, | ||
179 | { "pll_m_out1", "pll_m", 275000000, false }, | ||
180 | { "pll_p_out4", "pll_p", 102000000, true }, | ||
181 | { "sclk", "pll_p_out4", 102000000, true }, | ||
182 | { "hclk", "sclk", 102000000, true }, | ||
183 | { "pclk", "hclk", 51000000, true }, | ||
184 | { "sbc5.sclk", NULL, 40000000, false}, | ||
185 | { "sbc6.sclk", NULL, 40000000, false}, | ||
186 | #endif | ||
187 | { "sbc1.sclk", NULL, 40000000, false}, | ||
188 | { "sbc2.sclk", NULL, 40000000, false}, | ||
189 | { "sbc3.sclk", NULL, 40000000, false}, | ||
190 | { "sbc4.sclk", NULL, 40000000, false}, | ||
191 | #else | ||
192 | { "pll_p", NULL, 216000000, true }, | ||
193 | { "pll_p_out1", "pll_p", 28800000, false }, | ||
194 | { "pll_p_out2", "pll_p", 48000000, false }, | ||
53 | { "pll_p_out3", "pll_p", 72000000, true }, | 195 | { "pll_p_out3", "pll_p", 72000000, true }, |
54 | { "pll_p_out4", "pll_p", 108000000, true }, | 196 | { "pll_m_out1", "pll_m", 275000000, true }, |
197 | { "pll_c", NULL, ULONG_MAX, false }, | ||
198 | { "pll_c_out1", "pll_c", 208000000, false }, | ||
199 | { "pll_p_out4", "pll_p", 108000000, false }, | ||
55 | { "sclk", "pll_p_out4", 108000000, true }, | 200 | { "sclk", "pll_p_out4", 108000000, true }, |
56 | { "hclk", "sclk", 108000000, true }, | 201 | { "hclk", "sclk", 108000000, true }, |
57 | { "pclk", "hclk", 54000000, true }, | 202 | { "pclk", "hclk", 54000000, true }, |
58 | { "csite", NULL, 0, true }, | 203 | #endif |
204 | #ifdef CONFIG_TEGRA_SLOW_CSITE | ||
205 | { "csite", "clk_m", 1000000, true }, | ||
206 | #else | ||
207 | { "csite", NULL, 0, true }, | ||
208 | #endif | ||
59 | { "emc", NULL, 0, true }, | 209 | { "emc", NULL, 0, true }, |
60 | { "cpu", NULL, 0, true }, | 210 | { "cpu", NULL, 0, true }, |
211 | { "kfuse", NULL, 0, true }, | ||
212 | { "fuse", NULL, 0, true }, | ||
213 | { "pll_u", NULL, 480000000, false }, | ||
214 | { "sdmmc1", "pll_p", 48000000, false}, | ||
215 | { "sdmmc3", "pll_p", 48000000, false}, | ||
216 | { "sdmmc4", "pll_p", 48000000, false}, | ||
217 | { "pll_a", "pll_p_out1", 0, false}, | ||
218 | { "pll_a_out0", "pll_a", 0, false}, | ||
219 | #ifndef CONFIG_ARCH_TEGRA_2x_SOC | ||
220 | { "cbus", "pll_c", 416000000, false }, | ||
221 | { "pll_c_out1", "pll_c", 208000000, false }, | ||
222 | { "mselect", "pll_p", 102000000, true }, | ||
223 | #endif | ||
61 | { NULL, NULL, 0, 0}, | 224 | { NULL, NULL, 0, 0}, |
62 | }; | 225 | }; |
63 | 226 | ||
64 | void __init tegra_init_cache(void) | ||
65 | { | ||
66 | #ifdef CONFIG_CACHE_L2X0 | 227 | #ifdef CONFIG_CACHE_L2X0 |
228 | #ifdef CONFIG_TRUSTED_FOUNDATIONS | ||
229 | static void tegra_cache_smc(bool enable, u32 arg) | ||
230 | { | ||
231 | void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000; | ||
232 | bool need_affinity_switch; | ||
233 | bool can_switch_affinity; | ||
234 | bool l2x0_enabled; | ||
235 | cpumask_t local_cpu_mask; | ||
236 | cpumask_t saved_cpu_mask; | ||
237 | unsigned long flags; | ||
238 | long ret; | ||
239 | |||
240 | /* | ||
241 | * ISSUE : Some registers of PL310 controler must be written | ||
242 | * from Secure context (and from CPU0)! | ||
243 | * | ||
244 | * When called form Normal we obtain an abort or do nothing. | ||
245 | * Instructions that must be called in Secure: | ||
246 | * - Write to Control register (L2X0_CTRL==0x100) | ||
247 | * - Write in Auxiliary controler (L2X0_AUX_CTRL==0x104) | ||
248 | * - Invalidate all entries (L2X0_INV_WAY==0x77C), | ||
249 | * mandatory at boot time. | ||
250 | * - Tag and Data RAM Latency Control Registers | ||
251 | * (0x108 & 0x10C) must be written in Secure. | ||
252 | */ | ||
253 | need_affinity_switch = (smp_processor_id() != 0); | ||
254 | can_switch_affinity = !irqs_disabled(); | ||
255 | |||
256 | WARN_ON(need_affinity_switch && !can_switch_affinity); | ||
257 | if (need_affinity_switch && can_switch_affinity) { | ||
258 | cpu_set(0, local_cpu_mask); | ||
259 | sched_getaffinity(0, &saved_cpu_mask); | ||
260 | ret = sched_setaffinity(0, &local_cpu_mask); | ||
261 | WARN_ON(ret != 0); | ||
262 | } | ||
263 | |||
264 | local_irq_save(flags); | ||
265 | l2x0_enabled = readl_relaxed(p + L2X0_CTRL) & 1; | ||
266 | if (enable && !l2x0_enabled) | ||
267 | tegra_generic_smc(0xFFFFF100, 0x00000001, arg); | ||
268 | else if (!enable && l2x0_enabled) | ||
269 | tegra_generic_smc(0xFFFFF100, 0x00000002, arg); | ||
270 | local_irq_restore(flags); | ||
271 | |||
272 | if (need_affinity_switch && can_switch_affinity) { | ||
273 | ret = sched_setaffinity(0, &saved_cpu_mask); | ||
274 | WARN_ON(ret != 0); | ||
275 | } | ||
276 | } | ||
277 | |||
278 | static void tegra_l2x0_disable(void) | ||
279 | { | ||
280 | unsigned long flags; | ||
281 | static u32 l2x0_way_mask; | ||
282 | |||
283 | if (!l2x0_way_mask) { | ||
284 | void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000; | ||
285 | u32 aux_ctrl; | ||
286 | u32 ways; | ||
287 | |||
288 | aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL); | ||
289 | ways = (aux_ctrl & (1 << 16)) ? 16 : 8; | ||
290 | l2x0_way_mask = (1 << ways) - 1; | ||
291 | } | ||
292 | |||
293 | local_irq_save(flags); | ||
294 | tegra_cache_smc(false, l2x0_way_mask); | ||
295 | local_irq_restore(flags); | ||
296 | } | ||
297 | #endif /* CONFIG_TRUSTED_FOUNDATIONS */ | ||
298 | |||
299 | void tegra_init_cache(bool init) | ||
300 | { | ||
67 | void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000; | 301 | void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000; |
302 | u32 aux_ctrl; | ||
303 | u32 speedo; | ||
304 | u32 tmp; | ||
305 | |||
306 | #ifdef CONFIG_TRUSTED_FOUNDATIONS | ||
307 | /* issue the SMC to enable the L2 */ | ||
308 | aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL); | ||
309 | tegra_cache_smc(true, aux_ctrl); | ||
68 | 310 | ||
311 | /* after init, reread aux_ctrl and register handlers */ | ||
312 | aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL); | ||
313 | l2x0_init(p, aux_ctrl, 0xFFFFFFFF); | ||
314 | |||
315 | /* override outer_disable() with our disable */ | ||
316 | outer_cache.disable = tegra_l2x0_disable; | ||
317 | #else | ||
318 | #if defined(CONFIG_ARCH_TEGRA_2x_SOC) | ||
69 | writel_relaxed(0x331, p + L2X0_TAG_LATENCY_CTRL); | 319 | writel_relaxed(0x331, p + L2X0_TAG_LATENCY_CTRL); |
70 | writel_relaxed(0x441, p + L2X0_DATA_LATENCY_CTRL); | 320 | writel_relaxed(0x441, p + L2X0_DATA_LATENCY_CTRL); |
71 | 321 | ||
72 | l2x0_init(p, 0x6C080001, 0x8200c3fe); | 322 | #elif defined(CONFIG_ARCH_TEGRA_3x_SOC) |
323 | #ifdef CONFIG_TEGRA_SILICON_PLATFORM | ||
324 | /* PL310 RAM latency is CPU dependent. NOTE: Changes here | ||
325 | must also be reflected in __cortex_a9_l2x0_restart */ | ||
326 | |||
327 | if (is_lp_cluster()) { | ||
328 | writel(0x221, p + L2X0_TAG_LATENCY_CTRL); | ||
329 | writel(0x221, p + L2X0_DATA_LATENCY_CTRL); | ||
330 | } else { | ||
331 | /* relax l2-cache latency for speedos 4,5,6 (T33's chips) */ | ||
332 | speedo = tegra_cpu_speedo_id(); | ||
333 | if (speedo == 4 || speedo == 5 || speedo == 6 || | ||
334 | speedo == 12 || speedo == 13) { | ||
335 | writel(0x442, p + L2X0_TAG_LATENCY_CTRL); | ||
336 | writel(0x552, p + L2X0_DATA_LATENCY_CTRL); | ||
337 | } else { | ||
338 | writel(0x441, p + L2X0_TAG_LATENCY_CTRL); | ||
339 | writel(0x551, p + L2X0_DATA_LATENCY_CTRL); | ||
340 | } | ||
341 | } | ||
342 | #else | ||
343 | writel(0x770, p + L2X0_TAG_LATENCY_CTRL); | ||
344 | writel(0x770, p + L2X0_DATA_LATENCY_CTRL); | ||
345 | #endif | ||
346 | #endif | ||
347 | aux_ctrl = readl(p + L2X0_CACHE_TYPE); | ||
348 | aux_ctrl = (aux_ctrl & 0x700) << (17-8); | ||
349 | aux_ctrl |= 0x7C000001; | ||
350 | if (init) { | ||
351 | l2x0_init(p, aux_ctrl, 0x8200c3fe); | ||
352 | } else { | ||
353 | tmp = aux_ctrl; | ||
354 | aux_ctrl = readl(p + L2X0_AUX_CTRL); | ||
355 | aux_ctrl &= 0x8200c3fe; | ||
356 | aux_ctrl |= tmp; | ||
357 | writel(aux_ctrl, p + L2X0_AUX_CTRL); | ||
358 | } | ||
359 | l2x0_enable(); | ||
360 | #endif | ||
361 | } | ||
362 | #endif | ||
363 | |||
364 | static void __init tegra_init_power(void) | ||
365 | { | ||
366 | #ifdef CONFIG_ARCH_TEGRA_HAS_SATA | ||
367 | tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_SATA); | ||
368 | #endif | ||
369 | #ifdef CONFIG_ARCH_TEGRA_HAS_PCIE | ||
370 | tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_PCIE); | ||
73 | #endif | 371 | #endif |
372 | } | ||
74 | 373 | ||
374 | static inline unsigned long gizmo_readl(unsigned long offset) | ||
375 | { | ||
376 | return readl(IO_TO_VIRT(TEGRA_AHB_GIZMO_BASE + offset)); | ||
377 | } | ||
378 | |||
379 | static inline void gizmo_writel(unsigned long value, unsigned long offset) | ||
380 | { | ||
381 | writel(value, IO_TO_VIRT(TEGRA_AHB_GIZMO_BASE + offset)); | ||
382 | } | ||
383 | |||
384 | static void __init tegra_init_ahb_gizmo_settings(void) | ||
385 | { | ||
386 | unsigned long val; | ||
387 | |||
388 | val = gizmo_readl(AHB_GIZMO_AHB_MEM); | ||
389 | val |= ENB_FAST_REARBITRATE | IMMEDIATE | DONT_SPLIT_AHB_WR; | ||
390 | gizmo_writel(val, AHB_GIZMO_AHB_MEM); | ||
391 | |||
392 | val = gizmo_readl(AHB_GIZMO_USB); | ||
393 | val |= IMMEDIATE; | ||
394 | gizmo_writel(val, AHB_GIZMO_USB); | ||
395 | |||
396 | val = gizmo_readl(AHB_GIZMO_USB2); | ||
397 | val |= IMMEDIATE; | ||
398 | gizmo_writel(val, AHB_GIZMO_USB2); | ||
399 | |||
400 | val = gizmo_readl(AHB_GIZMO_USB3); | ||
401 | val |= IMMEDIATE; | ||
402 | gizmo_writel(val, AHB_GIZMO_USB3); | ||
403 | |||
404 | val = gizmo_readl(AHB_ARBITRATION_PRIORITY_CTRL); | ||
405 | val |= PRIORITY_SELECT_USB | PRIORITY_SELECT_USB2 | PRIORITY_SELECT_USB3 | ||
406 | | AHB_PRIORITY_WEIGHT(7); | ||
407 | gizmo_writel(val, AHB_ARBITRATION_PRIORITY_CTRL); | ||
408 | |||
409 | val = gizmo_readl(AHB_MEM_PREFETCH_CFG1); | ||
410 | val &= ~MST_ID(~0); | ||
411 | val |= PREFETCH_ENB | AHBDMA_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000); | ||
412 | gizmo_writel(val, AHB_MEM_PREFETCH_CFG1); | ||
413 | |||
414 | val = gizmo_readl(AHB_MEM_PREFETCH_CFG2); | ||
415 | val &= ~MST_ID(~0); | ||
416 | val |= PREFETCH_ENB | USB_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000); | ||
417 | gizmo_writel(val, AHB_MEM_PREFETCH_CFG2); | ||
418 | |||
419 | val = gizmo_readl(AHB_MEM_PREFETCH_CFG3); | ||
420 | val &= ~MST_ID(~0); | ||
421 | val |= PREFETCH_ENB | USB3_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000); | ||
422 | gizmo_writel(val, AHB_MEM_PREFETCH_CFG3); | ||
423 | |||
424 | val = gizmo_readl(AHB_MEM_PREFETCH_CFG4); | ||
425 | val &= ~MST_ID(~0); | ||
426 | val |= PREFETCH_ENB | USB2_MST_ID | ADDR_BNDRY(0xc) | INACTIVITY_TIMEOUT(0x1000); | ||
427 | gizmo_writel(val, AHB_MEM_PREFETCH_CFG4); | ||
75 | } | 428 | } |
76 | 429 | ||
77 | void __init tegra_init_early(void) | 430 | void __init tegra_init_early(void) |
78 | { | 431 | { |
432 | #ifndef CONFIG_SMP | ||
433 | /* For SMP system, initializing the reset handler here is too | ||
434 | late. For non-SMP systems, the function that calls the reset | ||
435 | handler initializer is not called, so do it here for non-SMP. */ | ||
436 | tegra_cpu_reset_handler_init(); | ||
437 | #endif | ||
79 | tegra_init_fuse(); | 438 | tegra_init_fuse(); |
439 | tegra_gpio_resume_init(); | ||
80 | tegra_init_clock(); | 440 | tegra_init_clock(); |
441 | tegra_init_pinmux(); | ||
81 | tegra_clk_init_from_table(common_clk_init_table); | 442 | tegra_clk_init_from_table(common_clk_init_table); |
82 | tegra_init_cache(); | 443 | tegra_init_power(); |
444 | tegra_init_cache(true); | ||
445 | tegra_init_ahb_gizmo_settings(); | ||
446 | tegra_init_debug_uart_rate(); | ||
447 | } | ||
448 | |||
449 | static int __init tegra_lp0_vec_arg(char *options) | ||
450 | { | ||
451 | char *p = options; | ||
452 | |||
453 | tegra_lp0_vec_size = memparse(p, &p); | ||
454 | if (*p == '@') | ||
455 | tegra_lp0_vec_start = memparse(p+1, &p); | ||
456 | if (!tegra_lp0_vec_size || !tegra_lp0_vec_start) { | ||
457 | tegra_lp0_vec_size = 0; | ||
458 | tegra_lp0_vec_start = 0; | ||
459 | } | ||
460 | |||
461 | return 0; | ||
462 | } | ||
463 | early_param("lp0_vec", tegra_lp0_vec_arg); | ||
464 | |||
465 | static int __init tegra_bootloader_fb_arg(char *options) | ||
466 | { | ||
467 | char *p = options; | ||
468 | |||
469 | tegra_bootloader_fb_size = memparse(p, &p); | ||
470 | if (*p == '@') | ||
471 | tegra_bootloader_fb_start = memparse(p+1, &p); | ||
472 | |||
473 | pr_info("Found tegra_fbmem: %08lx@%08lx\n", | ||
474 | tegra_bootloader_fb_size, tegra_bootloader_fb_start); | ||
475 | |||
476 | return 0; | ||
477 | } | ||
478 | early_param("tegra_fbmem", tegra_bootloader_fb_arg); | ||
479 | |||
480 | static int __init tegra_sku_override(char *id) | ||
481 | { | ||
482 | char *p = id; | ||
483 | |||
484 | sku_override = memparse(p, &p); | ||
485 | |||
486 | return 0; | ||
487 | } | ||
488 | early_param("sku_override", tegra_sku_override); | ||
489 | |||
490 | int tegra_get_sku_override(void) | ||
491 | { | ||
492 | return sku_override; | ||
493 | } | ||
494 | |||
495 | static int __init tegra_vpr_arg(char *options) | ||
496 | { | ||
497 | char *p = options; | ||
498 | |||
499 | tegra_vpr_size = memparse(p, &p); | ||
500 | if (*p == '@') | ||
501 | tegra_vpr_start = memparse(p+1, &p); | ||
502 | pr_info("Found vpr, start=0x%lx size=%lx", | ||
503 | tegra_vpr_start, tegra_vpr_size); | ||
504 | return 0; | ||
505 | } | ||
506 | early_param("vpr", tegra_vpr_arg); | ||
507 | |||
508 | enum panel_type get_panel_type(void) | ||
509 | { | ||
510 | return board_panel_type; | ||
511 | } | ||
512 | static int __init tegra_board_panel_type(char *options) | ||
513 | { | ||
514 | if (!strcmp(options, "lvds")) | ||
515 | board_panel_type = panel_type_lvds; | ||
516 | else if (!strcmp(options, "dsi")) | ||
517 | board_panel_type = panel_type_dsi; | ||
518 | else | ||
519 | return 0; | ||
520 | return 1; | ||
521 | } | ||
522 | __setup("panel=", tegra_board_panel_type); | ||
523 | |||
524 | enum power_supply_type get_power_supply_type(void) | ||
525 | { | ||
526 | return pow_supply_type; | ||
527 | } | ||
528 | static int __init tegra_board_power_supply_type(char *options) | ||
529 | { | ||
530 | if (!strcmp(options, "Adapter")) | ||
531 | pow_supply_type = POWER_SUPPLY_TYPE_MAINS; | ||
532 | if (!strcmp(options, "Mains")) | ||
533 | pow_supply_type = POWER_SUPPLY_TYPE_MAINS; | ||
534 | else if (!strcmp(options, "Battery")) | ||
535 | pow_supply_type = POWER_SUPPLY_TYPE_BATTERY; | ||
536 | else | ||
537 | return 0; | ||
538 | return 1; | ||
539 | } | ||
540 | __setup("power_supply=", tegra_board_power_supply_type); | ||
541 | |||
542 | int get_core_edp(void) | ||
543 | { | ||
544 | return pmu_core_edp; | ||
545 | } | ||
546 | static int __init tegra_pmu_core_edp(char *options) | ||
547 | { | ||
548 | char *p = options; | ||
549 | int core_edp = memparse(p, &p); | ||
550 | if (core_edp != 0) | ||
551 | pmu_core_edp = core_edp; | ||
552 | return 0; | ||
553 | } | ||
554 | early_param("core_edp_mv", tegra_pmu_core_edp); | ||
555 | |||
556 | int get_maximum_cpu_current_supported(void) | ||
557 | { | ||
558 | return max_cpu_current; | ||
559 | } | ||
560 | static int __init tegra_max_cpu_current(char *options) | ||
561 | { | ||
562 | char *p = options; | ||
563 | max_cpu_current = memparse(p, &p); | ||
564 | return 1; | ||
565 | } | ||
566 | __setup("max_cpu_cur_ma=", tegra_max_cpu_current); | ||
567 | |||
568 | static int __init tegra_debug_uartport(char *info) | ||
569 | { | ||
570 | char *p = info; | ||
571 | unsigned long long port_id; | ||
572 | if (!strncmp(p, "hsport", 6)) | ||
573 | is_tegra_debug_uart_hsport = true; | ||
574 | else if (!strncmp(p, "lsport", 6)) | ||
575 | is_tegra_debug_uart_hsport = false; | ||
576 | |||
577 | if (p[6] == ',') { | ||
578 | if (p[7] == '-') { | ||
579 | debug_uart_port_id = -1; | ||
580 | } else { | ||
581 | port_id = memparse(p + 7, &p); | ||
582 | debug_uart_port_id = (int) port_id; | ||
583 | } | ||
584 | } else { | ||
585 | debug_uart_port_id = -1; | ||
586 | } | ||
587 | |||
588 | return 1; | ||
589 | } | ||
590 | |||
591 | bool is_tegra_debug_uartport_hs(void) | ||
592 | { | ||
593 | return is_tegra_debug_uart_hsport; | ||
594 | } | ||
595 | |||
596 | int get_tegra_uart_debug_port_id(void) | ||
597 | { | ||
598 | return debug_uart_port_id; | ||
599 | } | ||
600 | __setup("debug_uartport=", tegra_debug_uartport); | ||
601 | |||
602 | static int __init tegra_image_type(char *options) | ||
603 | { | ||
604 | if (!strcmp(options, "RCK")) | ||
605 | board_image_type = rck_image; | ||
606 | |||
607 | return 0; | ||
608 | } | ||
609 | |||
610 | enum image_type get_tegra_image_type(void) | ||
611 | { | ||
612 | return board_image_type; | ||
613 | } | ||
614 | |||
615 | __setup("image=", tegra_image_type); | ||
616 | |||
617 | static int __init tegra_audio_codec_type(char *info) | ||
618 | { | ||
619 | char *p = info; | ||
620 | if (!strncmp(p, "wm8903", 6)) | ||
621 | audio_codec_name = audio_codec_wm8903; | ||
622 | else | ||
623 | audio_codec_name = audio_codec_none; | ||
624 | |||
625 | return 1; | ||
626 | } | ||
627 | |||
628 | enum audio_codec_type get_audio_codec_type(void) | ||
629 | { | ||
630 | return audio_codec_name; | ||
631 | } | ||
632 | __setup("audio_codec=", tegra_audio_codec_type); | ||
633 | |||
634 | |||
635 | void tegra_get_board_info(struct board_info *bi) | ||
636 | { | ||
637 | /* | ||
638 | bi->board_id = (system_serial_high >> 16) & 0xFFFF; | ||
639 | bi->sku = (system_serial_high) & 0xFFFF; | ||
640 | bi->fab = (system_serial_low >> 24) & 0xFF; | ||
641 | bi->major_revision = (system_serial_low >> 16) & 0xFF; | ||
642 | bi->minor_revision = (system_serial_low >> 8) & 0xFF; | ||
643 | */ | ||
644 | //no board info on EEPROM yet | ||
645 | bi->board_id = 0x00000C5B; | ||
646 | bi->sku = 0x00000B01; | ||
647 | bi->fab = 0x00000004; | ||
648 | bi->major_revision = 0x00000041; | ||
649 | bi->minor_revision = 0x00000000; | ||
650 | } | ||
651 | |||
652 | static int __init tegra_pmu_board_info(char *info) | ||
653 | { | ||
654 | char *p = info; | ||
655 | pmu_board_info.board_id = memparse(p, &p); | ||
656 | pmu_board_info.sku = memparse(p+1, &p); | ||
657 | pmu_board_info.fab = memparse(p+1, &p); | ||
658 | pmu_board_info.major_revision = memparse(p+1, &p); | ||
659 | pmu_board_info.minor_revision = memparse(p+1, &p); | ||
660 | return 1; | ||
661 | } | ||
662 | |||
663 | void tegra_get_pmu_board_info(struct board_info *bi) | ||
664 | { | ||
665 | memcpy(bi, &pmu_board_info, sizeof(struct board_info)); | ||
666 | } | ||
667 | |||
668 | __setup("pmuboard=", tegra_pmu_board_info); | ||
669 | |||
670 | static int __init tegra_display_board_info(char *info) | ||
671 | { | ||
672 | char *p = info; | ||
673 | display_board_info.board_id = memparse(p, &p); | ||
674 | display_board_info.sku = memparse(p+1, &p); | ||
675 | display_board_info.fab = memparse(p+1, &p); | ||
676 | display_board_info.major_revision = memparse(p+1, &p); | ||
677 | display_board_info.minor_revision = memparse(p+1, &p); | ||
678 | return 1; | ||
679 | } | ||
680 | |||
681 | void tegra_get_display_board_info(struct board_info *bi) | ||
682 | { | ||
683 | memcpy(bi, &display_board_info, sizeof(struct board_info)); | ||
684 | } | ||
685 | |||
686 | __setup("displayboard=", tegra_display_board_info); | ||
687 | |||
688 | static int __init tegra_camera_board_info(char *info) | ||
689 | { | ||
690 | char *p = info; | ||
691 | camera_board_info.board_id = memparse(p, &p); | ||
692 | camera_board_info.sku = memparse(p+1, &p); | ||
693 | camera_board_info.fab = memparse(p+1, &p); | ||
694 | camera_board_info.major_revision = memparse(p+1, &p); | ||
695 | camera_board_info.minor_revision = memparse(p+1, &p); | ||
696 | return 1; | ||
697 | } | ||
698 | |||
699 | void tegra_get_camera_board_info(struct board_info *bi) | ||
700 | { | ||
701 | memcpy(bi, &camera_board_info, sizeof(struct board_info)); | ||
702 | } | ||
703 | |||
704 | __setup("cameraboard=", tegra_camera_board_info); | ||
705 | |||
706 | static int __init tegra_modem_id(char *id) | ||
707 | { | ||
708 | char *p = id; | ||
709 | |||
710 | modem_id = memparse(p, &p); | ||
711 | return 1; | ||
712 | } | ||
713 | |||
714 | int tegra_get_modem_id(void) | ||
715 | { | ||
716 | return modem_id; | ||
717 | } | ||
718 | |||
719 | __setup("modem_id=", tegra_modem_id); | ||
720 | |||
721 | /* | ||
722 | * Tegra has a protected aperture that prevents access by most non-CPU | ||
723 | * memory masters to addresses above the aperture value. Enabling it | ||
724 | * secures the CPU's memory from the GPU, except through the GART. | ||
725 | */ | ||
726 | void __init tegra_protected_aperture_init(unsigned long aperture) | ||
727 | { | ||
728 | #ifndef CONFIG_NVMAP_ALLOW_SYSMEM | ||
729 | void __iomem *mc_base = IO_ADDRESS(TEGRA_MC_BASE); | ||
730 | pr_info("Enabling Tegra protected aperture at 0x%08lx\n", aperture); | ||
731 | writel(aperture, mc_base + MC_SECURITY_CFG2); | ||
732 | #else | ||
733 | pr_err("Tegra protected aperture disabled because nvmap is using " | ||
734 | "system memory\n"); | ||
735 | #endif | ||
736 | } | ||
737 | |||
738 | /* | ||
739 | * Due to conflicting restrictions on the placement of the framebuffer, | ||
740 | * the bootloader is likely to leave the framebuffer pointed at a location | ||
741 | * in memory that is outside the grhost aperture. This function will move | ||
742 | * the framebuffer contents from a physical address that is anywher (lowmem, | ||
743 | * highmem, or outside the memory map) to a physical address that is outside | ||
744 | * the memory map. | ||
745 | */ | ||
746 | void tegra_move_framebuffer(unsigned long to, unsigned long from, | ||
747 | unsigned long size) | ||
748 | { | ||
749 | struct page *page; | ||
750 | void __iomem *to_io; | ||
751 | void *from_virt; | ||
752 | unsigned long i; | ||
753 | |||
754 | BUG_ON(PAGE_ALIGN((unsigned long)to) != (unsigned long)to); | ||
755 | BUG_ON(PAGE_ALIGN(from) != from); | ||
756 | BUG_ON(PAGE_ALIGN(size) != size); | ||
757 | |||
758 | to_io = ioremap(to, size); | ||
759 | if (!to_io) { | ||
760 | pr_err("%s: Failed to map target framebuffer\n", __func__); | ||
761 | return; | ||
762 | } | ||
763 | |||
764 | if (pfn_valid(page_to_pfn(phys_to_page(from)))) { | ||
765 | for (i = 0 ; i < size; i += PAGE_SIZE) { | ||
766 | page = phys_to_page(from + i); | ||
767 | from_virt = kmap(page); | ||
768 | memcpy(to_io + i, from_virt, PAGE_SIZE); | ||
769 | kunmap(page); | ||
770 | } | ||
771 | } else { | ||
772 | void __iomem *from_io = ioremap(from, size); | ||
773 | if (!from_io) { | ||
774 | pr_err("%s: Failed to map source framebuffer\n", | ||
775 | __func__); | ||
776 | goto out; | ||
777 | } | ||
778 | |||
779 | for (i = 0; i < size; i += 4) | ||
780 | writel(readl(from_io + i), to_io + i); | ||
781 | |||
782 | iounmap(from_io); | ||
783 | } | ||
784 | out: | ||
785 | iounmap(to_io); | ||
786 | } | ||
787 | |||
788 | #ifdef CONFIG_TEGRA_SMMU_BASE_AT_E0000000 | ||
789 | #define FORCE_SMMU_BASE_FOR_TEGRA3_A01 1 | ||
790 | #else | ||
791 | #define FORCE_SMMU_BASE_FOR_TEGRA3_A01 0 | ||
792 | #endif | ||
793 | #if FORCE_SMMU_BASE_FOR_TEGRA3_A01 || \ | ||
794 | (defined(CONFIG_TEGRA_IOVMM_SMMU) && defined(CONFIG_ARCH_TEGRA_3x_SOC)) | ||
795 | /* Support for Tegra3 A01 chip mask that needs to have SMMU IOVA reside in | ||
796 | * the upper half of 4GB IOVA space. A02 and after use the bottom 1GB and | ||
797 | * do not need to reserve memory. | ||
798 | */ | ||
799 | #define SUPPORT_SMMU_BASE_FOR_TEGRA3_A01 | ||
800 | #endif | ||
801 | |||
802 | void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size, | ||
803 | unsigned long fb2_size) | ||
804 | { | ||
805 | #ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01 | ||
806 | int smmu_reserved = 0; | ||
807 | struct tegra_smmu_window *smmu_window = tegra_smmu_window(0); | ||
808 | #endif | ||
809 | |||
810 | if (carveout_size) { | ||
811 | tegra_carveout_start = memblock_end_of_DRAM() - carveout_size; | ||
812 | if (memblock_remove(tegra_carveout_start, carveout_size)) { | ||
813 | pr_err("Failed to remove carveout %08lx@%08lx " | ||
814 | "from memory map\n", | ||
815 | carveout_size, tegra_carveout_start); | ||
816 | tegra_carveout_start = 0; | ||
817 | tegra_carveout_size = 0; | ||
818 | } else | ||
819 | tegra_carveout_size = carveout_size; | ||
820 | } | ||
821 | |||
822 | if (fb2_size) { | ||
823 | tegra_fb2_start = memblock_end_of_DRAM() - fb2_size; | ||
824 | if (memblock_remove(tegra_fb2_start, fb2_size)) { | ||
825 | pr_err("Failed to remove second framebuffer " | ||
826 | "%08lx@%08lx from memory map\n", | ||
827 | fb2_size, tegra_fb2_start); | ||
828 | tegra_fb2_start = 0; | ||
829 | tegra_fb2_size = 0; | ||
830 | } else | ||
831 | tegra_fb2_size = fb2_size; | ||
832 | } | ||
833 | |||
834 | if (fb_size) { | ||
835 | tegra_fb_start = memblock_end_of_DRAM() - fb_size; | ||
836 | if (memblock_remove(tegra_fb_start, fb_size)) { | ||
837 | pr_err("Failed to remove framebuffer %08lx@%08lx " | ||
838 | "from memory map\n", | ||
839 | fb_size, tegra_fb_start); | ||
840 | tegra_fb_start = 0; | ||
841 | tegra_fb_size = 0; | ||
842 | } else | ||
843 | tegra_fb_size = fb_size; | ||
844 | } | ||
845 | |||
846 | if (tegra_fb_size) | ||
847 | tegra_grhost_aperture = tegra_fb_start; | ||
848 | |||
849 | if (tegra_fb2_size && tegra_fb2_start < tegra_grhost_aperture) | ||
850 | tegra_grhost_aperture = tegra_fb2_start; | ||
851 | |||
852 | if (tegra_carveout_size && tegra_carveout_start < tegra_grhost_aperture) | ||
853 | tegra_grhost_aperture = tegra_carveout_start; | ||
854 | |||
855 | #ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01 | ||
856 | if (!smmu_window) { | ||
857 | pr_err("No SMMU resource\n"); | ||
858 | } else { | ||
859 | size_t smmu_window_size; | ||
860 | |||
861 | if (FORCE_SMMU_BASE_FOR_TEGRA3_A01 || | ||
862 | (tegra_get_chipid() == TEGRA_CHIPID_TEGRA3 && | ||
863 | tegra_get_revision() == TEGRA_REVISION_A01)) { | ||
864 | smmu_window->start = TEGRA_SMMU_BASE_TEGRA3_A01; | ||
865 | smmu_window->end = TEGRA_SMMU_BASE_TEGRA3_A01 + | ||
866 | TEGRA_SMMU_SIZE_TEGRA3_A01 - 1; | ||
867 | } | ||
868 | smmu_window_size = smmu_window->end + 1 - smmu_window->start; | ||
869 | if (smmu_window->start >= 0x80000000) { | ||
870 | if (memblock_reserve(smmu_window->start, | ||
871 | smmu_window_size)) | ||
872 | pr_err( | ||
873 | "Failed to reserve SMMU I/O VA window %08lx@%08lx\n", | ||
874 | (unsigned long)smmu_window_size, | ||
875 | (unsigned long)smmu_window->start); | ||
876 | else | ||
877 | smmu_reserved = 1; | ||
878 | } | ||
879 | } | ||
880 | #endif | ||
881 | |||
882 | if (tegra_lp0_vec_size && | ||
883 | (tegra_lp0_vec_start < memblock_end_of_DRAM())) { | ||
884 | if (memblock_reserve(tegra_lp0_vec_start, tegra_lp0_vec_size)) { | ||
885 | pr_err("Failed to reserve lp0_vec %08lx@%08lx\n", | ||
886 | tegra_lp0_vec_size, tegra_lp0_vec_start); | ||
887 | tegra_lp0_vec_start = 0; | ||
888 | tegra_lp0_vec_size = 0; | ||
889 | } | ||
890 | tegra_lp0_vec_relocate = false; | ||
891 | } else | ||
892 | tegra_lp0_vec_relocate = true; | ||
893 | |||
894 | /* | ||
895 | * We copy the bootloader's framebuffer to the framebuffer allocated | ||
896 | * above, and then free this one. | ||
897 | * */ | ||
898 | if (tegra_bootloader_fb_size) { | ||
899 | tegra_bootloader_fb_size = PAGE_ALIGN(tegra_bootloader_fb_size); | ||
900 | if (memblock_reserve(tegra_bootloader_fb_start, | ||
901 | tegra_bootloader_fb_size)) { | ||
902 | pr_err("Failed to reserve bootloader frame buffer " | ||
903 | "%08lx@%08lx\n", tegra_bootloader_fb_size, | ||
904 | tegra_bootloader_fb_start); | ||
905 | tegra_bootloader_fb_start = 0; | ||
906 | tegra_bootloader_fb_size = 0; | ||
907 | } | ||
908 | } | ||
909 | |||
910 | pr_info("Tegra reserved memory:\n" | ||
911 | "LP0: %08lx - %08lx\n" | ||
912 | "Bootloader framebuffer: %08lx - %08lx\n" | ||
913 | "Framebuffer: %08lx - %08lx\n" | ||
914 | "2nd Framebuffer: %08lx - %08lx\n" | ||
915 | "Carveout: %08lx - %08lx\n" | ||
916 | "Vpr: %08lx - %08lx\n", | ||
917 | tegra_lp0_vec_start, | ||
918 | tegra_lp0_vec_size ? | ||
919 | tegra_lp0_vec_start + tegra_lp0_vec_size - 1 : 0, | ||
920 | tegra_bootloader_fb_start, | ||
921 | tegra_bootloader_fb_size ? | ||
922 | tegra_bootloader_fb_start + tegra_bootloader_fb_size - 1 : 0, | ||
923 | tegra_fb_start, | ||
924 | tegra_fb_size ? | ||
925 | tegra_fb_start + tegra_fb_size - 1 : 0, | ||
926 | tegra_fb2_start, | ||
927 | tegra_fb2_size ? | ||
928 | tegra_fb2_start + tegra_fb2_size - 1 : 0, | ||
929 | tegra_carveout_start, | ||
930 | tegra_carveout_size ? | ||
931 | tegra_carveout_start + tegra_carveout_size - 1 : 0, | ||
932 | tegra_vpr_start, | ||
933 | tegra_vpr_size ? | ||
934 | tegra_vpr_start + tegra_vpr_size - 1 : 0); | ||
935 | |||
936 | #ifdef SUPPORT_SMMU_BASE_FOR_TEGRA3_A01 | ||
937 | if (smmu_reserved) | ||
938 | pr_info("SMMU: %08lx - %08lx\n", | ||
939 | smmu_window->start, smmu_window->end); | ||
940 | #endif | ||
941 | } | ||
942 | |||
943 | static struct resource ram_console_resources[] = { | ||
944 | { | ||
945 | .flags = IORESOURCE_MEM, | ||
946 | }, | ||
947 | }; | ||
948 | |||
949 | static struct platform_device ram_console_device = { | ||
950 | .name = "ram_console", | ||
951 | .id = -1, | ||
952 | .num_resources = ARRAY_SIZE(ram_console_resources), | ||
953 | .resource = ram_console_resources, | ||
954 | }; | ||
955 | |||
956 | void __init tegra_ram_console_debug_reserve(unsigned long ram_console_size) | ||
957 | { | ||
958 | struct resource *res; | ||
959 | long ret; | ||
960 | |||
961 | res = platform_get_resource(&ram_console_device, IORESOURCE_MEM, 0); | ||
962 | if (!res) | ||
963 | goto fail; | ||
964 | res->start = memblock_end_of_DRAM() - ram_console_size; | ||
965 | res->end = res->start + ram_console_size - 1; | ||
966 | ret = memblock_remove(res->start, ram_console_size); | ||
967 | if (ret) | ||
968 | goto fail; | ||
969 | |||
970 | return; | ||
971 | |||
972 | fail: | ||
973 | ram_console_device.resource = NULL; | ||
974 | ram_console_device.num_resources = 0; | ||
975 | pr_err("Failed to reserve memory block for ram console\n"); | ||
976 | } | ||
977 | |||
978 | void __init tegra_ram_console_debug_init(void) | ||
979 | { | ||
980 | int err; | ||
981 | |||
982 | err = platform_device_register(&ram_console_device); | ||
983 | if (err) { | ||
984 | pr_err("%s: ram console registration failed (%d)!\n", __func__, err); | ||
985 | } | ||
986 | } | ||
987 | |||
988 | void __init tegra_release_bootloader_fb(void) | ||
989 | { | ||
990 | /* Since bootloader fb is reserved in common.c, it is freed here. */ | ||
991 | if (tegra_bootloader_fb_size) | ||
992 | if (memblock_free(tegra_bootloader_fb_start, | ||
993 | tegra_bootloader_fb_size)) | ||
994 | pr_err("Failed to free bootloader fb.\n"); | ||
995 | } | ||
996 | |||
997 | #ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND | ||
998 | static char cpufreq_gov_default[32]; | ||
999 | static char *cpufreq_gov_conservative = "conservative"; | ||
1000 | static char *cpufreq_sysfs_place_holder="/sys/devices/system/cpu/cpu%i/cpufreq/scaling_governor"; | ||
1001 | static char *cpufreq_gov_conservative_param="/sys/devices/system/cpu/cpufreq/conservative/%s"; | ||
1002 | |||
1003 | static void cpufreq_set_governor(char *governor) | ||
1004 | { | ||
1005 | struct file *scaling_gov = NULL; | ||
1006 | mm_segment_t old_fs; | ||
1007 | char buf[128]; | ||
1008 | int i = 0; | ||
1009 | loff_t offset = 0; | ||
1010 | |||
1011 | if (governor == NULL) | ||
1012 | return; | ||
1013 | |||
1014 | /* change to KERNEL_DS address limit */ | ||
1015 | old_fs = get_fs(); | ||
1016 | set_fs(KERNEL_DS); | ||
1017 | #ifndef CONFIG_TEGRA_AUTO_HOTPLUG | ||
1018 | for_each_online_cpu(i) | ||
1019 | #endif | ||
1020 | { | ||
1021 | sprintf(buf, cpufreq_sysfs_place_holder, i); | ||
1022 | scaling_gov = filp_open(buf, O_RDWR, 0); | ||
1023 | if (scaling_gov != NULL) { | ||
1024 | if (scaling_gov->f_op != NULL && | ||
1025 | scaling_gov->f_op->write != NULL) | ||
1026 | scaling_gov->f_op->write(scaling_gov, | ||
1027 | governor, | ||
1028 | strlen(governor), | ||
1029 | &offset); | ||
1030 | else | ||
1031 | pr_err("f_op might be null\n"); | ||
1032 | |||
1033 | filp_close(scaling_gov, NULL); | ||
1034 | } else { | ||
1035 | pr_err("%s. Can't open %s\n", __func__, buf); | ||
1036 | } | ||
1037 | } | ||
1038 | set_fs(old_fs); | ||
1039 | } | ||
1040 | |||
1041 | void cpufreq_save_default_governor(void) | ||
1042 | { | ||
1043 | struct file *scaling_gov = NULL; | ||
1044 | mm_segment_t old_fs; | ||
1045 | char buf[128]; | ||
1046 | loff_t offset = 0; | ||
1047 | |||
1048 | /* change to KERNEL_DS address limit */ | ||
1049 | old_fs = get_fs(); | ||
1050 | set_fs(KERNEL_DS); | ||
1051 | |||
1052 | buf[127] = 0; | ||
1053 | sprintf(buf, cpufreq_sysfs_place_holder,0); | ||
1054 | scaling_gov = filp_open(buf, O_RDONLY, 0); | ||
1055 | if (scaling_gov != NULL) { | ||
1056 | if (scaling_gov->f_op != NULL && | ||
1057 | scaling_gov->f_op->read != NULL) | ||
1058 | scaling_gov->f_op->read(scaling_gov, | ||
1059 | cpufreq_gov_default, | ||
1060 | 32, | ||
1061 | &offset); | ||
1062 | else | ||
1063 | pr_err("f_op might be null\n"); | ||
1064 | |||
1065 | filp_close(scaling_gov, NULL); | ||
1066 | } else { | ||
1067 | pr_err("%s. Can't open %s\n", __func__, buf); | ||
1068 | } | ||
1069 | set_fs(old_fs); | ||
1070 | } | ||
1071 | |||
1072 | void cpufreq_restore_default_governor(void) | ||
1073 | { | ||
1074 | cpufreq_set_governor(cpufreq_gov_default); | ||
1075 | } | ||
1076 | |||
1077 | void cpufreq_set_conservative_governor_param(char *name, int value) | ||
1078 | { | ||
1079 | struct file *gov_param = NULL; | ||
1080 | mm_segment_t old_fs; | ||
1081 | static char buf[128], param_value[8]; | ||
1082 | loff_t offset = 0; | ||
1083 | |||
1084 | /* change to KERNEL_DS address limit */ | ||
1085 | old_fs = get_fs(); | ||
1086 | set_fs(KERNEL_DS); | ||
1087 | |||
1088 | sprintf(param_value, "%d", value); | ||
1089 | sprintf(buf, cpufreq_gov_conservative_param, name); | ||
1090 | gov_param = filp_open(buf, O_RDWR, 0); | ||
1091 | if (gov_param != NULL) { | ||
1092 | if (gov_param->f_op != NULL && | ||
1093 | gov_param->f_op->write != NULL) | ||
1094 | gov_param->f_op->write(gov_param, | ||
1095 | param_value, | ||
1096 | strlen(param_value), | ||
1097 | &offset); | ||
1098 | else | ||
1099 | pr_err("f_op might be null\n"); | ||
1100 | |||
1101 | filp_close(gov_param, NULL); | ||
1102 | } else { | ||
1103 | pr_err("%s. Can't open %s\n", __func__, buf); | ||
1104 | } | ||
1105 | set_fs(old_fs); | ||
1106 | } | ||
1107 | |||
1108 | void cpufreq_set_conservative_governor(void) | ||
1109 | { | ||
1110 | cpufreq_set_governor(cpufreq_gov_conservative); | ||
83 | } | 1111 | } |
1112 | #endif /* CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND */ | ||