* arch/arm/mach-tegra/common.c
*
* Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2010-2012, NVIDIA Corporation. All rights reserved.
*
* Author:
* Colin Cross <ccross@android.com>
#include <linux/delay.h>
#include <linux/highmem.h>
#include <linux/memblock.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-#include <linux/mqueue.h>
#include <linux/bitops.h>
+#include <linux/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/of.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/system.h>
#include <mach/pinmux.h>
#include <mach/powergate.h>
#include <mach/system.h>
+#include <mach/tegra_smmu.h>
#include "apbio.h"
#include "board.h"
#include "fuse.h"
#include "pm.h"
#include "reset.h"
+#include "devices.h"
#define MC_SECURITY_CFG2 0x7c
#define ENB_FAST_REARBITRATE BIT(2)
#define DONT_SPLIT_AHB_WR BIT(7)
+#define RECOVERY_MODE BIT(31)
+#define BOOTLOADER_MODE BIT(30)
+#define FORCED_RECOVERY_MODE BIT(1)
+
#define AHB_GIZMO_USB 0x1c
#define AHB_GIZMO_USB2 0x78
#define AHB_GIZMO_USB3 0x7c
unsigned long tegra_fb2_size;
unsigned long tegra_carveout_start;
unsigned long tegra_carveout_size;
+unsigned long tegra_vpr_start;
+unsigned long tegra_vpr_size;
unsigned long tegra_lp0_vec_start;
unsigned long tegra_lp0_vec_size;
+bool tegra_lp0_vec_relocate;
unsigned long tegra_grhost_aperture = ~0ul;
static bool is_tegra_debug_uart_hsport;
static struct board_info pmu_board_info;
+static struct board_info display_board_info;
+static struct board_info camera_board_info;
static int pmu_core_edp = 1200; /* default 1.2V EDP limit */
static int board_panel_type;
+static enum power_supply_type pow_supply_type = POWER_SUPPLY_TYPE_MAINS;
void (*arch_reset)(char mode, const char *cmd) = tegra_assert_system_reset;
void __iomem *reset = IO_ADDRESS(TEGRA_PMC_BASE + 0x00);
u32 reg;
+ reg = readl_relaxed(reset + PMC_SCRATCH0);
+ /* Writing recovery kernel or Bootloader mode in SCRATCH0 31:30:1 */
+ if (cmd) {
+ if (!strcmp(cmd, "recovery"))
+ reg |= RECOVERY_MODE;
+ else if (!strcmp(cmd, "bootloader"))
+ reg |= BOOTLOADER_MODE;
+ else if (!strcmp(cmd, "forced-recovery"))
+ reg |= FORCED_RECOVERY_MODE;
+ else
+ reg &= ~(BOOTLOADER_MODE | RECOVERY_MODE | FORCED_RECOVERY_MODE);
+ }
+ else {
+ /* Clearing SCRATCH0 31:30:1 on default reboot */
+ reg &= ~(BOOTLOADER_MODE | RECOVERY_MODE | FORCED_RECOVERY_MODE);
+ }
+ writel_relaxed(reg, reset + PMC_SCRATCH0);
/* use *_related to avoid spinlock since caches are off */
reg = readl_relaxed(reset);
reg |= 0x10;
#endif
}
static int modem_id;
+static int commchip_id;
+static int sku_override;
+static int debug_uart_port_id;
+static enum audio_codec_type audio_codec_name;
+static enum image_type board_image_type = system_image;
+static int max_cpu_current;
/* WARNING: There is implicit client of pllp_out3 like i2c, uart, dsi
* and so this clock (pllp_out3) should never be disabled.
static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
/* name parent rate enabled */
{ "clk_m", NULL, 0, true },
+ { "emc", NULL, 0, true },
+ { "cpu", NULL, 0, true },
+ { "kfuse", NULL, 0, true },
+ { "fuse", NULL, 0, true },
+ { "sclk", NULL, 0, true },
#ifdef CONFIG_TEGRA_SILICON_PLATFORM
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
{ "pll_p", NULL, 216000000, true },
{ "pll_p_out1", "pll_p", 28800000, true },
- { "pll_p_out2", "pll_p", 48000000, true },
+ { "pll_p_out2", "pll_p", 48000000, false },
{ "pll_p_out3", "pll_p", 72000000, true },
- { "pll_p_out4", "pll_p", 108000000, true },
- { "pll_m", "clk_m", 600000000, true },
+ { "pll_p_out4", "pll_p", 108000000, false },
+ { "pll_m", "clk_m", 0, true },
{ "pll_m_out1", "pll_m", 120000000, true },
- { "sclk", "pll_m_out1", 40000000, true },
+ { "sclk", "pll_c_out1", 40000000, true },
{ "hclk", "sclk", 40000000, true },
{ "pclk", "hclk", 40000000, true },
+ { "mpe", "pll_c", 0, false },
+ { "epp", "pll_c", 0, false },
+ { "vi_sensor", "pll_c", 0, false },
+ { "vi", "pll_c", 0, false },
+ { "2d", "pll_c", 0, false },
+ { "3d", "pll_c", 0, false },
#else
- { "pll_p", NULL, 408000000, true },
- { "pll_p_out1", "pll_p", 9600000, true },
- { "pll_p_out2", "pll_p", 48000000, true },
- { "pll_p_out3", "pll_p", 102000000, true },
- { "pll_m_out1", "pll_m", 275000000, true },
+ { "pll_p", NULL, 0, true },
+ { "pll_p_out1", "pll_p", 0, false },
+ { "pll_p_out2", "pll_p", 48000000, false },
+ { "pll_p_out3", "pll_p", 0, true },
+ { "pll_m_out1", "pll_m", 275000000, false },
{ "pll_p_out4", "pll_p", 102000000, true },
{ "sclk", "pll_p_out4", 102000000, true },
{ "hclk", "sclk", 102000000, true },
#endif
#else
{ "pll_p", NULL, 216000000, true },
- { "pll_p_out1", "pll_p", 28800000, true },
- { "pll_p_out2", "pll_p", 48000000, true },
+ { "pll_p_out1", "pll_p", 28800000, false },
+ { "pll_p_out2", "pll_p", 48000000, false },
{ "pll_p_out3", "pll_p", 72000000, true },
{ "pll_m_out1", "pll_m", 275000000, true },
- { "pll_c", NULL, ULONG_MAX, false },
- { "pll_c_out1", "pll_c", 208000000, false },
- { "pll_p_out4", "pll_p", 108000000, true },
+ { "pll_p_out4", "pll_p", 108000000, false },
{ "sclk", "pll_p_out4", 108000000, true },
{ "hclk", "sclk", 108000000, true },
{ "pclk", "hclk", 54000000, true },
#endif
- { "csite", NULL, 0, true },
- { "emc", NULL, 0, true },
- { "cpu", NULL, 0, true },
- { "kfuse", NULL, 0, true },
- { "fuse", NULL, 0, true },
+#ifdef CONFIG_TEGRA_SLOW_CSITE
+ { "csite", "clk_m", 1000000, true },
+#else
+ { "csite", NULL, 0, true },
+#endif
{ "pll_u", NULL, 480000000, false },
{ "sdmmc1", "pll_p", 48000000, false},
{ "sdmmc3", "pll_p", 48000000, false},
- { "sdmmc4", "clk_m", 12000000, true},
+ { "sdmmc4", "pll_p", 48000000, false},
+ { "sbc1.sclk", NULL, 40000000, false},
+ { "sbc2.sclk", NULL, 40000000, false},
+ { "sbc3.sclk", NULL, 40000000, false},
+ { "sbc4.sclk", NULL, 40000000, false},
#ifndef CONFIG_ARCH_TEGRA_2x_SOC
- { "cbus", "pll_c", ULONG_MAX, false },
+ { "sbc5.sclk", NULL, 40000000, false},
+ { "sbc6.sclk", NULL, 40000000, false},
+ { "wake.sclk", NULL, 40000000, true },
+ { "cpu_mode.sclk", NULL, 80000000, false },
+ { "cbus", "pll_c", 416000000, false },
{ "pll_c_out1", "pll_c", 208000000, false },
+ { "mselect", "pll_p", 102000000, true },
#endif
{ NULL, NULL, 0, 0},
};
-void tegra_init_cache(void)
+#ifdef CONFIG_TRUSTED_FOUNDATIONS
+#define CACHE_LINE_SIZE 32
+
+static inline void tegra_l2x0_disable_tz(void)
+{
+ static u32 l2x0_way_mask;
+ BUG_ON(smp_processor_id() != 0);
+
+ if (!l2x0_way_mask) {
+ void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
+ u32 aux_ctrl;
+ u32 ways;
+
+ aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
+ ways = (aux_ctrl & (1 << 16)) ? 16 : 8;
+ l2x0_way_mask = (1 << ways) - 1;
+ }
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ /* flush all ways on disable */
+ tegra_generic_smc_uncached(0xFFFFF100, 0x00000002, l2x0_way_mask);
+#elif defined(CONFIG_ARCH_TEGRA_3x_SOC)
+ if (tegra_is_cpu_in_lp2(0)) {
+ register unsigned long sp asm ("sp");
+
+ /* flush only the stack, if entering LP2 */
+ __cpuc_flush_dcache_area((void *)sp, (CACHE_LINE_SIZE * 2));
+ outer_flush_range(__pa(sp), __pa(sp) + (CACHE_LINE_SIZE * 2));
+
+ /* pass zero arg, so secureos flushes only its workspace */
+ tegra_generic_smc_uncached(0xFFFFF100, 0x00000002, 0x0);
+ } else {
+ /* flush all ways on disable, if entering LP0/LP1 */
+ tegra_generic_smc_uncached(0xFFFFF100,
+ 0x00000002, l2x0_way_mask);
+ }
+#endif
+}
+
+static inline void tegra_init_cache_tz(bool init)
{
+ void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
+ u32 aux_ctrl;
+
+ BUG_ON(smp_processor_id() != 0);
+
+ if (init) {
+ /* init L2 from secureos */
+ tegra_generic_smc(0xFFFFF100, 0x00000001, 0x0);
+
+ /* common init called for outer call hookup */
+ aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
+ l2x0_init(p, aux_ctrl, 0xFFFFFFFF);
+
+ /* use our outer_disable() routine */
+ outer_cache.disable = tegra_l2x0_disable_tz;
+ } else {
+ /* reenable L2 in secureos */
+ aux_ctrl = readl_relaxed(p + L2X0_AUX_CTRL);
+ tegra_generic_smc_uncached(0xFFFFF100, 0x00000004, aux_ctrl);
+ }
+}
+#endif /* CONFIG_TRUSTED_FOUNDATIONS */
+
#ifdef CONFIG_CACHE_L2X0
+void tegra_init_cache(bool init)
+{
+#ifdef CONFIG_TRUSTED_FOUNDATIONS
+ /* enable/re-enable of L2 handled by secureos */
+ return tegra_init_cache_tz(init);
+#else
void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
u32 aux_ctrl;
writel(0x221, p + L2X0_TAG_LATENCY_CTRL);
writel(0x221, p + L2X0_DATA_LATENCY_CTRL);
} else {
- writel(0x331, p + L2X0_TAG_LATENCY_CTRL);
- writel(0x441, p + L2X0_DATA_LATENCY_CTRL);
+ u32 speedo;
+
+ /* relax l2-cache latency for speedos 4,5,6 (T33's chips) */
+ speedo = tegra_cpu_speedo_id();
+ if (speedo == 4 || speedo == 5 || speedo == 6 ||
+ speedo == 12 || speedo == 13) {
+ writel(0x442, p + L2X0_TAG_LATENCY_CTRL);
+ writel(0x552, p + L2X0_DATA_LATENCY_CTRL);
+ } else {
+ writel(0x441, p + L2X0_TAG_LATENCY_CTRL);
+ writel(0x551, p + L2X0_DATA_LATENCY_CTRL);
+ }
}
#else
writel(0x770, p + L2X0_TAG_LATENCY_CTRL);
writel(0x770, p + L2X0_DATA_LATENCY_CTRL);
#endif
-
- /* Enable PL310 double line fill feature. */
- writel(((1<<30) | 0), p + L2X0_PREFETCH_CTRL);
#endif
+ writel(0x3, p + L2X0_POWER_CTRL);
aux_ctrl = readl(p + L2X0_CACHE_TYPE);
aux_ctrl = (aux_ctrl & 0x700) << (17-8);
- aux_ctrl |= 0x6C000001;
- l2x0_init(p, aux_ctrl, 0x8200c3fe);
+ aux_ctrl |= 0x7C000001;
+ if (init) {
+ l2x0_init(p, aux_ctrl, 0x8200c3fe);
+ } else {
+ u32 tmp;
+
+ tmp = aux_ctrl;
+ aux_ctrl = readl(p + L2X0_AUX_CTRL);
+ aux_ctrl &= 0x8200c3fe;
+ aux_ctrl |= tmp;
+ writel(aux_ctrl, p + L2X0_AUX_CTRL);
+ }
+ l2x0_enable();
#endif
}
+#endif /* CONFIG_CACHE_L2X0 */
static void __init tegra_init_power(void)
{
-#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+#ifdef CONFIG_ARCH_TEGRA_HAS_SATA
tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_SATA);
#endif
+#ifdef CONFIG_ARCH_TEGRA_HAS_PCIE
tegra_powergate_partition_with_clk_off(TEGRA_POWERGATE_PCIE);
+#endif
}
static inline unsigned long gizmo_readl(unsigned long offset)
gizmo_writel(val, AHB_MEM_PREFETCH_CFG4);
}
-static bool console_flushed;
-
-static int tegra_pm_flush_console(struct notifier_block *this,
- unsigned long code, void *unused)
-{
- if (console_flushed)
- return NOTIFY_NONE;
- console_flushed = true;
-
- pr_emerg("Restarting %s\n", linux_banner);
- if (console_trylock()) {
- console_unlock();
- return NOTIFY_NONE;
- }
-
- mdelay(50);
-
- local_irq_disable();
- if (!console_trylock())
- pr_emerg("%s: Console was locked! Busting\n", __func__);
- else
- pr_emerg("%s: Console was locked!\n", __func__);
- console_unlock();
- return NOTIFY_NONE;
-}
-
-static struct notifier_block tegra_reboot_notifier = {
- .notifier_call = tegra_pm_flush_console,
-};
-
void __init tegra_init_early(void)
{
- register_reboot_notifier(&tegra_reboot_notifier);
#ifndef CONFIG_SMP
/* For SMP system, initializing the reset handler here is too
late. For non-SMP systems, the function that calls the reset
tegra_init_pinmux();
tegra_clk_init_from_table(common_clk_init_table);
tegra_init_power();
- tegra_init_cache();
+ tegra_init_cache(true);
tegra_init_ahb_gizmo_settings();
+ tegra_init_debug_uart_rate();
}
static int __init tegra_lp0_vec_arg(char *options)
static int __init tegra_bootloader_fb_arg(char *options)
{
char *p = options;
- unsigned long start;
- unsigned long size;
tegra_bootloader_fb_size = memparse(p, &p);
if (*p == '@')
}
early_param("tegra_fbmem", tegra_bootloader_fb_arg);
+static int __init tegra_sku_override(char *id)
+{
+ char *p = id;
+
+ sku_override = memparse(p, &p);
+
+ return 0;
+}
+early_param("sku_override", tegra_sku_override);
+
+int tegra_get_sku_override(void)
+{
+ return sku_override;
+}
+
+static int __init tegra_vpr_arg(char *options)
+{
+ char *p = options;
+
+ tegra_vpr_size = memparse(p, &p);
+ if (*p == '@')
+ tegra_vpr_start = memparse(p+1, &p);
+ pr_info("Found vpr, start=0x%lx size=%lx",
+ tegra_vpr_start, tegra_vpr_size);
+ return 0;
+}
+early_param("vpr", tegra_vpr_arg);
+
enum panel_type get_panel_type(void)
{
return board_panel_type;
}
__setup("panel=", tegra_board_panel_type);
+enum power_supply_type get_power_supply_type(void)
+{
+ return pow_supply_type;
+}
+static int __init tegra_board_power_supply_type(char *options)
+{
+ if (!strcmp(options, "Adapter"))
+ pow_supply_type = POWER_SUPPLY_TYPE_MAINS;
+ if (!strcmp(options, "Mains"))
+ pow_supply_type = POWER_SUPPLY_TYPE_MAINS;
+ else if (!strcmp(options, "Battery"))
+ pow_supply_type = POWER_SUPPLY_TYPE_BATTERY;
+ else
+ return 0;
+ return 1;
+}
+__setup("power_supply=", tegra_board_power_supply_type);
+
int get_core_edp(void)
{
return pmu_core_edp;
int core_edp = memparse(p, &p);
if (core_edp != 0)
pmu_core_edp = core_edp;
+ return 0;
+}
+early_param("core_edp_mv", tegra_pmu_core_edp);
+
+int get_maximum_cpu_current_supported(void)
+{
+ return max_cpu_current;
+}
+static int __init tegra_max_cpu_current(char *options)
+{
+ char *p = options;
+ max_cpu_current = memparse(p, &p);
return 1;
}
-__setup("core_edp_mv=", tegra_pmu_core_edp);
+__setup("max_cpu_cur_ma=", tegra_max_cpu_current);
static int __init tegra_debug_uartport(char *info)
{
- if (!strcmp(info, "hsport"))
+ char *p = info;
+ unsigned long long port_id;
+ if (!strncmp(p, "hsport", 6))
is_tegra_debug_uart_hsport = true;
- else if (!strcmp(info, "lsport"))
+ else if (!strncmp(p, "lsport", 6))
is_tegra_debug_uart_hsport = false;
+ if (p[6] == ',') {
+ if (p[7] == '-') {
+ debug_uart_port_id = -1;
+ } else {
+ port_id = memparse(p + 7, &p);
+ debug_uart_port_id = (int) port_id;
+ }
+ } else {
+ debug_uart_port_id = -1;
+ }
+
return 1;
}
return is_tegra_debug_uart_hsport;
}
+int get_tegra_uart_debug_port_id(void)
+{
+ return debug_uart_port_id;
+}
__setup("debug_uartport=", tegra_debug_uartport);
+static int __init tegra_image_type(char *options)
+{
+ if (!strcmp(options, "RCK"))
+ board_image_type = rck_image;
+
+ return 0;
+}
+
+enum image_type get_tegra_image_type(void)
+{
+ return board_image_type;
+}
+
+__setup("image=", tegra_image_type);
+
+static int __init tegra_audio_codec_type(char *info)
+{
+ char *p = info;
+ if (!strncmp(p, "wm8903", 6))
+ audio_codec_name = audio_codec_wm8903;
+ else
+ audio_codec_name = audio_codec_none;
+
+ return 1;
+}
+
+enum audio_codec_type get_audio_codec_type(void)
+{
+ return audio_codec_name;
+}
+__setup("audio_codec=", tegra_audio_codec_type);
+
+
void tegra_get_board_info(struct board_info *bi)
{
- bi->board_id = (system_serial_high >> 16) & 0xFFFF;
- bi->sku = (system_serial_high) & 0xFFFF;
- bi->fab = (system_serial_low >> 24) & 0xFF;
- bi->major_revision = (system_serial_low >> 16) & 0xFF;
- bi->minor_revision = (system_serial_low >> 8) & 0xFF;
+#ifdef CONFIG_OF
+ struct device_node *board_info;
+ u32 prop_val;
+ int err;
+
+ board_info = of_find_node_by_path("/chosen/board_info");
+ if (!IS_ERR_OR_NULL(board_info)) {
+ memset(bi, 0, sizeof(*bi));
+
+ err = of_property_read_u32(board_info, "id", &prop_val);
+ if (err)
+ pr_err("failed to read /chosen/board_info/id\n");
+ else
+ bi->board_id = prop_val;
+
+ err = of_property_read_u32(board_info, "sku", &prop_val);
+ if (err)
+ pr_err("failed to read /chosen/board_info/sku\n");
+ else
+ bi->sku = prop_val;
+
+ err = of_property_read_u32(board_info, "fab", &prop_val);
+ if (err)
+ pr_err("failed to read /chosen/board_info/fab\n");
+ else
+ bi->fab = prop_val;
+
+ err = of_property_read_u32(board_info, "major_revision", &prop_val);
+ if (err)
+ pr_err("failed to read /chosen/board_info/major_revision\n");
+ else
+ bi->major_revision = prop_val;
+
+ err = of_property_read_u32(board_info, "minor_revision", &prop_val);
+ if (err)
+ pr_err("failed to read /chosen/board_info/minor_revision\n");
+ else
+ bi->minor_revision = prop_val;
+ } else {
+#endif
+ bi->board_id = (system_serial_high >> 16) & 0xFFFF;
+ bi->sku = (system_serial_high) & 0xFFFF;
+ bi->fab = (system_serial_low >> 24) & 0xFF;
+ bi->major_revision = (system_serial_low >> 16) & 0xFF;
+ bi->minor_revision = (system_serial_low >> 8) & 0xFF;
+#ifdef CONFIG_OF
+ }
+#endif
}
static int __init tegra_pmu_board_info(char *info)
__setup("pmuboard=", tegra_pmu_board_info);
+static int __init tegra_display_board_info(char *info)
+{
+ char *p = info;
+ display_board_info.board_id = memparse(p, &p);
+ display_board_info.sku = memparse(p+1, &p);
+ display_board_info.fab = memparse(p+1, &p);
+ display_board_info.major_revision = memparse(p+1, &p);
+ display_board_info.minor_revision = memparse(p+1, &p);
+ return 1;
+}
+
+void tegra_get_display_board_info(struct board_info *bi)
+{
+ memcpy(bi, &display_board_info, sizeof(struct board_info));
+}
+
+__setup("displayboard=", tegra_display_board_info);
+
+static int __init tegra_camera_board_info(char *info)
+{
+ char *p = info;
+ camera_board_info.board_id = memparse(p, &p);
+ camera_board_info.sku = memparse(p+1, &p);
+ camera_board_info.fab = memparse(p+1, &p);
+ camera_board_info.major_revision = memparse(p+1, &p);
+ camera_board_info.minor_revision = memparse(p+1, &p);
+ return 1;
+}
+
+void tegra_get_camera_board_info(struct board_info *bi)
+{
+ memcpy(bi, &camera_board_info, sizeof(struct board_info));
+}
+
+__setup("cameraboard=", tegra_camera_board_info);
+
static int __init tegra_modem_id(char *id)
{
char *p = id;
__setup("modem_id=", tegra_modem_id);
+static int __init tegra_commchip_id(char *id)
+{
+ char *p = id;
+
+ if (get_option(&p, &commchip_id) != 1)
+ return 0;
+ return 1;
+}
+
+int tegra_get_commchip_id(void)
+{
+ return commchip_id;
+}
+
+__setup("commchip_id=", tegra_commchip_id);
+
/*
* Tegra has a protected aperture that prevents access by most non-CPU
* memory masters to addresses above the aperture value. Enabling it
for (i = 0 ; i < size; i += PAGE_SIZE) {
page = phys_to_page(from + i);
from_virt = kmap(page);
- memcpy_toio(to_io + i, from_virt, PAGE_SIZE);
+ memcpy(to_io + i, from_virt, PAGE_SIZE);
kunmap(page);
}
} else {
iounmap(to_io);
}
-#ifdef CONFIG_TEGRA_IOVMM_SMMU
-/* Support for Tegra3 A01 chip mask that needs to have SMMU IOVA reside in
- * the upper half of 4GB IOVA space. A02 and after use the bottom 1GB and
- * do not need to reserve memory.
- */
-#define SUPPORT_TEGRA_3_IOVMM_SMMU_A01
-#endif
-
void __init tegra_reserve(unsigned long carveout_size, unsigned long fb_size,
unsigned long fb2_size)
{
-#ifdef SUPPORT_TEGRA_3_IOVMM_SMMU_A01
- extern struct platform_device tegra_smmu_device;
- int smmu_reserved = 0;
- struct resource *smmu_window =
- platform_get_resource_byname(&tegra_smmu_device,
- IORESOURCE_MEM, "smmu");
-#endif
- if (tegra_lp0_vec_size)
- if (memblock_reserve(tegra_lp0_vec_start, tegra_lp0_vec_size)) {
- pr_err("Failed to reserve lp0_vec %08lx@%08lx\n",
- tegra_lp0_vec_size, tegra_lp0_vec_start);
- tegra_lp0_vec_start = 0;
- tegra_lp0_vec_size = 0;
- }
-
if (carveout_size) {
tegra_carveout_start = memblock_end_of_DRAM() - carveout_size;
if (memblock_remove(tegra_carveout_start, carveout_size)) {
if (tegra_carveout_size && tegra_carveout_start < tegra_grhost_aperture)
tegra_grhost_aperture = tegra_carveout_start;
-#ifdef SUPPORT_TEGRA_3_IOVMM_SMMU_A01
- if (!smmu_window) {
- pr_err("No SMMU resources\n");
- } else {
- size_t smmu_window_size;
-
- if (tegra_get_revision() == TEGRA_REVISION_A01) {
- smmu_window->start = TEGRA_SMMU_BASE_A01;
- smmu_window->end = TEGRA_SMMU_BASE_A01 +
- TEGRA_SMMU_SIZE_A01 - 1;
- }
- smmu_window_size = smmu_window->end + 1 - smmu_window->start;
- if (smmu_window->start >= 0x80000000) {
- if (memblock_reserve(smmu_window->start,
- smmu_window_size))
- pr_err(
- "Failed to reserve SMMU I/O VA window %08lx@%08lx\n",
- (unsigned long)smmu_window_size,
- (unsigned long)smmu_window->start);
- else
- smmu_reserved = 1;
+ if (tegra_lp0_vec_size &&
+ (tegra_lp0_vec_start < memblock_end_of_DRAM())) {
+ if (memblock_reserve(tegra_lp0_vec_start, tegra_lp0_vec_size)) {
+ pr_err("Failed to reserve lp0_vec %08lx@%08lx\n",
+ tegra_lp0_vec_size, tegra_lp0_vec_start);
+ tegra_lp0_vec_start = 0;
+ tegra_lp0_vec_size = 0;
}
- }
-#endif
+ tegra_lp0_vec_relocate = false;
+ } else
+ tegra_lp0_vec_relocate = true;
/*
* We copy the bootloader's framebuffer to the framebuffer allocated
"Bootloader framebuffer: %08lx - %08lx\n"
"Framebuffer: %08lx - %08lx\n"
"2nd Framebuffer: %08lx - %08lx\n"
- "Carveout: %08lx - %08lx\n",
+ "Carveout: %08lx - %08lx\n"
+ "Vpr: %08lx - %08lx\n",
tegra_lp0_vec_start,
tegra_lp0_vec_size ?
tegra_lp0_vec_start + tegra_lp0_vec_size - 1 : 0,
tegra_fb2_start + tegra_fb2_size - 1 : 0,
tegra_carveout_start,
tegra_carveout_size ?
- tegra_carveout_start + tegra_carveout_size - 1 : 0);
+ tegra_carveout_start + tegra_carveout_size - 1 : 0,
+ tegra_vpr_start,
+ tegra_vpr_size ?
+ tegra_vpr_start + tegra_vpr_size - 1 : 0);
+}
-#ifdef SUPPORT_TEGRA_3_IOVMM_SMMU_A01
- if (smmu_reserved)
- pr_info("SMMU: %08x - %08x\n",
- smmu_window->start, smmu_window->end);
-#endif
+static struct resource ram_console_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ram_console_device = {
+ .name = "ram_console",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ram_console_resources),
+ .resource = ram_console_resources,
+};
+
+void __init tegra_ram_console_debug_reserve(unsigned long ram_console_size)
+{
+ struct resource *res;
+ long ret;
+
+ res = platform_get_resource(&ram_console_device, IORESOURCE_MEM, 0);
+ if (!res)
+ goto fail;
+ res->start = memblock_end_of_DRAM() - ram_console_size;
+ res->end = res->start + ram_console_size - 1;
+ ret = memblock_remove(res->start, ram_console_size);
+ if (ret)
+ goto fail;
+
+ return;
+
+fail:
+ ram_console_device.resource = NULL;
+ ram_console_device.num_resources = 0;
+ pr_err("Failed to reserve memory block for ram console\n");
+}
+
+void __init tegra_ram_console_debug_init(void)
+{
+ int err;
+
+ err = platform_device_register(&ram_console_device);
+ if (err) {
+ pr_err("%s: ram console registration failed (%d)!\n", __func__, err);
+ }
}
void __init tegra_release_bootloader_fb(void)
tegra_bootloader_fb_size))
pr_err("Failed to free bootloader fb.\n");
}
+
+#ifdef CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND
+char cpufreq_default_gov[CONFIG_NR_CPUS][MAX_GOV_NAME_LEN];
+char *cpufreq_conservative_gov = "conservative";
+
+void cpufreq_store_default_gov(void)
+{
+ unsigned int cpu = 0;
+ struct cpufreq_policy *policy;
+
+#ifndef CONFIG_TEGRA_AUTO_HOTPLUG
+ for_each_online_cpu(cpu)
+#endif
+ {
+ policy = cpufreq_cpu_get(cpu);
+ if (policy && policy->governor) {
+ sprintf(cpufreq_default_gov[cpu], "%s",
+ policy->governor->name);
+ cpufreq_cpu_put(policy);
+ } else {
+ /* No policy or no gov set for this
+ * online cpu. If we are here, require
+ * serious debugging hence setting
+ * as pr_error.
+ */
+ pr_err("No gov or No policy for online cpu:%d,"
+ , cpu);
+ }
+ }
+}
+
+void cpufreq_change_gov(char *target_gov)
+{
+ int ret = -EINVAL;
+ unsigned int cpu = 0;
+
+#ifndef CONFIG_TEGRA_AUTO_HOTPLUG
+ for_each_online_cpu(cpu)
+#endif
+ {
+ ret = cpufreq_set_gov(target_gov, cpu);
+ if (ret < 0)
+ /* Unable to set gov for the online cpu.
+ * If it happens, needs to debug.
+ */
+ pr_info("Unable to set gov:%s for online cpu:%d,"
+ , cpufreq_default_gov[cpu]
+ , cpu);
+ }
+}
+
+void cpufreq_restore_default_gov(void)
+{
+ int ret = -EINVAL;
+ unsigned int cpu = 0;
+
+#ifndef CONFIG_TEGRA_AUTO_HOTPLUG
+ for_each_online_cpu(cpu)
+#endif
+ {
+ if (&cpufreq_default_gov[cpu] &&
+ strlen((const char *)&cpufreq_default_gov[cpu])) {
+ ret = cpufreq_set_gov(cpufreq_default_gov[cpu], cpu);
+ if (ret < 0)
+ /* Unable to restore gov for the cpu as
+ * It was online on suspend and becomes
+ * offline on resume.
+ */
+ pr_info("Unable to restore gov:%s for cpu:%d,"
+ , cpufreq_default_gov[cpu]
+ , cpu);
+ }
+ cpufreq_default_gov[cpu][0] = '\0';
+ }
+}
+#endif /* CONFIG_TEGRA_CONVSERVATIVE_GOV_ON_EARLYSUPSEND */